fix some bugs and restructure a bit more

This commit is contained in:
Drew Weymouth
2023-05-15 17:05:18 -07:00
parent fd106560d0
commit f926ed3fb9
14 changed files with 183 additions and 224 deletions
+3 -1
View File
@@ -44,10 +44,12 @@ type MediaProvider interface {
AlbumSortOrders() []string
IterateAlbums(sortOrder string, searchQuery string, filter AlbumFilter) AlbumIterator
IterateAlbums(sortOrder string, filter AlbumFilter) AlbumIterator
IterateTracks(searchQuery string) TrackIterator
SearchAlbums(searchQuery string, filter AlbumFilter) AlbumIterator
GetRandomTracks(genre string, count int) ([]*Track, error)
GetSimilarTracks(artistID string, count int) ([]*Track, error)
+30 -34
View File
@@ -10,6 +10,30 @@ import (
"github.com/dweymouth/supersonic/sharedutil"
)
const (
AlbumSortRecentlyAdded string = "Recently Added"
AlbumSortRecentlyPlayed string = "Recently Played"
AlbumSortFrequentlyPlayed string = "Frequently Played"
AlbumSortRandom string = "Random"
AlbumSortTitleAZ string = "Title (A-Z)"
AlbumSortArtistAZ string = "Artist (A-Z)"
AlbumSortYearAscending string = "Year (ascending)"
AlbumSortYearDescending string = "Year (descending)"
)
func (s *subsonicMediaProvider) AlbumSortOrders() []string {
return []string{
AlbumSortRecentlyAdded,
AlbumSortRecentlyPlayed,
AlbumSortFrequentlyPlayed,
AlbumSortRandom,
AlbumSortTitleAZ,
AlbumSortArtistAZ,
AlbumSortYearAscending,
AlbumSortYearDescending,
}
}
func filterMatches(f mediaprovider.AlbumFilter, album *subsonic.AlbumID3) bool {
if album == nil {
return false
@@ -34,15 +58,7 @@ func filterMatches(f mediaprovider.AlbumFilter, album *subsonic.AlbumID3) bool {
return false
}
func filterIsEmpty(f mediaprovider.AlbumFilter) bool {
return !f.ExcludeFavorited && !f.ExcludeUnfavorited &&
f.MinYear == 0 && f.MaxYear == 0 && len(f.Genres) == 0
}
func (s *subsonicMediaProvider) IterateAlbums(sortOrder, searchQuery string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator {
if searchQuery != "" {
return s.newSearchIter(searchQuery, filter)
}
func (s *subsonicMediaProvider) IterateAlbums(sortOrder string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator {
if sortOrder == "" && len(filter.Genres) == 1 {
return s.newBaseIter("byGenre", filter, map[string]string{"genre": filter.Genres[0]})
}
@@ -72,6 +88,10 @@ func (s *subsonicMediaProvider) IterateAlbums(sortOrder, searchQuery string, fil
}
}
func (s *subsonicMediaProvider) SearchAlbums(searchQuery string, filter mediaprovider.AlbumFilter) mediaprovider.AlbumIterator {
return s.newSearchIter(searchQuery, filter)
}
type baseIter struct {
listType string
filter mediaprovider.AlbumFilter
@@ -217,7 +237,7 @@ func (s *searchIter) addNewAlbums(al []*subsonic.AlbumID3) {
if _, have := s.albumIDset[album.ID]; have {
continue
}
if filterMatches(s.filter, album) {
if !filterMatches(s.filter, album) {
continue
}
s.prefetched = append(s.prefetched, album)
@@ -326,27 +346,3 @@ func (r *randomIter) Next() *mediaprovider.Album {
return nil
}
/*
type BatchingIterator struct {
iter AlbumIterator
}
func NewBatchingIterator(iter AlbumIterator) *BatchingIterator {
return &BatchingIterator{iter}
}
func (b *BatchingIterator) NextN(n int) []*subsonic.AlbumID3 {
results := make([]*subsonic.AlbumID3, 0, n)
i := 0
for i < n {
album := b.iter.Next()
if album == nil {
break
}
results = append(results, album)
i++
}
return results
}
*/
@@ -12,17 +12,6 @@ import (
"github.com/dweymouth/supersonic/sharedutil"
)
const (
AlbumSortRecentlyAdded string = "Recently Added"
AlbumSortRecentlyPlayed string = "Recently Played"
AlbumSortFrequentlyPlayed string = "Frequently Played"
AlbumSortRandom string = "Random"
AlbumSortTitleAZ string = "Title (A-Z)"
AlbumSortArtistAZ string = "Artist (A-Z)"
AlbumSortYearAscending string = "Year (ascending)"
AlbumSortYearDescending string = "Year (descending)"
)
type subsonicMediaProvider struct {
client *subsonic.Client
}
@@ -31,19 +20,6 @@ func SubsonicMediaProvider(subsonicClient *subsonic.Client) mediaprovider.MediaP
return &subsonicMediaProvider{client: subsonicClient}
}
func (s *subsonicMediaProvider) AlbumSortOrders() []string {
return []string{
AlbumSortRecentlyAdded,
AlbumSortRecentlyPlayed,
AlbumSortFrequentlyPlayed,
AlbumSortRandom,
AlbumSortTitleAZ,
AlbumSortArtistAZ,
AlbumSortYearAscending,
AlbumSortYearDescending,
}
}
func (s *subsonicMediaProvider) CreatePlaylist(name string, trackIDs []string) error {
return s.client.CreatePlaylistWithTracks(trackIDs, map[string]string{"name": name})
}
@@ -69,21 +45,11 @@ func (s *subsonicMediaProvider) GetAlbum(albumID string) (*mediaprovider.AlbumWi
if err != nil {
return nil, err
}
return &mediaprovider.AlbumWithTracks{
Album: mediaprovider.Album{
ID: al.ID,
Name: al.Name,
ArtistIDs: []string{al.ArtistID},
CoverArtID: al.CoverArt,
ArtistNames: []string{al.Artist},
Genres: []string{al.Genre},
Year: al.Year,
TrackCount: al.SongCount,
Favorite: !al.Starred.IsZero(),
Duration: al.Duration,
},
album := &mediaprovider.AlbumWithTracks{
Tracks: sharedutil.MapSlice(al.Song, toTrack),
}, nil
}
fillAlbum(al, &album.Album)
return album, nil
}
func (s *subsonicMediaProvider) GetArtist(artistID string) (*mediaprovider.ArtistWithAlbums, error) {
@@ -168,19 +134,11 @@ func (s *subsonicMediaProvider) GetPlaylist(playlistID string) (*mediaprovider.P
if err != nil {
return nil, err
}
return &mediaprovider.PlaylistWithTracks{
Playlist: mediaprovider.Playlist{
ID: pl.ID,
CoverArtID: pl.CoverArt,
Name: pl.Name,
Description: pl.Comment,
TrackCount: pl.SongCount,
Public: pl.Public,
Owner: pl.Owner,
Duration: pl.Duration,
},
playlist := &mediaprovider.PlaylistWithTracks{
Tracks: sharedutil.MapSlice(pl.Entry, toTrack),
}, nil
}
fillPlaylist(pl, &playlist.Playlist)
return playlist, nil
}
func (s *subsonicMediaProvider) GetPlaylists() ([]*mediaprovider.Playlist, error) {
@@ -261,34 +219,24 @@ func (s *subsonicMediaProvider) SetRating(params mediaprovider.RatingFavoritePar
var err error
batchSetRating := func(offs int, wg *sync.WaitGroup) {
for i := 0; i < batchSize && offs+i < len(params.TrackIDs); i++ {
if wg != nil {
wg.Add(1)
}
wg.Add(1)
go func(idx int) {
newErr := s.client.SetRating(params.TrackIDs[idx], rating)
if err == nil && newErr != nil {
err = newErr
}
if wg != nil {
wg.Done()
}
wg.Done()
}(offs + i)
}
}
if len(params.TrackIDs) <= 5 {
// one batch only - no need to use wait group
batchSetRating(0, nil)
} else {
go func() {
numBatches := int(math.Ceil(float64(len(params.TrackIDs)) / float64(batchSize)))
for i := 0; i < numBatches; i++ {
var wg sync.WaitGroup
batchSetRating(i*batchSize, &wg)
wg.Wait()
}
}()
numBatches := int(math.Ceil(float64(len(params.TrackIDs)) / float64(batchSize)))
for i := 0; i < numBatches; i++ {
var wg sync.WaitGroup
batchSetRating(i*batchSize, &wg)
wg.Wait()
}
return err
}
@@ -314,6 +262,7 @@ func toTrack(ch *subsonic.Child) *mediaprovider.Track {
Favorite: !ch.Starred.IsZero(),
PlayCount: int(ch.PlayCount),
FilePath: ch.Path,
Size: ch.Size,
BitRate: ch.BitRate,
}
}
@@ -322,18 +271,22 @@ func toAlbum(al *subsonic.AlbumID3) *mediaprovider.Album {
if al == nil {
return nil
}
return &mediaprovider.Album{
ID: al.ID,
CoverArtID: al.CoverArt,
Name: al.Name,
Duration: al.Duration,
ArtistIDs: []string{al.ArtistID},
ArtistNames: []string{al.Artist},
Year: al.Year,
Genres: []string{al.Genre},
TrackCount: al.SongCount,
Favorite: !al.Starred.IsZero(),
}
album := &mediaprovider.Album{}
fillAlbum(al, album)
return album
}
func fillAlbum(subAlbum *subsonic.AlbumID3, album *mediaprovider.Album) {
album.ID = subAlbum.ID
album.CoverArtID = subAlbum.CoverArt
album.Name = subAlbum.Name
album.Duration = subAlbum.Duration
album.ArtistIDs = []string{subAlbum.ArtistID}
album.ArtistNames = []string{subAlbum.Artist}
album.Year = subAlbum.Year
album.TrackCount = subAlbum.SongCount
album.Genres = []string{subAlbum.Genre}
album.Favorite = !subAlbum.Starred.IsZero()
}
func toArtist(ar *subsonic.Artist) *mediaprovider.Artist {
@@ -360,14 +313,21 @@ func toArtistFromID3(ar *subsonic.ArtistID3) *mediaprovider.Artist {
}
func toPlaylist(pl *subsonic.Playlist) *mediaprovider.Playlist {
return &mediaprovider.Playlist{
Name: pl.Name,
ID: pl.ID,
CoverArtID: pl.CoverArt,
Description: pl.Comment,
Owner: pl.Owner,
Public: pl.Public,
TrackCount: pl.SongCount,
Duration: pl.Duration,
if pl == nil {
return nil
}
playlist := &mediaprovider.Playlist{}
fillPlaylist(pl, playlist)
return playlist
}
func fillPlaylist(pl *subsonic.Playlist, playlist *mediaprovider.Playlist) {
playlist.Name = pl.Name
playlist.ID = pl.ID
playlist.CoverArtID = pl.CoverArt
playlist.Description = pl.Comment
playlist.Owner = pl.Owner
playlist.Public = pl.Public
playlist.TrackCount = pl.SongCount
playlist.Duration = pl.Duration
}
@@ -11,7 +11,7 @@ func (s *subsonicMediaProvider) IterateTracks(searchQuery string) mediaprovider.
if searchQuery == "" {
return &allTracksIterator{
s: s,
albumIter: s.IterateAlbums(AlbumSortArtistAZ, "", mediaprovider.AlbumFilter{}),
albumIter: s.IterateAlbums(AlbumSortArtistAZ, mediaprovider.AlbumFilter{}),
}
}
return &searchTracksIterator{