fix: improve subsonic client compatibility

This commit is contained in:
2026-04-03 21:16:40 +03:00
parent a054192e45
commit 0b10dfe055
3 changed files with 166 additions and 23 deletions

View File

@@ -25,6 +25,7 @@ type Response struct {
Artist *ArtistFull `json:"artist,omitempty"`
Album *AlbumFull `json:"album,omitempty"`
AlbumList2 *AlbumList2 `json:"albumList2,omitempty"`
SongsByGenre *SongsByGenre `json:"songsByGenre,omitempty"`
Song *SongFull `json:"song,omitempty"`
RandomSong []SongRef `json:"randomSongs,omitempty"`
SearchResult3 *SearchResult3 `json:"searchResult3,omitempty"`
@@ -36,6 +37,7 @@ type Response struct {
Podcasts *Podcasts `json:"podcasts,omitempty"`
NewestPods *NewestPods `json:"newestPodcasts,omitempty"`
RadioStations *RadioStations `json:"internetRadioStations,omitempty"`
Extensions *Extensions `json:"openSubsonicExtensions,omitempty"`
ScanStatus *ScanStatus `json:"scanStatus,omitempty"`
Error *ErrorRef `json:"error,omitempty"`
}
@@ -74,6 +76,7 @@ type ArtistFull struct {
type AlbumRef struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
Title string `json:"title"`
Artist string `json:"artist"`
ArtistID string `json:"artistId"`
@@ -96,6 +99,10 @@ type AlbumList2 struct {
Album []AlbumRef `json:"album,omitempty"`
}
type SongsByGenre struct {
Song []SongRef `json:"song,omitempty"`
}
type SongFull struct {
ID string `json:"id"`
Title string `json:"title"`
@@ -188,6 +195,15 @@ type RadioStations struct {
InternetRadioStation []any `json:"internetRadioStation,omitempty"`
}
type Extensions struct {
Extension []Extension `json:"extension,omitempty"`
}
type Extension struct {
Name string `json:"name"`
Versions string `json:"versions"`
}
type ErrorRef struct {
Code int `json:"code"`
Message string `json:"message"`
@@ -248,7 +264,7 @@ func RandomSongsResponse(tracks []library.Track) Envelope {
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.CoverArtID,
CoverArt: track.AlbumID,
})
}
return response
@@ -265,12 +281,13 @@ func ArtistResponse(artist library.ArtistDetail) Envelope {
for _, album := range artist.Albums {
item.Albums = append(item.Albums, AlbumRef{
ID: album.ID,
Name: album.Title,
Title: album.Title,
Artist: album.ArtistName,
ArtistID: album.ArtistID,
Year: album.Year,
Genre: album.Genre,
CoverArt: album.CoverArtID,
CoverArt: album.ID,
})
}
response.SubsonicResponse.Artist = item
@@ -289,12 +306,13 @@ func Search3Response(results library.SearchResults) Envelope {
for _, album := range results.Albums {
payload.Album = append(payload.Album, AlbumRef{
ID: album.ID,
Name: album.Title,
Title: album.Title,
Artist: album.ArtistName,
ArtistID: album.ArtistID,
Year: album.Year,
Genre: album.Genre,
CoverArt: album.CoverArtID,
CoverArt: album.ID,
})
}
for _, track := range results.Tracks {
@@ -305,7 +323,7 @@ func Search3Response(results library.SearchResults) Envelope {
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.CoverArtID,
CoverArt: track.AlbumID,
})
}
response.SubsonicResponse.SearchResult3 = payload
@@ -324,12 +342,13 @@ func Starred2Response(results library.StarredResults) Envelope {
for _, album := range results.Albums {
payload.Album = append(payload.Album, AlbumRef{
ID: album.ID,
Name: album.Title,
Title: album.Title,
Artist: album.ArtistName,
ArtistID: album.ArtistID,
Year: album.Year,
Genre: album.Genre,
CoverArt: album.CoverArtID,
CoverArt: album.ID,
})
}
for _, track := range results.Tracks {
@@ -340,7 +359,7 @@ func Starred2Response(results library.StarredResults) Envelope {
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.CoverArtID,
CoverArt: track.AlbumID,
})
}
response.SubsonicResponse.Starred2 = payload
@@ -387,7 +406,7 @@ func PlaylistResponse(owner string, detail playlist.Detail) Envelope {
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.CoverArtID,
CoverArt: track.AlbumID,
})
}
response.SubsonicResponse.Playlist = item
@@ -402,14 +421,17 @@ func AlbumResponse(album library.AlbumDetail) Envelope {
Artist: album.ArtistName,
ArtistID: album.ArtistID,
Year: album.Year,
CoverArt: album.CoverArtID,
CoverArt: album.ID,
}
for _, track := range album.Tracks {
item.Song = append(item.Song, SongRef{
ID: track.ID,
Title: track.Title,
Album: track.AlbumTitle,
Artist: track.ArtistName,
ID: track.ID,
Title: track.Title,
Album: track.AlbumTitle,
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.AlbumID,
})
}
response.SubsonicResponse.Album = item
@@ -422,18 +444,37 @@ func AlbumList2Response(albums []library.Album) Envelope {
for _, album := range albums {
payload.Album = append(payload.Album, AlbumRef{
ID: album.ID,
Name: album.Title,
Title: album.Title,
Artist: album.ArtistName,
ArtistID: album.ArtistID,
Year: album.Year,
Genre: album.Genre,
CoverArt: album.CoverArtID,
CoverArt: album.ID,
})
}
response.SubsonicResponse.AlbumList2 = payload
return response
}
func SongsByGenreResponse(tracks []library.Track) Envelope {
response := PingResponse()
payload := &SongsByGenre{}
for _, track := range tracks {
payload.Song = append(payload.Song, SongRef{
ID: track.ID,
Title: track.Title,
Album: track.AlbumTitle,
Artist: track.ArtistName,
AlbumID: track.AlbumID,
ArtistID: track.ArtistID,
CoverArt: track.AlbumID,
})
}
response.SubsonicResponse.SongsByGenre = payload
return response
}
func SongResponse(track library.Track) Envelope {
response := PingResponse()
response.SubsonicResponse.Song = &SongFull{
@@ -445,7 +486,7 @@ func SongResponse(track library.Track) Envelope {
ArtistID: track.ArtistID,
Track: track.TrackNumber,
Duration: track.DurationSecs,
CoverArt: track.CoverArtID,
CoverArt: track.AlbumID,
}
return response
}
@@ -503,6 +544,17 @@ func InternetRadioStationsResponse() Envelope {
return response
}
func OpenSubsonicExtensionsResponse() Envelope {
response := PingResponse()
response.SubsonicResponse.Extensions = &Extensions{
Extension: []Extension{
{Name: "formPost", Versions: "1"},
{Name: "apiKeyAuthentication", Versions: "1"},
},
}
return response
}
func ErrorResponse(code int, message string) Envelope {
response := PingResponse()
response.SubsonicResponse.Status = "failed"