add AlbumFilter to backend album iterators
This commit is contained in:
+51
-13
@@ -3,8 +3,10 @@ package backend
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dweymouth/go-subsonic/subsonic"
|
||||
"github.com/dweymouth/supersonic/sharedutil"
|
||||
)
|
||||
|
||||
type AlbumSortOrder string
|
||||
@@ -33,36 +35,69 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func (l *LibraryManager) AlbumsIter(sort AlbumSortOrder) AlbumIterator {
|
||||
type AlbumFilter struct {
|
||||
MinYear int
|
||||
MaxYear int // 0 == unset/match any
|
||||
Genres []string // len(0) == unset/match any
|
||||
|
||||
ExcludeFavorited bool // mut. exc. with ExcludeUnfavorited
|
||||
ExcludeUnfavorited bool // mut. exc. with ExcludeFavorited
|
||||
}
|
||||
|
||||
func (f *AlbumFilter) Matches(album *subsonic.AlbumID3) bool {
|
||||
if album == nil {
|
||||
return false
|
||||
}
|
||||
if f.ExcludeFavorited && !album.Starred.IsZero() {
|
||||
return false
|
||||
}
|
||||
if f.ExcludeUnfavorited && album.Starred.IsZero() {
|
||||
return false
|
||||
}
|
||||
if y := album.Year; y < f.MinYear || (f.MaxYear > 0 && y > f.MaxYear) {
|
||||
return false
|
||||
}
|
||||
if len(f.Genres) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, g := range f.Genres {
|
||||
if strings.EqualFold(g, album.Genre) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (l *LibraryManager) AlbumsIter(sort AlbumSortOrder, filter AlbumFilter) AlbumIterator {
|
||||
switch sort {
|
||||
case AlbumSortRecentlyAdded:
|
||||
return l.newBaseIter("newest", make(map[string]string))
|
||||
return l.newBaseIter("newest", filter, make(map[string]string))
|
||||
case AlbumSortRecentlyPlayed:
|
||||
return l.newBaseIter("recent", make(map[string]string))
|
||||
return l.newBaseIter("recent", filter, make(map[string]string))
|
||||
case AlbumSortFrequentlyPlayed:
|
||||
return l.newBaseIter("frequent", make(map[string]string))
|
||||
return l.newBaseIter("frequent", filter, make(map[string]string))
|
||||
case AlbumSortRandom:
|
||||
return l.newRandomIter()
|
||||
case AlbumSortTitleAZ:
|
||||
return l.newBaseIter("alphabeticalByName", make(map[string]string))
|
||||
return l.newBaseIter("alphabeticalByName", filter, make(map[string]string))
|
||||
case AlbumSortArtistAZ:
|
||||
return l.newBaseIter("alphabeticalByArtist", make(map[string]string))
|
||||
return l.newBaseIter("alphabeticalByArtist", filter, make(map[string]string))
|
||||
case AlbumSortYearAscending:
|
||||
return l.newBaseIter("byYear", map[string]string{"fromYear": "0", "toYear": "3000"})
|
||||
return l.newBaseIter("byYear", filter, map[string]string{"fromYear": "0", "toYear": "3000"})
|
||||
case AlbumSortYearDescending:
|
||||
return l.newBaseIter("byYear", map[string]string{"fromYear": "3000", "toYear": "0"})
|
||||
return l.newBaseIter("byYear", filter, map[string]string{"fromYear": "3000", "toYear": "0"})
|
||||
default:
|
||||
log.Printf("Undefined album sort order: %s", sort)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LibraryManager) StarredIter() AlbumIterator {
|
||||
return l.newBaseIter("starred", make(map[string]string))
|
||||
func (l *LibraryManager) StarredIter(filter AlbumFilter) AlbumIterator {
|
||||
return l.newBaseIter("starred", filter, make(map[string]string))
|
||||
}
|
||||
|
||||
func (l *LibraryManager) GenreIter(genre string) AlbumIterator {
|
||||
return l.newBaseIter("byGenre", map[string]string{"genre": genre})
|
||||
func (l *LibraryManager) GenreIter(genre string, filter AlbumFilter) AlbumIterator {
|
||||
return l.newBaseIter("byGenre", filter, map[string]string{"genre": genre})
|
||||
}
|
||||
|
||||
func (l *LibraryManager) SearchIter(query string) AlbumIterator {
|
||||
@@ -83,6 +118,7 @@ func (l *LibraryManager) GetAlbum(id string) (*subsonic.AlbumID3, error) {
|
||||
|
||||
type baseIter struct {
|
||||
listType string
|
||||
filter AlbumFilter
|
||||
pos int
|
||||
l *LibraryManager
|
||||
s *subsonic.Client
|
||||
@@ -92,9 +128,10 @@ type baseIter struct {
|
||||
done bool
|
||||
}
|
||||
|
||||
func (l *LibraryManager) newBaseIter(listType string, opts map[string]string) *baseIter {
|
||||
func (l *LibraryManager) newBaseIter(listType string, filter AlbumFilter, opts map[string]string) *baseIter {
|
||||
return &baseIter{
|
||||
listType: listType,
|
||||
filter: filter,
|
||||
l: l,
|
||||
s: l.s.Server,
|
||||
opts: opts,
|
||||
@@ -123,6 +160,7 @@ func (r *baseIter) Next() *subsonic.AlbumID3 {
|
||||
log.Println(err)
|
||||
albums = nil
|
||||
}
|
||||
albums = sharedutil.FilterSlice(albums, r.filter.Matches)
|
||||
if len(albums) == 0 {
|
||||
r.done = true
|
||||
return nil
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func (l *LibraryManager) AllTracksIterator() TrackIterator {
|
||||
return &allTracksIterator{
|
||||
l: l,
|
||||
albumIter: l.AlbumsIter(AlbumSortArtistAZ),
|
||||
albumIter: l.AlbumsIter(AlbumSortArtistAZ, AlbumFilter{}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ func SliceContains[T comparable](ts []T, t T) bool {
|
||||
}
|
||||
|
||||
func FilterSlice[T any](ss []T, test func(T) bool) []T {
|
||||
if ss == nil {
|
||||
return nil
|
||||
}
|
||||
result := make([]T, 0)
|
||||
for _, s := range ss {
|
||||
if test(s) {
|
||||
@@ -27,6 +30,9 @@ func FilterSlice[T any](ss []T, test func(T) bool) []T {
|
||||
}
|
||||
|
||||
func MapSlice[T any, U any](ts []T, f func(T) U) []U {
|
||||
if ts == nil {
|
||||
return nil
|
||||
}
|
||||
result := make([]U, len(ts))
|
||||
for i, t := range ts {
|
||||
result[i] = f(t)
|
||||
|
||||
@@ -71,7 +71,7 @@ func NewAlbumsPage(cfg *backend.AlbumsPageConfig, contr *controller.Controller,
|
||||
cfg.SortOrder = string(backend.AlbumSortRecentlyAdded)
|
||||
}
|
||||
a.sortOrder.Selected = cfg.SortOrder
|
||||
iter := lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected))
|
||||
iter := lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected), backend.AlbumFilter{})
|
||||
a.grid = widgets.NewGridView(widgets.NewGridViewAlbumIterator(iter), im)
|
||||
contr.ConnectAlbumGridActions(a.grid)
|
||||
a.searcher = widgets.NewSearchEntry()
|
||||
@@ -154,7 +154,7 @@ func (a *AlbumsPage) Reload() {
|
||||
if a.searchText != "" {
|
||||
a.doSearch(a.searchText)
|
||||
} else {
|
||||
iter := a.lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected))
|
||||
iter := a.lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected), backend.AlbumFilter{})
|
||||
a.grid.Reset(widgets.NewGridViewAlbumIterator(iter))
|
||||
a.grid.Refresh()
|
||||
}
|
||||
@@ -190,7 +190,7 @@ func (a *AlbumsPage) doSearch(query string) {
|
||||
|
||||
func (a *AlbumsPage) onSortOrderChanged(order string) {
|
||||
a.cfg.SortOrder = a.sortOrder.Selected
|
||||
iter := a.lm.AlbumsIter(backend.AlbumSortOrder(order))
|
||||
iter := a.lm.AlbumsIter(backend.AlbumSortOrder(order), backend.AlbumFilter{})
|
||||
a.grid.Reset(widgets.NewGridViewAlbumIterator(iter))
|
||||
if a.searchText == "" {
|
||||
a.container.Objects[0] = a.grid
|
||||
|
||||
@@ -55,7 +55,8 @@ func NewFavoritesPage(cfg *backend.FavoritesPageConfig, contr *controller.Contro
|
||||
}
|
||||
a.ExtendBaseWidget(a)
|
||||
a.createHeader(0, "")
|
||||
a.grid = widgets.NewGridView(widgets.NewGridViewAlbumIterator(lm.StarredIter()), a.im)
|
||||
iter := lm.StarredIter(backend.AlbumFilter{})
|
||||
a.grid = widgets.NewGridView(widgets.NewGridViewAlbumIterator(iter), a.im)
|
||||
a.contr.ConnectAlbumGridActions(a.grid)
|
||||
if cfg.InitialView == "Artists" {
|
||||
a.toggleBtns.SetActivatedButton(1)
|
||||
@@ -129,7 +130,8 @@ func (a *FavoritesPage) Reload() {
|
||||
if a.searchText != "" {
|
||||
a.doSearchAlbums(a.searchText)
|
||||
} else {
|
||||
a.grid.Reset(widgets.NewGridViewAlbumIterator(a.lm.StarredIter()))
|
||||
iter := a.lm.StarredIter(backend.AlbumFilter{})
|
||||
a.grid.Reset(widgets.NewGridViewAlbumIterator(iter))
|
||||
}
|
||||
if a.tracklistCtr != nil || a.artistListCtr != nil {
|
||||
go func() {
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewGenrePage(genre string, contr *controller.Controller, pm *backend.Playba
|
||||
SizeName: theme.SizeNameHeadingText,
|
||||
}
|
||||
g.playRandom = widget.NewButtonWithIcon(" Play random", myTheme.ShuffleIcon, g.playRandomSongs)
|
||||
iter := g.lm.GenreIter(g.genre)
|
||||
iter := g.lm.GenreIter(g.genre, backend.AlbumFilter{})
|
||||
g.grid = widgets.NewGridView(widgets.NewGridViewAlbumIterator(iter), g.im)
|
||||
g.contr.ConnectAlbumGridActions(g.grid)
|
||||
g.searcher = widgets.NewSearchEntry()
|
||||
@@ -118,7 +118,8 @@ func (g *GenrePage) Reload() {
|
||||
if g.searchText != "" {
|
||||
g.doSearch(g.searchText)
|
||||
} else {
|
||||
g.grid.Reset(widgets.NewGridViewAlbumIterator(g.lm.GenreIter(g.genre)))
|
||||
iter := g.lm.GenreIter(g.genre, backend.AlbumFilter{})
|
||||
g.grid.Reset(widgets.NewGridViewAlbumIterator(iter))
|
||||
g.grid.Refresh()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user