From 9f1a1825e0361da31612d60c6ddbabb50d6dc5c4 Mon Sep 17 00:00:00 2001 From: sentriz Date: Mon, 8 Nov 2021 19:59:41 +0000 Subject: [PATCH] make `musicFolderId`s ints https://github.com/sentriz/gonic/issues/50#issuecomment-963257103 https://github.com/einsteinx2/iSubMusicStreamer/blob/006c1dafee6b926fde9d775cb0e64011a4662853/Classes/Models/API%20Models/MediaFolder.swift#L16 related #50 --- server/ctrlsubsonic/ctrl.go | 12 ++++++++++++ server/ctrlsubsonic/ctrl_test.go | 8 +++++++- server/ctrlsubsonic/handlers_by_folder.go | 10 +++++----- server/ctrlsubsonic/handlers_by_folder_test.go | 5 ++--- server/ctrlsubsonic/handlers_by_tags.go | 12 ++++++------ server/ctrlsubsonic/handlers_by_tags_test.go | 5 ++--- server/ctrlsubsonic/handlers_common.go | 18 ++++-------------- server/ctrlsubsonic/spec/spec.go | 2 +- server/server.go | 1 + 9 files changed, 40 insertions(+), 33 deletions(-) diff --git a/server/ctrlsubsonic/ctrl.go b/server/ctrlsubsonic/ctrl.go index 1b544cf0..8c8ffeea 100644 --- a/server/ctrlsubsonic/ctrl.go +++ b/server/ctrlsubsonic/ctrl.go @@ -30,6 +30,7 @@ type Controller struct { CachePath string CoverCachePath string PodcastsPath string + MusicPaths []string Jukebox *jukebox.Jukebox Scrobblers []scrobble.Scrobbler Podcasts *podcasts.Podcasts @@ -116,3 +117,14 @@ func (c *Controller) HR(h handlerSubsonicRaw) http.Handler { } }) } + +func (c *Controller) getMusicFolder(p params.Params) string { + idx, err := p.GetInt("musicFolderId") + if err != nil { + return "" + } + if idx > len(c.MusicPaths) { + return "" + } + return c.MusicPaths[idx] +} diff --git a/server/ctrlsubsonic/ctrl_test.go b/server/ctrlsubsonic/ctrl_test.go index 862e26a8..aa36bfa1 100644 --- a/server/ctrlsubsonic/ctrl_test.go +++ b/server/ctrlsubsonic/ctrl_test.go @@ -9,6 +9,7 @@ import ( "net/url" "os" "path" + "path/filepath" "regexp" "strings" "testing" @@ -110,8 +111,13 @@ func makec(t *testing.T, roots []string) (*Controller, *mockfs.MockFS) { m.ResetDates() m.LogAlbums() + var absRoots []string + for _, root := range roots { + absRoots = append(absRoots, filepath.Join(m.TmpDir(), root)) + } + base := &ctrlbase.Controller{DB: m.DB()} - return &Controller{Controller: base}, m + return &Controller{Controller: base, MusicPaths: absRoots}, m } func TestMain(m *testing.M) { diff --git a/server/ctrlsubsonic/handlers_by_folder.go b/server/ctrlsubsonic/handlers_by_folder.go index 04ccc2d5..3679f307 100644 --- a/server/ctrlsubsonic/handlers_by_folder.go +++ b/server/ctrlsubsonic/handlers_by_folder.go @@ -24,7 +24,7 @@ func (c *Controller) ServeGetIndexes(r *http.Request) *spec.Response { Select("id"). Model(&db.Album{}). Where("parent_id IS NULL") - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { rootQ = rootQ. Where("root_dir=?", m) } @@ -145,7 +145,7 @@ func (c *Controller) ServeGetAlbumList(r *http.Request) *spec.Response { return spec.NewError(10, "unknown value `%s` for parameter 'type'", v) } - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("root_dir=?", m) } var folders []*db.Album @@ -185,7 +185,7 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response { Select("id"). Model(&db.Album{}). Where("parent_id IS NULL") - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { rootQ = rootQ.Where("root_dir=?", m) } @@ -207,7 +207,7 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response { Where(`tag_artist_id IS NOT NULL AND (right_path LIKE ? OR right_path_u_dec LIKE ?)`, query, query). Offset(params.GetOrInt("albumOffset", 0)). Limit(params.GetOrInt("albumCount", 20)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("root_dir=?", m) } if err := q.Find(&albums).Error; err != nil { @@ -224,7 +224,7 @@ func (c *Controller) ServeSearchTwo(r *http.Request) *spec.Response { Where("filename LIKE ? OR filename_u_dec LIKE ?", query, query). Offset(params.GetOrInt("songOffset", 0)). Limit(params.GetOrInt("songCount", 20)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q. Joins("JOIN albums ON albums.id=tracks.album_id"). Where("albums.root_dir=?", m) diff --git a/server/ctrlsubsonic/handlers_by_folder_test.go b/server/ctrlsubsonic/handlers_by_folder_test.go index 8c5c6e7c..4cfa4f31 100644 --- a/server/ctrlsubsonic/handlers_by_folder_test.go +++ b/server/ctrlsubsonic/handlers_by_folder_test.go @@ -2,7 +2,6 @@ package ctrlsubsonic import ( "net/url" - "path/filepath" "testing" _ "github.com/jinzhu/gorm/dialects/sqlite" @@ -14,8 +13,8 @@ func TestGetIndexes(t *testing.T) { runQueryCases(t, contr, contr.ServeGetIndexes, []*queryCase{ {url.Values{}, "no_args", false}, - {url.Values{"musicFolderId": {filepath.Join(m.TmpDir(), "m-0")}}, "with_music_folder_1", false}, - {url.Values{"musicFolderId": {filepath.Join(m.TmpDir(), "m-1")}}, "with_music_folder_2", false}, + {url.Values{"musicFolderId": {"0"}}, "with_music_folder_1", false}, + {url.Values{"musicFolderId": {"1"}}, "with_music_folder_2", false}, }) } diff --git a/server/ctrlsubsonic/handlers_by_tags.go b/server/ctrlsubsonic/handlers_by_tags.go index bc80032f..9f0c5efb 100644 --- a/server/ctrlsubsonic/handlers_by_tags.go +++ b/server/ctrlsubsonic/handlers_by_tags.go @@ -23,7 +23,7 @@ func (c *Controller) ServeGetArtists(r *http.Request) *spec.Response { Joins("LEFT JOIN albums sub ON artists.id=sub.tag_artist_id"). Group("artists.id"). Order("artists.name COLLATE NOCASE") - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("sub.root_dir=?", m) } if err := q.Find(&artists).Error; err != nil { @@ -148,7 +148,7 @@ func (c *Controller) ServeGetAlbumListTwo(r *http.Request) *spec.Response { default: return spec.NewError(10, "unknown value `%s` for parameter 'type'", listType) } - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("root_dir=?", m) } var albums []*db.Album @@ -188,7 +188,7 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response { Where("name LIKE ? OR name_u_dec LIKE ?", query, query). Offset(params.GetOrInt("artistOffset", 0)). Limit(params.GetOrInt("artistCount", 20)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q. Joins("JOIN albums ON albums.tag_artist_id=artists.id"). Where("albums.root_dir=?", m) @@ -207,7 +207,7 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response { Where("tag_title LIKE ? OR tag_title_u_dec LIKE ?", query, query). Offset(params.GetOrInt("albumOffset", 0)). Limit(params.GetOrInt("albumCount", 20)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("root_dir=?", m) } if err := q.Find(&albums).Error; err != nil { @@ -224,7 +224,7 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response { Where("tag_title LIKE ? OR tag_title_u_dec LIKE ?", query, query). Offset(params.GetOrInt("songOffset", 0)). Limit(params.GetOrInt("songCount", 20)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q. Joins("JOIN albums ON albums.id=tracks.album_id"). Where("albums.root_dir=?", m) @@ -344,7 +344,7 @@ func (c *Controller) ServeGetSongsByGenre(r *http.Request) *spec.Response { Preload("Album"). Offset(params.GetOrInt("offset", 0)). Limit(params.GetOrInt("count", 10)) - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("albums.root_dir=?", m) } if err := q.Find(&tracks).Error; err != nil { diff --git a/server/ctrlsubsonic/handlers_by_tags_test.go b/server/ctrlsubsonic/handlers_by_tags_test.go index 90918e24..f05cc2f3 100644 --- a/server/ctrlsubsonic/handlers_by_tags_test.go +++ b/server/ctrlsubsonic/handlers_by_tags_test.go @@ -2,7 +2,6 @@ package ctrlsubsonic import ( "net/url" - "path/filepath" "testing" ) @@ -13,8 +12,8 @@ func TestGetArtists(t *testing.T) { runQueryCases(t, contr, contr.ServeGetArtists, []*queryCase{ {url.Values{}, "no_args", false}, - {url.Values{"musicFolderId": {filepath.Join(m.TmpDir(), "m-0")}}, "with_music_folder_1", false}, - {url.Values{"musicFolderId": {filepath.Join(m.TmpDir(), "m-1")}}, "with_music_folder_2", false}, + {url.Values{"musicFolderId": {"0"}}, "with_music_folder_1", false}, + {url.Values{"musicFolderId": {"1"}}, "with_music_folder_2", false}, }) } diff --git a/server/ctrlsubsonic/handlers_common.go b/server/ctrlsubsonic/handlers_common.go index c2c9ec8e..e0e4188f 100644 --- a/server/ctrlsubsonic/handlers_common.go +++ b/server/ctrlsubsonic/handlers_common.go @@ -71,21 +71,11 @@ func (c *Controller) ServeScrobble(r *http.Request) *spec.Response { } func (c *Controller) ServeGetMusicFolders(r *http.Request) *spec.Response { - var roots []string - err := c.DB. - Model(&db.Album{}). - Pluck("DISTINCT(root_dir)", &roots). - Where("parent_id IS NULL"). - Error - if err != nil { - return spec.NewError(0, "error getting roots: %v", err) - } - sub := spec.NewResponse() sub.MusicFolders = &spec.MusicFolders{} - sub.MusicFolders.List = make([]*spec.MusicFolder, len(roots)) - for i, root := range roots { - sub.MusicFolders.List[i] = &spec.MusicFolder{ID: root, Name: filepath.Base(root)} + sub.MusicFolders.List = make([]*spec.MusicFolder, len(c.MusicPaths)) + for i, path := range c.MusicPaths { + sub.MusicFolders.List[i] = &spec.MusicFolder{ID: i, Name: filepath.Base(path)} } return sub } @@ -226,7 +216,7 @@ func (c *Controller) ServeGetRandomSongs(r *http.Request) *spec.Response { q = q.Joins("JOIN track_genres ON track_genres.track_id=tracks.id") q = q.Joins("JOIN genres ON genres.id=track_genres.genre_id AND genres.name=?", genre) } - if m, _ := params.Get("musicFolderId"); m != "" { + if m := c.getMusicFolder(params); m != "" { q = q.Where("albums.root_dir=?", m) } q.Find(&tracks) diff --git a/server/ctrlsubsonic/spec/spec.go b/server/ctrlsubsonic/spec/spec.go index 05b9ee99..f30fab89 100644 --- a/server/ctrlsubsonic/spec/spec.go +++ b/server/ctrlsubsonic/spec/spec.go @@ -179,7 +179,7 @@ type MusicFolders struct { } type MusicFolder struct { - ID string `xml:"id,attr,omitempty" json:"id,omitempty"` + ID int `xml:"id,attr,omitempty" json:"id,omitempty"` Name string `xml:"name,attr,omitempty" json:"name,omitempty"` } diff --git a/server/server.go b/server/server.go index adcff54d..f1ecdb5b 100644 --- a/server/server.go +++ b/server/server.go @@ -93,6 +93,7 @@ func New(opts Options) (*Server, error) { CachePath: opts.CachePath, CoverCachePath: opts.CoverCachePath, PodcastsPath: opts.PodcastPath, + MusicPaths: opts.MusicPaths, Jukebox: &jukebox.Jukebox{}, Scrobblers: []scrobble.Scrobbler{&lastfm.Scrobbler{DB: opts.DB}, &listenbrainz.Scrobbler{}}, Podcasts: podcast,