First step towards improving sorting for Artists. Use the same iterator approach as albums and tracks.
80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
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
|
|
}
|
|
}
|