Files
musicmouse/python-backend/musicmouse/media.py
Martin Bauer a737ccf108 Bring the docs in line with the code
- python-backend/README: track analysis is implemented (2e0e6ad); the cache layout,
  the module table (lirc, screen, timers, podcasts, tippen) and the route table
  (track analysis, HA proxy, typing game) were missing pieces.
- docs/REPO_OVERVIEW: Mein Zimmer and the clock are implemented; Home Assistant is
  also reached over HTTP through the room page's proxy, not MQTT only; the IR remote,
  scripts/, the optional config sections and figure kind were not mentioned.
- web/README: the key table was the mockup's (Ctrl transport keys, TAB over 'all');
  ?pi=1 is now a preset with per-browser overrides, not a read-once flag; the room
  page and the typing game exist; eslint is part of the checks.
- Docstrings that described earlier designs: HaConfig (written as browser-direct in
  the same commit that built the proxy, a8ed350), services/__init__, events,
  playback, media, colors, tippen progress and AppHeader, lowPower.ts, and the
  'Hoerbuecher' spelling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 10:51:27 +02:00

47 lines
1.1 KiB
Python

"""Playlist model.
What the player plays: a name and the files, in order. The browse API serves
:class:`~musicmouse.library.models.Album` instead, which carries the tag metadata;
``Album.to_playlist()`` builds one of these from it.
"""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
__all__ = ["Playlist", "Track"]
@dataclass(frozen=True, slots=True)
class Track:
path: Path
@property
def title(self) -> str:
return self.path.stem
def __repr__(self) -> str:
return f"Track({self.title!r})"
@dataclass(frozen=True, slots=True)
class Playlist:
name: str
tracks: tuple[Track, ...]
#: Set when this playlist came from a library album. It is how a front-end answers
#: "what is playing?" without keeping its own copy of that state.
album_id: str | None = None
def __len__(self) -> int:
return len(self.tracks)
def __bool__(self) -> bool:
return bool(self.tracks)
def __getitem__(self, index: int) -> Track:
return self.tracks[index]
def __repr__(self) -> str:
return f"Playlist({self.name!r}, {len(self.tracks)} tracks)"