Compare commits

...

2 commits

2 changed files with 27 additions and 6 deletions

View file

@ -1,3 +1,5 @@
from dataclasses import dataclass
from aiocache import Cache
from ..async_tools import run_background_task
@ -6,6 +8,25 @@ from .types import CurrentSongResponse, MpdStateHandler
CACHE_TTL = 60 * 10 # ten minutes
@dataclass(frozen=True)
class HasArt:
data: bytes
@dataclass(frozen=True)
class HasNoArt:
data = None
ArtCacheEntry = HasArt | HasNoArt
def make_cache_entry(art: bytes | None) -> ArtCacheEntry:
if art is None:
return HasNoArt()
return HasArt(art)
def calc_album_key(song: CurrentSongResponse) -> str:
artist = song.get("albumartist", song.get("artist", "Unknown Artist"))
album = song.get("album", "Unknown Album")
@ -18,8 +39,8 @@ def calc_track_key(song: CurrentSongResponse) -> str:
class MpdArtworkCache:
mpd: MpdStateHandler
album_cache: "Cache[bytes | None]"
track_cache: "Cache[bytes | None]"
album_cache: "Cache[ArtCacheEntry]"
track_cache: "Cache[ArtCacheEntry]"
def __init__(self, mpd: MpdStateHandler):
self.mpd = mpd
@ -29,7 +50,7 @@ class MpdArtworkCache:
async def get_cached_artwork(self, song: CurrentSongResponse) -> bytes | None:
art = await self.track_cache.get(calc_track_key(song))
if art:
return art
return art.data
# If we don't have track artwork cached, go find some.
run_background_task(self.cache_artwork(song))
@ -37,12 +58,12 @@ class MpdArtworkCache:
# Even if we don't have cached track art, we can try looking for cached album art.
art = await self.album_cache.get(calc_album_key(song))
if art:
return art
return art.data
return None
async def cache_artwork(self, song: CurrentSongResponse) -> None:
art = await self.mpd.readpicture(song["file"])
art = make_cache_entry(await self.mpd.readpicture(song["file"]))
try:
await self.album_cache.add(calc_album_key(song), art, ttl=CACHE_TTL)
except ValueError:

View file

@ -93,7 +93,7 @@ class MpdStateListener(Player):
async def readpicture(self, file: str) -> bytes | None:
try:
readpic = await self.client.readpicture(file)
return readpic["binary"]
return readpic.get("binary")
except CommandError:
return None