from dataclasses import dataclass from typing import Iterable, Tuple from serato_doctor.models.crate import Crate from serato_doctor.models.reference import ReferenceResult, TrackReference from serato_doctor.models.track import DiskTrack @dataclass(frozen=True) class Library: """The read-only view of crate references and audio found on disk.""" references: Tuple[TrackReference, ...] tracks: Tuple[DiskTrack, ...] crates: Tuple[Crate, ...] = () @classmethod def build( cls, references: Iterable[TrackReference], tracks: Iterable[DiskTrack], ) -> "Library": return cls(tuple(references), tuple(tracks)) @classmethod def from_crates( cls, crates: Iterable[Crate], tracks: Iterable[DiskTrack] ) -> "Library": crate_tuple = tuple(crates) references = tuple( reference for crate in crate_tuple for reference in crate.references ) return cls(references, tuple(tracks), crate_tuple) def reconcile_by_filename(self) -> Tuple[ReferenceResult, ...]: disk_names = {track.filename for track in self.tracks} return tuple( ReferenceResult( reference=reference, exists_by_filename=reference.filename in disk_names, ) for reference in self.references )