Files
musicseerr/backend/services/weekly_exploration_service.py
T
2026-04-03 15:53:00 +01:00

95 lines
3.4 KiB
Python

from __future__ import annotations
import asyncio
import logging
from api.v1.schemas.weekly_exploration import (
WeeklyExplorationSection,
WeeklyExplorationTrack,
)
from infrastructure.cover_urls import release_cover_url, release_group_cover_url
from repositories.protocols import (
ListenBrainzRepositoryProtocol,
MusicBrainzRepositoryProtocol,
)
logger = logging.getLogger(__name__)
class WeeklyExplorationService:
def __init__(
self,
listenbrainz_repo: ListenBrainzRepositoryProtocol,
musicbrainz_repo: MusicBrainzRepositoryProtocol,
) -> None:
self._lb_repo = listenbrainz_repo
self._mb_repo = musicbrainz_repo
async def build_section(self, username: str) -> WeeklyExplorationSection | None:
try:
playlists = await self._lb_repo.get_recommendation_playlists(username)
if not playlists:
return None
newest = next(
(p for p in playlists if p.get("source_patch") == "weekly-exploration"),
playlists[0],
)
playlist_id = newest.get("playlist_id", "")
if not playlist_id:
return None
playlist = await self._lb_repo.get_playlist_tracks(playlist_id)
if not playlist or not playlist.tracks:
return None
unique_release_ids = list({
track.caa_release_mbid for track in playlist.tracks if track.caa_release_mbid
})
rg_results = await asyncio.gather(
*(
self._mb_repo.get_release_group_id_from_release(release_id)
for release_id in unique_release_ids
),
return_exceptions=True,
)
release_to_rg = {
release_id: release_group_id
for release_id, release_group_id in zip(unique_release_ids, rg_results)
if isinstance(release_group_id, str) and release_group_id
}
tracks: list[WeeklyExplorationTrack] = []
for track in playlist.tracks:
artist_mbid = track.artist_mbids[0] if track.artist_mbids else None
release_group_mbid = (
release_to_rg.get(track.caa_release_mbid, "") if track.caa_release_mbid else None
)
cover_url: str | None = None
if release_group_mbid:
cover_url = release_group_cover_url(release_group_mbid, size=250)
elif track.caa_release_mbid:
cover_url = release_cover_url(track.caa_release_mbid, size=250)
tracks.append(WeeklyExplorationTrack(
title=track.title,
artist_name=track.creator,
album_name=track.album,
recording_mbid=track.recording_mbid,
artist_mbid=artist_mbid,
release_group_mbid=release_group_mbid or None,
cover_url=cover_url,
duration_ms=track.duration_ms,
))
return WeeklyExplorationSection(
title=playlist.title,
playlist_date=playlist.date,
tracks=tracks,
source_url=newest.get("identifier", ""),
)
except Exception as exc: # noqa: BLE001
logger.warning("Failed to build weekly exploration: %s", exc)
return None