diff --git a/backend/mediaprovider/helpers/albumiterator.go b/backend/mediaprovider/helpers/albumiterator.go index 6a68dbd..4e0873a 100644 --- a/backend/mediaprovider/helpers/albumiterator.go +++ b/backend/mediaprovider/helpers/albumiterator.go @@ -49,9 +49,11 @@ func (r *baseIter) Next() *mediaprovider.Album { return nil } r.serverPos += len(albums) - albums = sharedutil.FilterSlice(albums, func(al *mediaprovider.Album) bool { - return filterMatches(r.filter, al) - }) + if !r.filter.IsNil() { + albums = sharedutil.FilterSlice(albums, func(al *mediaprovider.Album) bool { + return filterMatches(r.filter, al) + }) + } r.prefetched = albums if len(albums) > 0 { break diff --git a/backend/mediaprovider/jellyfin/albumiterator.go b/backend/mediaprovider/jellyfin/albumiterator.go index 80e302f..0eb72a3 100644 --- a/backend/mediaprovider/jellyfin/albumiterator.go +++ b/backend/mediaprovider/jellyfin/albumiterator.go @@ -1,6 +1,11 @@ package jellyfin -import "github.com/dweymouth/supersonic/backend/mediaprovider" +import ( + "github.com/dweymouth/go-jellyfin" + "github.com/dweymouth/supersonic/backend/mediaprovider" + "github.com/dweymouth/supersonic/backend/mediaprovider/helpers" + "github.com/dweymouth/supersonic/sharedutil" +) const ( AlbumSortRecentlyAdded string = "Recently Added" @@ -26,9 +31,64 @@ func (j *jellyfinMediaProvider) AlbumSortOrders() []string { } } -func (s *jellyfinMediaProvider) IterateAlbums(sortOrder string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator { - return nil - // TODO: unimplemented +func (j *jellyfinMediaProvider) IterateAlbums(sortOrder string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator { + var jfFilt jellyfin.Filter + if filter.ExcludeUnfavorited { + jfFilt.Favorite = true + filter.ExcludeUnfavorited = false + } + var jfSort jellyfin.Sort + switch sortOrder { + case AlbumSortRecentlyAdded: + jfSort.Field = "DateCreated" + jfSort.Mode = jellyfin.SortDesc + case AlbumSortFrequentlyPlayed: + jfSort.Field = "PlayCount" + jfSort.Mode = jellyfin.SortDesc + case AlbumSortRandom: + jfSort.Field = "Random" + case AlbumSortArtistAZ: + jfSort.Field = "AlbumArtist" + jfSort.Mode = jellyfin.SortAsc + case AlbumSortTitleAZ: + jfSort.Field = "SortName" + jfSort.Mode = jellyfin.SortAsc + case AlbumSortRecentlyPlayed: + jfSort.Field = "DatePlayed" + jfSort.Mode = jellyfin.SortDesc + case AlbumSortYearAscending: + jfSort.Field = "ProductionYear" + jfSort.Mode = jellyfin.SortAsc + case AlbumSortYearDescending: + jfSort.Field = "ProductionYear" + jfSort.Mode = jellyfin.SortDesc + } + fetcher := func(offs, limit int) ([]*mediaprovider.Album, error) { + al, err := j.client.GetAlbums(jellyfin.QueryOpts{ + Sort: jfSort, + Filter: jfFilt, + Paging: jellyfin.Paging{StartIndex: offs, Limit: limit}, + }) + if err != nil { + return nil, err + } + return sharedutil.MapSlice(al, toAlbum), nil + } + if sortOrder == AlbumSortRandom { + determFetcher := func(offs, limit int) ([]*mediaprovider.Album, error) { + al, err := j.client.GetAlbums(jellyfin.QueryOpts{ + Sort: jellyfin.Sort{Field: "SortName", Mode: jellyfin.SortAsc}, + Filter: jfFilt, + Paging: jellyfin.Paging{StartIndex: offs, Limit: limit}, + }) + if err != nil { + return nil, err + } + return sharedutil.MapSlice(al, toAlbum), nil + } + return helpers.NewRandomIter(determFetcher, fetcher, filter, j.prefetchCoverCB) + } + return helpers.NewBaseIter(fetcher, filter, j.prefetchCoverCB) } func (s *jellyfinMediaProvider) SearchAlbums(searchQuery string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator { diff --git a/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go b/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go index 9d4bee4..818e934 100644 --- a/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go +++ b/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go @@ -9,12 +9,21 @@ import ( "time" "github.com/dweymouth/go-jellyfin" + jellyfinCli "github.com/dweymouth/go-jellyfin" "github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/sharedutil" ) const cacheValidDurationSeconds = 60 +type JellyfinServer struct { + jellyfinCli.Client +} + +func (j *JellyfinServer) MediaProvider() mediaprovider.MediaProvider { + return newJellyfinMediaProvider(&j.Client) +} + var _ mediaprovider.MediaProvider = (*jellyfinMediaProvider)(nil) type jellyfinMediaProvider struct { diff --git a/backend/mediaprovider/jellyfin/jellyfinserver.go b/backend/mediaprovider/jellyfin/jellyfinserver.go deleted file mode 100644 index 623e378..0000000 --- a/backend/mediaprovider/jellyfin/jellyfinserver.go +++ /dev/null @@ -1,14 +0,0 @@ -package jellyfin - -import ( - jellyfinCli "github.com/dweymouth/go-jellyfin" - "github.com/dweymouth/supersonic/backend/mediaprovider" -) - -type JellyfinServer struct { - jellyfinCli.Client -} - -func (j *JellyfinServer) MediaProvider() mediaprovider.MediaProvider { - return newJellyfinMediaProvider(&j.Client) -} diff --git a/backend/mediaprovider/mediaprovider.go b/backend/mediaprovider/mediaprovider.go index 121d6fa..644511b 100644 --- a/backend/mediaprovider/mediaprovider.go +++ b/backend/mediaprovider/mediaprovider.go @@ -14,6 +14,13 @@ type AlbumFilter struct { ExcludeUnfavorited bool // mut. exc. with ExcludeFavorited } +// Returns true if the filter is the nil filter - i.e. matches everything +func (a *AlbumFilter) IsNil() bool { + return a.MinYear == 0 && a.MaxYear == 0 && + len(a.Genres) == 0 && + !a.ExcludeFavorited && !a.ExcludeUnfavorited +} + type AlbumIterator interface { Next() *Album } diff --git a/backend/mediaprovider/subsonic/albumiterator.go b/backend/mediaprovider/subsonic/albumiterator.go index f84355a..6fa71e1 100644 --- a/backend/mediaprovider/subsonic/albumiterator.go +++ b/backend/mediaprovider/subsonic/albumiterator.go @@ -74,6 +74,7 @@ func (s *subsonicMediaProvider) IterateAlbums(sortOrder string, filter mediaprov return helpers.NewBaseIter(makeFetchFn(fetchFn), filter, s.prefetchCoverCB) } if sortOrder == "" && filter.ExcludeUnfavorited { + filter.ExcludeUnfavorited = false // we're already filtering by this return s.baseIterFromSimpleSortOrder("starred", filter) } if sortOrder == "" {