"""Shared data model. A ``Track`` is the uniform object every provider emits: a *resolved* reference (which backend can download it, and where) plus display metadata. Fetchers turn it into a local file; the queue and the state database use ``key`` for de-duplication and anti-repeat. """ from dataclasses import dataclass @dataclass(frozen=True) class Track: backend: str # which fetcher handles it: "subsonic" | "ytdlp" locator: str # backend-specific: Subsonic song id, or a media URL artist: str title: str origin: str # provider that produced it, e.g. "navidrome" mbid: str | None = None # filled by the Canonicalizer (milestone 5) source_ext: str | None = None # filename hint, e.g. "mp3", "flac" source_url: str | None = None # container URL a track was picked from @property def key(self) -> str: """Stable identity for de-duplication and anti-repeat. Until the Canonicalizer (milestone 5) fills ``mbid``, we key on the backend locator, which is unique within a source. """ if self.mbid: return f"mbid:{self.mbid}" return f"{self.backend}:{self.locator}" def __str__(self) -> str: return f"{self.artist} — {self.title} [{self.origin}]"