feat(tilderadio): add the tildeverse community stream as a catalogue
This commit is contained in:
1 parent
58e9202e25
commit
058d336a2c
8 files changed
+883
-4
No files matched your search
+38
-1
@@ -40,6 +40,25 @@ class Song:
|
||||
return f"{self.artist}\x1f{self.title}\x1f{self.album}"
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Broadcast:
|
||||
"""One entry in a catalogue's schedule: a show, a DJ slot, a stream."""
|
||||
|
||||
name: str
|
||||
dj: str = ""
|
||||
start: datetime | None = None
|
||||
end: datetime | None = None
|
||||
#: True for the broadcast that is on air right now.
|
||||
live: bool = False
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
return self.name.strip() or self.dj.strip() or "untitled broadcast"
|
||||
|
||||
def key(self) -> str:
|
||||
return f"{self.name}\x1f{self.start.isoformat() if self.start else ''}"
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Station:
|
||||
id: str
|
||||
@@ -47,6 +66,9 @@ class Station:
|
||||
description: str = ""
|
||||
genre: str = ""
|
||||
dj: str = ""
|
||||
#: Who is presenting right now when that is more than a DJ name —
|
||||
#: ``"auto dj · library rotation"`` for a station between live shows.
|
||||
presenter: str = ""
|
||||
image: str = ""
|
||||
listeners: int = 0
|
||||
last_playing: str = ""
|
||||
@@ -69,6 +91,15 @@ class Station:
|
||||
def genre_label(self) -> str:
|
||||
return self.genre.replace("|", " · ") or "eclectic"
|
||||
|
||||
@property
|
||||
def presenter_label(self) -> str:
|
||||
"""What the ON AIR metadata line says about who is on the desk."""
|
||||
if self.presenter.strip():
|
||||
return self.presenter.strip()
|
||||
if self.dj.strip():
|
||||
return f"dj {self.dj.strip()}"
|
||||
return ""
|
||||
|
||||
def sorted_playlists(self) -> list[dict[str, str]]:
|
||||
return sorted(
|
||||
self.playlists,
|
||||
@@ -87,7 +118,7 @@ class Station:
|
||||
fmt = _FORMAT_LABEL.get(
|
||||
first.get("format", ""), first.get("format") or "stream"
|
||||
)
|
||||
return f"{fmt} · {guess_bitrate(first.get('url', ''))}k"
|
||||
return f"{fmt} · {playlist_bitrate(first)}k"
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
@@ -95,6 +126,12 @@ class Station:
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def playlist_bitrate(playlist: dict[str, str]) -> int:
|
||||
"""The bitrate a catalogue declared, else the best guess from the URL."""
|
||||
declared = to_int(playlist.get("bitrate"))
|
||||
return declared or guess_bitrate(playlist.get("url", ""))
|
||||
|
||||
|
||||
def guess_bitrate(url: str) -> int:
|
||||
match = re.search(
|
||||
r"(256|192|130|128|96|64|48|32)(?=\.pls|\.m3u|-mp3|-aac)", url
|
||||
|
||||
Reference in new issue
Block a user