From 17df63b550404c79ef4084b5057db2364e47f9a1 Mon Sep 17 00:00:00 2001
From: Deluan <deluan@deluan.com>
Date: Tue, 19 May 2020 23:50:27 -0400
Subject: [PATCH] Fix `child.size` and `directory.playCount` compatibility with
 Subsonic API. Fixes #304

---
 engine/browser.go                                           | 6 +++---
 engine/common.go                                            | 2 +-
 model/album.go                                              | 2 +-
 model/artist.go                                             | 2 +-
 model/mediafile.go                                          | 4 ++--
 persistence/mediafile_repository_test.go                    | 4 ++--
 scanner/metadata_ffmpeg.go                                  | 2 +-
 server/subsonic/browsing.go                                 | 2 +-
 server/subsonic/helpers.go                                  | 3 +--
 ...tcher-Match-Responses Child with data should match .JSON | 2 +-
 server/subsonic/responses/responses.go                      | 4 ++--
 server/subsonic/responses/responses_test.go                 | 2 +-
 12 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/engine/browser.go b/engine/browser.go
index 05be0fab2..25976bb4c 100644
--- a/engine/browser.go
+++ b/engine/browser.go
@@ -61,7 +61,7 @@ type DirectoryInfo struct {
 	Entries    Entries
 	Parent     string
 	Starred    time.Time
-	PlayCount  int32
+	PlayCount  int64
 	UserRating int
 	AlbumCount int
 	CoverArt   string
@@ -138,7 +138,7 @@ func (b *browser) buildArtistDir(a *model.Artist, albums model.Albums) *Director
 	for i := range albums {
 		al := albums[i]
 		dir.Entries[i] = FromAlbum(&al)
-		dir.PlayCount += int32(al.PlayCount)
+		dir.PlayCount += al.PlayCount
 	}
 	return dir
 }
@@ -156,7 +156,7 @@ func (b *browser) buildAlbumDir(al *model.Album, tracks model.MediaFiles) *Direc
 		Year:       al.MaxYear,
 		Genre:      al.Genre,
 		CoverArt:   al.CoverArtId,
-		PlayCount:  int32(al.PlayCount),
+		PlayCount:  al.PlayCount,
 		UserRating: al.Rating,
 	}
 
diff --git a/engine/common.go b/engine/common.go
index 5d1eecaf4..beac10b19 100644
--- a/engine/common.go
+++ b/engine/common.go
@@ -23,7 +23,7 @@ type Entry struct {
 	Starred     time.Time
 	Track       int
 	Duration    int
-	Size        int
+	Size        int64
 	Suffix      string
 	BitRate     int
 	ContentType string
diff --git a/model/album.go b/model/album.go
index f429a924f..433b93844 100644
--- a/model/album.go
+++ b/model/album.go
@@ -27,7 +27,7 @@ type Album struct {
 	UpdatedAt            time.Time `json:"updatedAt"`
 
 	// Annotations
-	PlayCount int       `json:"playCount"   orm:"-"`
+	PlayCount int64     `json:"playCount"   orm:"-"`
 	PlayDate  time.Time `json:"playDate"    orm:"-"`
 	Rating    int       `json:"rating"      orm:"-"`
 	Starred   bool      `json:"starred"     orm:"-"`
diff --git a/model/artist.go b/model/artist.go
index 299d0d81e..1a705c3ec 100644
--- a/model/artist.go
+++ b/model/artist.go
@@ -12,7 +12,7 @@ type Artist struct {
 	OrderArtistName string `json:"orderArtistName"`
 
 	// Annotations
-	PlayCount int       `json:"playCount"   orm:"-"`
+	PlayCount int64     `json:"playCount"   orm:"-"`
 	PlayDate  time.Time `json:"playDate"    orm:"-"`
 	Rating    int       `json:"rating"      orm:"-"`
 	Starred   bool      `json:"starred"     orm:"-"`
diff --git a/model/mediafile.go b/model/mediafile.go
index 4d70bee37..10d8a6efe 100644
--- a/model/mediafile.go
+++ b/model/mediafile.go
@@ -20,7 +20,7 @@ type MediaFile struct {
 	DiscNumber           int       `json:"discNumber"`
 	DiscSubtitle         string    `json:"discSubtitle"`
 	Year                 int       `json:"year"`
-	Size                 int       `json:"size"`
+	Size                 int64     `json:"size"`
 	Suffix               string    `json:"suffix"`
 	Duration             float32   `json:"duration"`
 	BitRate              int       `json:"bitRate"`
@@ -38,7 +38,7 @@ type MediaFile struct {
 	UpdatedAt            time.Time `json:"updatedAt"`
 
 	// Annotations
-	PlayCount int       `json:"playCount"   orm:"-"`
+	PlayCount int64     `json:"playCount"   orm:"-"`
 	PlayDate  time.Time `json:"playDate"    orm:"-"`
 	Rating    int       `json:"rating"      orm:"-"`
 	Starred   bool      `json:"starred"     orm:"-"`
diff --git a/persistence/mediafile_repository_test.go b/persistence/mediafile_repository_test.go
index 3b929d729..5cbab9a7a 100644
--- a/persistence/mediafile_repository_test.go
+++ b/persistence/mediafile_repository_test.go
@@ -101,7 +101,7 @@ var _ = Describe("MediaRepository", func() {
 			Expect(err).To(BeNil())
 
 			Expect(mf.PlayDate.Unix()).To(Equal(playDate.Unix()))
-			Expect(mf.PlayCount).To(Equal(1))
+			Expect(mf.PlayCount).To(Equal(int64(1)))
 		})
 
 		It("increments play count on newly starred items", func() {
@@ -115,7 +115,7 @@ var _ = Describe("MediaRepository", func() {
 			Expect(err).To(BeNil())
 
 			Expect(mf.PlayDate.Unix()).To(Equal(playDate.Unix()))
-			Expect(mf.PlayCount).To(Equal(1))
+			Expect(mf.PlayCount).To(Equal(int64(1)))
 		})
 	})
 })
diff --git a/scanner/metadata_ffmpeg.go b/scanner/metadata_ffmpeg.go
index e22a94377..e647d8cca 100644
--- a/scanner/metadata_ffmpeg.go
+++ b/scanner/metadata_ffmpeg.go
@@ -49,7 +49,7 @@ func (m *Metadata) BitRate() int                { return m.parseInt("bitrate") }
 func (m *Metadata) ModificationTime() time.Time { return m.fileInfo.ModTime() }
 func (m *Metadata) FilePath() string            { return m.filePath }
 func (m *Metadata) Suffix() string              { return m.suffix }
-func (m *Metadata) Size() int                   { return int(m.fileInfo.Size()) }
+func (m *Metadata) Size() int64                 { return m.fileInfo.Size() }
 
 func LoadAllAudioFiles(dirPath string) (map[string]os.FileInfo, error) {
 	dir, err := os.Open(dirPath)
diff --git a/server/subsonic/browsing.go b/server/subsonic/browsing.go
index 16d2f708f..9b5e2ea23 100644
--- a/server/subsonic/browsing.go
+++ b/server/subsonic/browsing.go
@@ -229,7 +229,7 @@ func (c *BrowsingController) buildAlbum(ctx context.Context, d *engine.Directory
 	dir.CoverArt = d.CoverArt
 	dir.SongCount = d.SongCount
 	dir.Duration = d.Duration
-	dir.PlayCount = int64(d.PlayCount)
+	dir.PlayCount = d.PlayCount
 	dir.Year = d.Year
 	dir.Genre = d.Genre
 	if !d.Created.IsZero() {
diff --git a/server/subsonic/helpers.go b/server/subsonic/helpers.go
index 06233d574..019601e4a 100644
--- a/server/subsonic/helpers.go
+++ b/server/subsonic/helpers.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"mime"
 	"net/http"
-	"strconv"
 
 	"github.com/deluan/navidrome/consts"
 	"github.com/deluan/navidrome/engine"
@@ -119,7 +118,7 @@ func ToChild(ctx context.Context, entry engine.Entry) responses.Child {
 	child.CoverArt = entry.CoverArt
 	child.Track = entry.Track
 	child.Duration = entry.Duration
-	child.Size = strconv.Itoa(entry.Size)
+	child.Size = entry.Size
 	child.Suffix = entry.Suffix
 	child.BitRate = entry.BitRate
 	child.ContentType = entry.ContentType
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses Child with data should match .JSON b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses Child with data should match .JSON
index fd8f29668..2d9e1ec53 100644
--- a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses Child with data should match .JSON	
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses Child with data should match .JSON	
@@ -1 +1 @@
-{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","directory":{"child":[{"id":"1","isDir":true,"title":"title","album":"album","artist":"artist","track":1,"year":1985,"genre":"Rock","coverArt":"1","size":"8421341","contentType":"audio/flac","suffix":"flac","starred":"2016-03-02T20:30:00Z","transcodedContentType":"audio/mpeg","transcodedSuffix":"mp3","duration":146,"bitRate":320,"isVideo":false}],"id":"1","name":"N"}}
+{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","directory":{"child":[{"id":"1","isDir":true,"title":"title","album":"album","artist":"artist","track":1,"year":1985,"genre":"Rock","coverArt":"1","size":8421341,"contentType":"audio/flac","suffix":"flac","starred":"2016-03-02T20:30:00Z","transcodedContentType":"audio/mpeg","transcodedSuffix":"mp3","duration":146,"bitRate":320,"isVideo":false}],"id":"1","name":"N"}}
diff --git a/server/subsonic/responses/responses.go b/server/subsonic/responses/responses.go
index c7118966e..be1cc4113 100644
--- a/server/subsonic/responses/responses.go
+++ b/server/subsonic/responses/responses.go
@@ -96,7 +96,7 @@ type Child struct {
 	Year                  int        `xml:"year,attr,omitempty"                     json:"year,omitempty"`
 	Genre                 string     `xml:"genre,attr,omitempty"                    json:"genre,omitempty"`
 	CoverArt              string     `xml:"coverArt,attr,omitempty"                 json:"coverArt,omitempty"`
-	Size                  string     `xml:"size,attr,omitempty"                     json:"size,omitempty"`
+	Size                  int64      `xml:"size,attr,omitempty"                     json:"size,omitempty"`
 	ContentType           string     `xml:"contentType,attr,omitempty"              json:"contentType,omitempty"`
 	Suffix                string     `xml:"suffix,attr,omitempty"                   json:"suffix,omitempty"`
 	Starred               *time.Time `xml:"starred,attr,omitempty"                  json:"starred,omitempty"`
@@ -132,7 +132,7 @@ type Directory struct {
 	Name       string     `xml:"name,attr"                          json:"name"`
 	Parent     string     `xml:"parent,attr,omitempty"              json:"parent,omitempty"`
 	Starred    *time.Time `xml:"starred,attr,omitempty"             json:"starred,omitempty"`
-	PlayCount  int32      `xml:"playCount,attr,omitempty"           json:"playcount,omitempty"`
+	PlayCount  int64      `xml:"playCount,attr,omitempty"           json:"playcount,omitempty"`
 	UserRating int        `xml:"userRating,attr,omitempty"          json:"userRating,omitempty"`
 
 	// ID3
diff --git a/server/subsonic/responses/responses_test.go b/server/subsonic/responses/responses_test.go
index d55d3901f..229675f71 100644
--- a/server/subsonic/responses/responses_test.go
+++ b/server/subsonic/responses/responses_test.go
@@ -115,7 +115,7 @@ var _ = Describe("Responses", func() {
 				t := time.Date(2016, 03, 2, 20, 30, 0, 0, time.UTC)
 				child[0] = Child{
 					Id: "1", IsDir: true, Title: "title", Album: "album", Artist: "artist", Track: 1,
-					Year: 1985, Genre: "Rock", CoverArt: "1", Size: "8421341", ContentType: "audio/flac",
+					Year: 1985, Genre: "Rock", CoverArt: "1", Size: 8421341, ContentType: "audio/flac",
 					Suffix: "flac", TranscodedContentType: "audio/mpeg", TranscodedSuffix: "mp3",
 					Duration: 146, BitRate: 320, Starred: &t,
 				}