diff --git a/server/subsonic/api.go b/server/subsonic/api.go
index ee76444e0..94d00fa3e 100644
--- a/server/subsonic/api.go
+++ b/server/subsonic/api.go
@@ -73,6 +73,8 @@ func (api *Router) routes() http.Handler {
H(reqParams, "getArtist", c.GetArtist)
H(reqParams, "getAlbum", c.GetAlbum)
H(reqParams, "getSong", c.GetSong)
+ H(reqParams, "getArtistInfo", c.GetArtistInfo)
+ H(reqParams, "getArtistInfo2", c.GetArtistInfo2)
})
r.Group(func(r chi.Router) {
c := initAlbumListController(api)
diff --git a/server/subsonic/browsing.go b/server/subsonic/browsing.go
index 7be8f7609..2650439e2 100644
--- a/server/subsonic/browsing.go
+++ b/server/subsonic/browsing.go
@@ -165,6 +165,30 @@ func (c *BrowsingController) GetGenres(w http.ResponseWriter, r *http.Request) (
return response, nil
}
+const noImageAvailableUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/1024px-No_image_available.svg.png"
+
+// TODO Integrate with Last.FM
+func (c *BrowsingController) GetArtistInfo(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
+ response := NewResponse()
+ response.ArtistInfo = &responses.ArtistInfo{}
+ response.ArtistInfo.Biography = "Biography not available"
+ response.ArtistInfo.SmallImageUrl = noImageAvailableUrl
+ response.ArtistInfo.MediumImageUrl = noImageAvailableUrl
+ response.ArtistInfo.LargeImageUrl = noImageAvailableUrl
+ return response, nil
+}
+
+// TODO Integrate with Last.FM
+func (c *BrowsingController) GetArtistInfo2(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
+ response := NewResponse()
+ response.ArtistInfo2 = &responses.ArtistInfo2{}
+ response.ArtistInfo2.Biography = "Biography not available"
+ response.ArtistInfo2.SmallImageUrl = noImageAvailableUrl
+ response.ArtistInfo2.MediumImageUrl = noImageAvailableUrl
+ response.ArtistInfo2.LargeImageUrl = noImageAvailableUrl
+ return response, nil
+}
+
func (c *BrowsingController) buildDirectory(d *engine.DirectoryInfo) *responses.Directory {
dir := &responses.Directory{
Id: d.Id,
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .JSON b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .JSON
new file mode 100644
index 000000000..35d7071da
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","artistInfo":{"biography":"Black Sabbath is an English \u003ca target='_blank' href=\"http://www.last.fm/tag/heavy%20metal\" class=\"bbcode_tag\" rel=\"tag\"\u003eheavy metal\u003c/a\u003e band","musicBrainzId":"5182c1d9-c7d2-4dad-afa0-ccfeada921a8","lastFmUrl":"http://www.last.fm/music/Black+Sabbath","smallImageUrl":"http://userserve-ak.last.fm/serve/64/27904353.jpg","mediumImageUrl":"http://userserve-ak.last.fm/serve/126/27904353.jpg","largeImageUrl":"http://userserve-ak.last.fm/serve/_/27904353/Black+Sabbath+sabbath+1970.jpg","similarArtist":[{"id":"22","name":"Accept"},{"id":"101","name":"Bruce Dickinson"},{"id":"26","name":"Aerosmith"}]}}
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .XML b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .XML
new file mode 100644
index 000000000..a1c26adbe
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo with data should match .XML
@@ -0,0 +1 @@
+Black Sabbath is an English <a target='_blank' href="http://www.last.fm/tag/heavy%20metal" class="bbcode_tag" rel="tag">heavy metal</a> band5182c1d9-c7d2-4dad-afa0-ccfeada921a8http://www.last.fm/music/Black+Sabbathhttp://userserve-ak.last.fm/serve/64/27904353.jpghttp://userserve-ak.last.fm/serve/126/27904353.jpghttp://userserve-ak.last.fm/serve/_/27904353/Black+Sabbath+sabbath+1970.jpg
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .JSON b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .JSON
new file mode 100644
index 000000000..b237947b5
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .JSON
@@ -0,0 +1 @@
+{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","artistInfo":{}}
diff --git a/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .XML b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .XML
new file mode 100644
index 000000000..87910d5b2
--- /dev/null
+++ b/server/subsonic/responses/.snapshots/responses-snapshotMatcher-Match-Responses ArtistInfo without data should match .XML
@@ -0,0 +1 @@
+
diff --git a/server/subsonic/responses/responses.go b/server/subsonic/responses/responses.go
index e77e9ed32..6ef81c8d9 100644
--- a/server/subsonic/responses/responses.go
+++ b/server/subsonic/responses/responses.go
@@ -34,6 +34,9 @@ type Subsonic struct {
Artist *Indexes `xml:"artists,omitempty" json:"artists,omitempty"`
ArtistWithAlbumsID3 *ArtistWithAlbumsID3 `xml:"artist,omitempty" json:"artist,omitempty"`
AlbumWithSongsID3 *AlbumWithSongsID3 `xml:"album,omitempty" json:"album,omitempty"`
+
+ ArtistInfo *ArtistInfo `xml:"artistInfo,omitempty" json:"artistInfo,omitempty"`
+ ArtistInfo2 *ArtistInfo2 `xml:"artistInfo2,omitempty" json:"artistInfo2,omitempty"`
}
type JsonWrapper struct {
@@ -272,3 +275,22 @@ type Genre struct {
type Genres struct {
Genre []Genre `xml:"genre,omitempty" json:"genre,omitempty"`
}
+
+type ArtistInfoBase struct {
+ Biography string `xml:"biography,omitempty" json:"biography,omitempty"`
+ MusicBrainzID string `xml:"musicBrainzId,omitempty" json:"musicBrainzId,omitempty"`
+ LastFmUrl string `xml:"lastFmUrl,omitempty" json:"lastFmUrl,omitempty"`
+ SmallImageUrl string `xml:"smallImageUrl,omitempty" json:"smallImageUrl,omitempty"`
+ MediumImageUrl string `xml:"mediumImageUrl,omitempty" json:"mediumImageUrl,omitempty"`
+ LargeImageUrl string `xml:"largeImageUrl,omitempty" json:"largeImageUrl,omitempty"`
+}
+
+type ArtistInfo struct {
+ ArtistInfoBase
+ SimilarArtist []Artist `xml:"similarArtist,omitempty" json:"similarArtist,omitempty"`
+}
+
+type ArtistInfo2 struct {
+ ArtistInfoBase
+ SimilarArtist []ArtistID3 `xml:"similarArtist,omitempty" json:"similarArtist,omitempty"`
+}
diff --git a/server/subsonic/responses/responses_test.go b/server/subsonic/responses/responses_test.go
index 30ad62758..8ca719bbc 100644
--- a/server/subsonic/responses/responses_test.go
+++ b/server/subsonic/responses/responses_test.go
@@ -282,4 +282,42 @@ var _ = Describe("Responses", func() {
})
})
})
+
+ Describe("ArtistInfo", func() {
+ BeforeEach(func() {
+ response.ArtistInfo = &ArtistInfo{}
+ })
+
+ 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() {
+ response.ArtistInfo.Biography = `Black Sabbath is an English heavy metal band`
+ response.ArtistInfo.MusicBrainzID = "5182c1d9-c7d2-4dad-afa0-ccfeada921a8"
+ response.ArtistInfo.LastFmUrl = "http://www.last.fm/music/Black+Sabbath"
+ response.ArtistInfo.SmallImageUrl = "http://userserve-ak.last.fm/serve/64/27904353.jpg"
+ response.ArtistInfo.MediumImageUrl = "http://userserve-ak.last.fm/serve/126/27904353.jpg"
+ response.ArtistInfo.LargeImageUrl = "http://userserve-ak.last.fm/serve/_/27904353/Black+Sabbath+sabbath+1970.jpg"
+ response.ArtistInfo.SimilarArtist = []Artist{
+ {Id: "22", Name: "Accept"},
+ {Id: "101", Name: "Bruce Dickinson"},
+ {Id: "26", Name: "Aerosmith"},
+ }
+ })
+ It("should match .XML", func() {
+ Expect(xml.Marshal(response)).To(MatchSnapshot())
+ })
+ It("should match .JSON", func() {
+ Expect(json.Marshal(response)).To(MatchSnapshot())
+ })
+
+ })
+ })
})