diff --git a/server/subsonic/api.go b/server/subsonic/api.go
index b3d6b9eda..f89d81b63 100644
--- a/server/subsonic/api.go
+++ b/server/subsonic/api.go
@@ -82,6 +82,7 @@ func (api *Router) routes() http.Handler {
H(withPlayer, "getSong", c.GetSong)
H(withPlayer, "getArtistInfo", c.GetArtistInfo)
H(withPlayer, "getArtistInfo2", c.GetArtistInfo2)
+ H(withPlayer, "GetTopSongs", c.GetArtistInfo2)
})
r.Group(func(r chi.Router) {
c := initAlbumListController(api)
diff --git a/server/subsonic/browsing.go b/server/subsonic/browsing.go
index 9862850ce..0392c1f1e 100644
--- a/server/subsonic/browsing.go
+++ b/server/subsonic/browsing.go
@@ -191,6 +191,13 @@ func (c *BrowsingController) GetArtistInfo2(w http.ResponseWriter, r *http.Reque
return response, nil
}
+// TODO Integrate with Last.FM
+func (c *BrowsingController) GetTopSongs(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
+ response := NewResponse()
+ response.TopSongs = &responses.TopSongs{}
+ return response, nil
+}
+
func (c *BrowsingController) buildDirectory(ctx context.Context, d *engine.DirectoryInfo) *responses.Directory {
dir := &responses.Directory{
Id: d.Id,
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .JSON b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .JSON
new file mode 100644
index 000000000..b8044a506
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","topSongs":{"song":[{"id":"1","isDir":false,"title":"title","isVideo":false}]}}
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .XML b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .XML
new file mode 100644
index 000000000..a4e62d774
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs with data should match .XML
@@ -0,0 +1 @@
+
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .JSON b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .JSON
new file mode 100644
index 000000000..d578a767d
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","topSongs":{}}
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .XML b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .XML
new file mode 100644
index 000000000..cec47f95e
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses TopSongs without data should match .XML
@@ -0,0 +1 @@
+
diff --git a/server/subsonic/responses/responses.go b/server/subsonic/responses/responses.go
index 3013d9cc7..0f1c4a9ab 100644
--- a/server/subsonic/responses/responses.go
+++ b/server/subsonic/responses/responses.go
@@ -38,6 +38,7 @@ type Subsonic struct {
ArtistInfo *ArtistInfo `xml:"artistInfo,omitempty" json:"artistInfo,omitempty"`
ArtistInfo2 *ArtistInfo2 `xml:"artistInfo2,omitempty" json:"artistInfo2,omitempty"`
+ TopSongs *TopSongs `xml:"topSongs,omitempty" json:"topSongs,omitempty"`
PlayQueue *PlayQueue `xml:"playQueue,omitempty" json:"playQueue,omitempty"`
Bookmarks *Bookmarks `xml:"bookmarks,omitempty" json:"bookmarks,omitempty"`
@@ -297,6 +298,10 @@ type ArtistInfo2 struct {
SimilarArtist []ArtistID3 `xml:"similarArtist,omitempty" json:"similarArtist,omitempty"`
}
+type TopSongs struct {
+ Song []Child `xml:"song,omitempty" json:"song,omitempty"`
+}
+
type PlayQueue struct {
Entry []Child `xml:"entry,omitempty" json:"entry,omitempty"`
Current string `xml:"current,attr,omitempty" json:"current,omitempty"`
diff --git a/server/subsonic/responses/responses_test.go b/server/subsonic/responses/responses_test.go
index 729d73d7c..43dd303dd 100644
--- a/server/subsonic/responses/responses_test.go
+++ b/server/subsonic/responses/responses_test.go
@@ -332,6 +332,35 @@ var _ = Describe("Responses", func() {
})
})
+ Describe("TopSongs", func() {
+ BeforeEach(func() {
+ response.TopSongs = &TopSongs{}
+ })
+
+ Context("without data", func() {
+ It("should match .XML", func() {
+ Expect(xml.Marshal(response)).To(MatchSnapshot())
+ })
+ It("should match .JSON", func() {
+ Expect(json.Marshal(response)).To(MatchSnapshot())
+ })
+ })
+
+ Context("with data", func() {
+ BeforeEach(func() {
+ child := make([]Child, 1)
+ child[0] = Child{Id: "1", Title: "title", IsDir: false}
+ response.TopSongs.Song = child
+ })
+ It("should match .XML", func() {
+ Expect(xml.Marshal(response)).To(MatchSnapshot())
+ })
+ It("should match .JSON", func() {
+ Expect(json.Marshal(response)).To(MatchSnapshot())
+ })
+ })
+ })
+
Describe("PlayQueue", func() {
BeforeEach(func() {
response.PlayQueue = &PlayQueue{}