Source code for rekordbox_set_list_manager.models.track

"""Track domain model."""

from uuid import UUID, uuid4

from pydantic import BaseModel, Field

from rekordbox_set_list_manager.models.enums import MatchStatus, RekordboxColor, TrackSource


[docs] class Track(BaseModel): """Represents a single audio track with metadata from one or more sources."""
[docs] id: UUID = Field(default_factory=uuid4)
[docs] title: str
[docs] artist: str
[docs] bpm: float | None = None
[docs] key: str | None = None
[docs] duration: int | None = None # seconds
[docs] isrc: str | None = None
# Source identifiers
[docs] source: TrackSource = TrackSource.MANUAL
[docs] spotify_id: str | None = None
[docs] tidal_id: str | None = None
[docs] rekordbox_id: int | None = None
# Local file reference
[docs] filepath: str | None = None
# Matching metadata
[docs] match_status: MatchStatus = MatchStatus.UNMATCHED
[docs] match_strategy: str | None = None # MatchStrategy value stored as string
[docs] match_score: float | None = None # 0.0-1.0; None means not yet matched
# Optional color override (when not using section default)
[docs] color: RekordboxColor | None = None
@property
[docs] def display_name(self) -> str: """Return 'Artist - Title' as a formatted display string.""" return f"{self.artist} - {self.title}"
@property
[docs] def duration_formatted(self) -> str | None: """Return the duration as a 'M:SS' string, or None if unknown.""" if self.duration is None: return None minutes, seconds = divmod(self.duration, 60) return f"{minutes}:{seconds:02d}"