From 0c7c6ba02060c94302dedb649a8502a8f0da2991 Mon Sep 17 00:00:00 2001 From: Deluan Date: Wed, 28 Dec 2022 13:37:13 -0500 Subject: [PATCH] PreCache Playlists CoverArt --- model/artwork_id.go | 7 +++++++ model/playlist.go | 4 ++++ scanner/playlist_importer.go | 13 ++++++++----- scanner/playlist_importer_test.go | 20 ++++++++++++++------ scanner/tag_scanner.go | 2 +- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/model/artwork_id.go b/model/artwork_id.go index b88a05439..915cc70ab 100644 --- a/model/artwork_id.go +++ b/model/artwork_id.go @@ -73,3 +73,10 @@ func artworkIDFromMediaFile(mf MediaFile) ArtworkID { ID: mf.ID, } } + +func artworkIDFromPlaylist(pls Playlist) ArtworkID { + return ArtworkID{ + Kind: KindPlaylistArtwork, + ID: pls.ID, + } +} diff --git a/model/playlist.go b/model/playlist.go index 06329cf29..9f38aea14 100644 --- a/model/playlist.go +++ b/model/playlist.go @@ -94,6 +94,10 @@ func (pls *Playlist) AddMediaFiles(mfs MediaFiles) { } } +func (pls Playlist) CoverArtID() ArtworkID { + return artworkIDFromPlaylist(pls) +} + type Playlists []Playlist type PlaylistRepository interface { diff --git a/scanner/playlist_importer.go b/scanner/playlist_importer.go index aca2dddb4..ef044b7bc 100644 --- a/scanner/playlist_importer.go +++ b/scanner/playlist_importer.go @@ -9,18 +9,20 @@ import ( "github.com/mattn/go-zglob" "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/core" + "github.com/navidrome/navidrome/core/artwork" "github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/model" ) type playlistImporter struct { - ds model.DataStore - pls core.Playlists - rootFolder string + ds model.DataStore + pls core.Playlists + cacheWarmer artwork.CacheWarmer + rootFolder string } -func newPlaylistImporter(ds model.DataStore, playlists core.Playlists, rootFolder string) *playlistImporter { - return &playlistImporter{ds: ds, pls: playlists, rootFolder: rootFolder} +func newPlaylistImporter(ds model.DataStore, playlists core.Playlists, cacheWarmer artwork.CacheWarmer, rootFolder string) *playlistImporter { + return &playlistImporter{ds: ds, pls: playlists, cacheWarmer: cacheWarmer, rootFolder: rootFolder} } func (s *playlistImporter) processPlaylists(ctx context.Context, dir string) int64 { @@ -46,6 +48,7 @@ func (s *playlistImporter) processPlaylists(ctx context.Context, dir string) int } else { log.Debug("Imported playlist", "name", pls.Name, "lastUpdated", pls.UpdatedAt, "path", pls.Path, "numTracks", pls.SongCount) } + s.cacheWarmer.PreCache(pls.CoverArtID()) count++ } return count diff --git a/scanner/playlist_importer_test.go b/scanner/playlist_importer_test.go index 01cff0cce..1b60f5c0b 100644 --- a/scanner/playlist_importer_test.go +++ b/scanner/playlist_importer_test.go @@ -4,6 +4,7 @@ import ( "context" "github.com/navidrome/navidrome/core" + "github.com/navidrome/navidrome/core/artwork" "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/consts" @@ -17,6 +18,7 @@ var _ = Describe("playlistImporter", func() { var ds model.DataStore var ps *playlistImporter var pls core.Playlists + var cw artwork.CacheWarmer ctx := context.Background() BeforeEach(func() { @@ -25,6 +27,8 @@ var _ = Describe("playlistImporter", func() { MockedPlaylist: &mockedPlaylist{}, } pls = core.NewPlaylists(ds) + + cw = &noopCacheWarmer{} }) Describe("processPlaylists", func() { @@ -33,19 +37,19 @@ var _ = Describe("playlistImporter", func() { conf.Server.PlaylistsPath = consts.DefaultPlaylistsPath }) It("finds and import playlists at the top level", func() { - ps = newPlaylistImporter(ds, pls, "tests/fixtures/playlists/subfolder1") + ps = newPlaylistImporter(ds, pls, cw, "tests/fixtures/playlists/subfolder1") Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists/subfolder1")).To(Equal(int64(1))) }) It("finds and import playlists at any subfolder level", func() { - ps = newPlaylistImporter(ds, pls, "tests") + ps = newPlaylistImporter(ds, pls, cw, "tests") Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists/subfolder1")).To(Equal(int64(1))) }) }) It("ignores playlists not in the PlaylistsPath", func() { conf.Server.PlaylistsPath = "subfolder1" - ps = newPlaylistImporter(ds, pls, "tests/fixtures/playlists") + ps = newPlaylistImporter(ds, pls, cw, "tests/fixtures/playlists") Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists/subfolder1")).To(Equal(int64(1))) Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists/subfolder2")).To(Equal(int64(0))) @@ -53,7 +57,7 @@ var _ = Describe("playlistImporter", func() { It("only imports playlists from the root of MusicFolder if PlaylistsPath is '.'", func() { conf.Server.PlaylistsPath = "." - ps = newPlaylistImporter(ds, pls, "tests/fixtures/playlists") + ps = newPlaylistImporter(ds, pls, cw, "tests/fixtures/playlists") Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists")).To(Equal(int64(3))) Expect(ps.processPlaylists(ctx, "tests/fixtures/playlists/subfolder1")).To(Equal(int64(0))) @@ -77,10 +81,14 @@ type mockedPlaylist struct { model.PlaylistRepository } -func (r *mockedPlaylist) FindByPath(path string) (*model.Playlist, error) { +func (r *mockedPlaylist) FindByPath(_ string) (*model.Playlist, error) { return nil, model.ErrNotFound } -func (r *mockedPlaylist) Put(pls *model.Playlist) error { +func (r *mockedPlaylist) Put(_ *model.Playlist) error { return nil } + +type noopCacheWarmer struct{} + +func (a *noopCacheWarmer) PreCache(_ model.ArtworkID) {} diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go index 9e17f3ea4..0726ae5c6 100644 --- a/scanner/tag_scanner.go +++ b/scanner/tag_scanner.go @@ -34,7 +34,7 @@ type TagScanner struct { func NewTagScanner(rootFolder string, ds model.DataStore, playlists core.Playlists, cacheWarmer artwork.CacheWarmer) FolderScanner { s := &TagScanner{ rootFolder: rootFolder, - plsSync: newPlaylistImporter(ds, playlists, rootFolder), + plsSync: newPlaylistImporter(ds, playlists, cacheWarmer, rootFolder), ds: ds, cacheWarmer: cacheWarmer, }