fix: Add cloning logic to filters, make providers not update original filter
This commit is contained in:
@@ -195,6 +195,8 @@ func (n nilFilter[M]) IsNil() bool { return true }
|
||||
|
||||
func (n nilFilter[M]) Matches(*M) bool { return true }
|
||||
|
||||
func (n nilFilter[M]) Clone() mediaprovider.MediaFilter[M, nilFilterOptions] { return n }
|
||||
|
||||
func (n nilFilter[M]) Options() nilFilterOptions { return nilFilterOptions{} }
|
||||
|
||||
func (n nilFilter[M]) SetOptions(o nilFilterOptions) {}
|
||||
func (n nilFilter[M]) SetOptions(options nilFilterOptions) {}
|
||||
|
||||
@@ -58,7 +58,7 @@ func (j *jellyfinMediaProvider) IterateAlbums(sortOrder string, filter mediaprov
|
||||
jfSort.Field = jellyfin.SortByYear
|
||||
jfSort.Mode = jellyfin.SortDesc
|
||||
}
|
||||
jfFilt := jfFilterFromFilter(filter)
|
||||
jfFilt, modifiedFilter := jfFilterFromFilter(filter)
|
||||
|
||||
fetcher := func(offs, limit int) ([]*mediaprovider.Album, error) {
|
||||
al, err := j.client.GetAlbums(jellyfin.QueryOpts{
|
||||
@@ -84,9 +84,9 @@ func (j *jellyfinMediaProvider) IterateAlbums(sortOrder string, filter mediaprov
|
||||
}
|
||||
return sharedutil.MapSlice(al, toAlbum), nil
|
||||
}
|
||||
return helpers.NewRandomAlbumIter(determFetcher, fetcher, filter, j.prefetchCoverCB)
|
||||
return helpers.NewRandomAlbumIter(determFetcher, fetcher, modifiedFilter, j.prefetchCoverCB)
|
||||
}
|
||||
return helpers.NewAlbumIterator(fetcher, filter, j.prefetchCoverCB)
|
||||
return helpers.NewAlbumIterator(fetcher, modifiedFilter, j.prefetchCoverCB)
|
||||
}
|
||||
|
||||
func (j *jellyfinMediaProvider) SearchAlbums(searchQuery string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator {
|
||||
@@ -151,15 +151,20 @@ func (j *jellyfinMediaProvider) IterateArtists(sortOrder string) mediaprovider.A
|
||||
}
|
||||
|
||||
// Creates the Jellyfin filter to implement the given mediaprovider filter,
|
||||
// and zeros out the now-unneeded fields in the mediaprovider filter.
|
||||
func jfFilterFromFilter(filter mediaprovider.AlbumFilter) jellyfin.Filter {
|
||||
// and returns a modified mediaprovider filter, with now-unneeded fields zeroed out.
|
||||
func jfFilterFromFilter(filter mediaprovider.AlbumFilter) (jellyfin.Filter, mediaprovider.AlbumFilter) {
|
||||
var jfFilt jellyfin.Filter
|
||||
|
||||
filterOptions := filter.Options()
|
||||
// Clone the original filter to not modify its options.
|
||||
// Set filters must be maintained in the original filter, as they are used for the UI.
|
||||
// Modified filter options are used to ignore further filtering that was already handled by the
|
||||
// Jellyfin API.
|
||||
modifiedFilter := filter.Clone()
|
||||
filterOptions := modifiedFilter.Options()
|
||||
|
||||
if filterOptions.ExcludeUnfavorited {
|
||||
jfFilt.Favorite = true
|
||||
filterOptions.ExcludeUnfavorited = false // Jellyfin will handle this filter
|
||||
filterOptions.ExcludeUnfavorited = false
|
||||
}
|
||||
if filterOptions.MinYear > 0 && filterOptions.MaxYear > 0 {
|
||||
jfFilt.YearRange = [2]int{filterOptions.MinYear, filterOptions.MaxYear}
|
||||
@@ -174,7 +179,6 @@ func jfFilterFromFilter(filter mediaprovider.AlbumFilter) jellyfin.Filter {
|
||||
jfFilt.Genres = filterOptions.Genres
|
||||
filterOptions.Genres = nil
|
||||
|
||||
filter.SetOptions(filterOptions)
|
||||
|
||||
return jfFilt
|
||||
modifiedFilter.SetOptions(filterOptions)
|
||||
return jfFilt, modifiedFilter
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ type TrackIterator = MediaIterator[Track]
|
||||
type MediaFilter[M, F any] interface {
|
||||
Options() F
|
||||
SetOptions(F)
|
||||
Clone() MediaFilter[M, F]
|
||||
IsNil() bool
|
||||
Matches(*M) bool
|
||||
}
|
||||
@@ -33,6 +34,19 @@ type AlbumFilterOptions struct {
|
||||
ExcludeUnfavorited bool // mut. exc. with ExcludeFavorited
|
||||
}
|
||||
|
||||
// Clone returns a deep copy of the filter options
|
||||
func (o AlbumFilterOptions) Clone() AlbumFilterOptions {
|
||||
genres := make([]string, len(o.Genres))
|
||||
copy(genres, o.Genres)
|
||||
return AlbumFilterOptions{
|
||||
MinYear: o.MinYear,
|
||||
MaxYear: o.MaxYear,
|
||||
Genres: genres,
|
||||
ExcludeFavorited: o.ExcludeFavorited,
|
||||
ExcludeUnfavorited: o.ExcludeUnfavorited,
|
||||
}
|
||||
}
|
||||
|
||||
type albumFilter struct {
|
||||
options AlbumFilterOptions
|
||||
}
|
||||
@@ -45,8 +59,13 @@ func (a albumFilter) Options() AlbumFilterOptions {
|
||||
return a.options
|
||||
}
|
||||
|
||||
func (a *albumFilter) SetOptions(o AlbumFilterOptions) {
|
||||
a.options = o
|
||||
func (a *albumFilter) SetOptions(options AlbumFilterOptions) {
|
||||
a.options = options
|
||||
}
|
||||
|
||||
// Clone returns a deep copy of the filter
|
||||
func (a albumFilter) Clone() AlbumFilter {
|
||||
return NewAlbumFilter(a.options.Clone())
|
||||
}
|
||||
|
||||
// Returns true if the filter is the nil filter - i.e. matches everything
|
||||
|
||||
@@ -68,18 +68,22 @@ func (s *subsonicMediaProvider) IterateAlbums(sortOrder string, filter mediaprov
|
||||
// but servers do internally match against all the genres the album is categorized with.
|
||||
// So we must not additionally filter by genre to avoid excluding results where
|
||||
// the single genre returned by Subsonic isn't the one we're iterating on.
|
||||
filterOptions.Genres = nil
|
||||
modifiedFilter := filter.Clone()
|
||||
modifiedOptions := modifiedFilter.Options()
|
||||
modifiedOptions.Genres = nil
|
||||
modifiedFilter.SetOptions(modifiedOptions)
|
||||
fetchFn := func(offset, limit int) ([]*subsonic.AlbumID3, error) {
|
||||
return s.client.GetAlbumList2("byGenre",
|
||||
map[string]string{"genre": genre, "offset": strconv.Itoa(offset), "limit": strconv.Itoa(limit)})
|
||||
}
|
||||
filter.SetOptions(filterOptions)
|
||||
return helpers.NewAlbumIterator(makeFetchFn(fetchFn), filter, s.prefetchCoverCB)
|
||||
return helpers.NewAlbumIterator(makeFetchFn(fetchFn), modifiedFilter, s.prefetchCoverCB)
|
||||
}
|
||||
if sortOrder == "" && filterOptions.ExcludeUnfavorited {
|
||||
filterOptions.ExcludeUnfavorited = false // we're already filtering by this
|
||||
filter.SetOptions(filterOptions)
|
||||
return s.baseIterFromSimpleSortOrder("starred", filter)
|
||||
modifiedFilter := filter.Clone()
|
||||
modifiedOptions := modifiedFilter.Options()
|
||||
modifiedOptions.ExcludeUnfavorited = false // we're already filtering by this
|
||||
modifiedFilter.SetOptions(modifiedOptions)
|
||||
return s.baseIterFromSimpleSortOrder("starred", modifiedFilter)
|
||||
}
|
||||
if sortOrder == "" {
|
||||
sortOrder = AlbumSortRecentlyAdded // default
|
||||
|
||||
Reference in New Issue
Block a user