misc: Implement Iterator approach for artists
First step towards improving sorting for Artists. Use the same iterator approach as albums and tracks.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
package subsonic
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"log"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/dweymouth/go-subsonic/subsonic"
|
||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||
"github.com/dweymouth/supersonic/backend/mediaprovider/helpers"
|
||||
"github.com/dweymouth/supersonic/sharedutil"
|
||||
)
|
||||
|
||||
const (
|
||||
ArtistSortNameAZ string = "Name (A-Z)"
|
||||
)
|
||||
|
||||
func (s *subsonicMediaProvider) ArtistSortOrders() []string {
|
||||
return []string{
|
||||
ArtistSortNameAZ,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) IterateArtists(sortOrder string) mediaprovider.ArtistIterator {
|
||||
if sortOrder == "" {
|
||||
sortOrder = ArtistSortNameAZ // default
|
||||
}
|
||||
switch sortOrder {
|
||||
case ArtistSortNameAZ:
|
||||
return s.baseArtistIterFromSimpleSortOrder(
|
||||
func(artists []*subsonic.ArtistID3) []*subsonic.ArtistID3 {
|
||||
slices.SortFunc(artists, func(a, b *subsonic.ArtistID3) int {
|
||||
return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name))
|
||||
})
|
||||
return artists
|
||||
},
|
||||
)
|
||||
default:
|
||||
log.Printf("Undefined artist sort order: %s", sortOrder)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) baseArtistIterFromSimpleSortOrder(sortFn func([]*subsonic.ArtistID3) []*subsonic.ArtistID3) mediaprovider.ArtistIterator {
|
||||
return helpers.NewArtistIterator(s.artistFetchFnFromStandardSort(sortFn))
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) artistFetchFnFromStandardSort(sortFn func([]*subsonic.ArtistID3) []*subsonic.ArtistID3) helpers.ArtistFetchFn {
|
||||
return makeArtistFetchFn(func(offset, limit int) ([]*subsonic.ArtistID3, error) {
|
||||
// When the iterator asks for a second page of results, return nil, as Subsonic does not support pagination for artists.
|
||||
if offset > 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
idxs, err := s.client.GetArtists(map[string]string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var artists []*subsonic.ArtistID3
|
||||
for _, idx := range idxs.Index {
|
||||
for _, ar := range idx.Artist {
|
||||
artists = append(artists, ar)
|
||||
}
|
||||
}
|
||||
artists = sortFn(artists)
|
||||
return artists, nil
|
||||
})
|
||||
}
|
||||
|
||||
func makeArtistFetchFn(subsonicFetchFn func(offset, limit int) ([]*subsonic.ArtistID3, error)) helpers.ArtistFetchFn {
|
||||
return func(offset, limit int) ([]*mediaprovider.Artist, error) {
|
||||
ar, err := subsonicFetchFn(offset, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sharedutil.MapSlice(ar, toArtistFromID3), nil
|
||||
}
|
||||
}
|
||||
@@ -130,20 +130,6 @@ func (s *subsonicMediaProvider) GetArtistInfo(artistID string) (*mediaprovider.A
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) GetArtists() ([]*mediaprovider.Artist, error) {
|
||||
idxs, err := s.client.GetArtists(map[string]string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var artists []*mediaprovider.Artist
|
||||
for _, idx := range idxs.Index {
|
||||
for _, ar := range idx.Artist {
|
||||
artists = append(artists, toArtistFromID3(ar))
|
||||
}
|
||||
}
|
||||
return artists, nil
|
||||
}
|
||||
|
||||
func (s *subsonicMediaProvider) GetCoverArt(id string, size int) (image.Image, error) {
|
||||
params := map[string]string{}
|
||||
if size > 0 {
|
||||
|
||||
Reference in New Issue
Block a user