add AlbumFilter to backend album iterators

This commit is contained in:
Drew Weymouth
2023-05-11 08:54:18 -07:00
parent 5634dfcfc1
commit 882f951aa1
6 changed files with 68 additions and 21 deletions
+51 -13
View File
@@ -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
+1 -1
View File
@@ -9,7 +9,7 @@ import (
func (l *LibraryManager) AllTracksIterator() TrackIterator {
return &allTracksIterator{
l: l,
albumIter: l.AlbumsIter(AlbumSortArtistAZ),
albumIter: l.AlbumsIter(AlbumSortArtistAZ, AlbumFilter{}),
}
}