diff --git a/server/subsonic/helpers.go b/server/subsonic/helpers.go index 706a12c8b..46d1ab310 100644 --- a/server/subsonic/helpers.go +++ b/server/subsonic/helpers.go @@ -7,6 +7,7 @@ import ( "mime" "net/http" "sort" + "strconv" "strings" "github.com/navidrome/navidrome/consts" @@ -244,6 +245,24 @@ func childrenFromAlbums(ctx context.Context, als model.Albums) []responses.Child return children } +// toItemDate converts a string date in the formats 'YYYY-MM-DD', 'YYYY-MM' or 'YYYY' to an OS ItemDate +func toItemDate(date string) responses.ItemDate { + itemDate := responses.ItemDate{} + if date == "" { + return itemDate + } + parts := strings.Split(date, "-") + if len(parts) > 2 { + itemDate.Day, _ = strconv.Atoi(parts[2]) + } + if len(parts) > 1 { + itemDate.Month, _ = strconv.Atoi(parts[1]) + } + itemDate.Year, _ = strconv.Atoi(parts[0]) + + return itemDate +} + func buildItemGenres(genres model.Genres) []responses.ItemGenre { itemGenres := make([]responses.ItemGenre, len(genres)) for i, g := range genres { @@ -301,5 +320,6 @@ func buildAlbumID3(ctx context.Context, album model.Album) responses.AlbumID3 { dir.MusicBrainzId = album.MbzAlbumID dir.IsCompilation = album.Compilation dir.SortName = album.SortAlbumName + dir.OriginalReleaseDate = toItemDate(album.OriginalDate) return dir } diff --git a/server/subsonic/helpers_test.go b/server/subsonic/helpers_test.go index 898ca2a6c..8b33ebda4 100644 --- a/server/subsonic/helpers_test.go +++ b/server/subsonic/helpers_test.go @@ -57,4 +57,15 @@ var _ = Describe("helpers", func() { Expect(buildDiscSubtitles(context.Background(), album)).To(Equal(expected)) }) }) + + DescribeTable("toItemDate", + func(date string, expected responses.ItemDate) { + Expect(toItemDate(date)).To(Equal(expected)) + }, + Entry("1994-02-04", "1994-02-04", responses.ItemDate{Year: 1994, Month: 2, Day: 4}), + Entry("1994-02", "1994-02", responses.ItemDate{Year: 1994, Month: 2}), + Entry("1994", "1994", responses.ItemDate{Year: 1994}), + Entry("19940201", "", responses.ItemDate{}), + Entry("", "", responses.ItemDate{}), + ) }) diff --git a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .JSON b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .JSON index 15ddbbcea..b7ba2d1dd 100644 --- a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .JSON +++ b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .JSON @@ -31,6 +31,11 @@ "title": "disc 2" } ], + "originalReleaseDate": { + "year": 1994, + "month": 2, + "day": 4 + }, "song": [ { "id": "1", diff --git a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .XML b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .XML index cfe3da99d..fd37f83f9 100644 --- a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .XML +++ b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 with data should match .XML @@ -4,6 +4,7 @@ + diff --git a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .JSON b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .JSON index 9508e14ba..8a5b87f24 100644 --- a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .JSON +++ b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .JSON @@ -12,6 +12,7 @@ "musicBrainzId": "", "isCompilation": false, "sortName": "", - "discTitles": [] + "discTitles": [], + "originalReleaseDate": {} } } diff --git a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .XML b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .XML index 58e03c04b..2b748953a 100644 --- a/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .XML +++ b/server/subsonic/responses/.snapshots/Responses AlbumWithSongsID3 without data should match .XML @@ -1,3 +1,5 @@ - + + + diff --git a/server/subsonic/responses/responses.go b/server/subsonic/responses/responses.go index f93a5967b..eb5a8c883 100644 --- a/server/subsonic/responses/responses.go +++ b/server/subsonic/responses/responses.go @@ -218,13 +218,14 @@ type AlbumID3 struct { Genre string `xml:"genre,attr,omitempty" json:"genre,omitempty"` // OpenSubsonic extensions - Played *time.Time `xml:"played,attr,omitempty" json:"played,omitempty"` - UserRating int32 `xml:"userRating,attr" json:"userRating"` - Genres ItemGenres `xml:"genres" json:"genres"` - MusicBrainzId string `xml:"musicBrainzId,attr" json:"musicBrainzId"` - IsCompilation bool `xml:"isCompilation,attr" json:"isCompilation"` - SortName string `xml:"sortName,attr" json:"sortName"` - DiscTitles DiscTitles `xml:"discTitles" json:"discTitles"` + Played *time.Time `xml:"played,attr,omitempty" json:"played,omitempty"` + UserRating int32 `xml:"userRating,attr" json:"userRating"` + Genres ItemGenres `xml:"genres" json:"genres"` + MusicBrainzId string `xml:"musicBrainzId,attr" json:"musicBrainzId"` + IsCompilation bool `xml:"isCompilation,attr" json:"isCompilation"` + SortName string `xml:"sortName,attr" json:"sortName"` + DiscTitles DiscTitles `xml:"discTitles" json:"discTitles"` + OriginalReleaseDate ItemDate `xml:"originalReleaseDate" json:"originalReleaseDate"` } type ArtistWithAlbumsID3 struct { @@ -492,3 +493,9 @@ func marshalJSONArray[T any](v []T) ([]byte, error) { a := v return json.Marshal(a) } + +type ItemDate struct { + Year int `xml:"year,attr,omitempty" json:"year,omitempty"` + Month int `xml:"month,attr,omitempty" json:"month,omitempty"` + Day int `xml:"day,attr,omitempty" json:"day,omitempty"` +} diff --git a/server/subsonic/responses/responses_test.go b/server/subsonic/responses/responses_test.go index 17ea9ec3d..47804d6ba 100644 --- a/server/subsonic/responses/responses_test.go +++ b/server/subsonic/responses/responses_test.go @@ -176,7 +176,8 @@ var _ = Describe("Responses", func() { Id: "1", Name: "album", Artist: "artist", Genre: "rock", Genres: []ItemGenre{{Name: "rock"}, {Name: "progressive"}}, MusicBrainzId: "1234", IsCompilation: true, SortName: "sorted album", - DiscTitles: DiscTitles{{Disc: 1, Title: "disc 1"}, {Disc: 2, Title: "disc 2"}}, + DiscTitles: DiscTitles{{Disc: 1, Title: "disc 1"}, {Disc: 2, Title: "disc 2"}}, + OriginalReleaseDate: ItemDate{Year: 1994, Month: 2, Day: 4}, } t := time.Date(2016, 03, 2, 20, 30, 0, 0, time.UTC) songs := []Child{{