84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
"""Radio Browser: a directory of the community's stations rather than a station.
|
|
|
|
The most-clicked working relays are loaded a page at a time, and the rest of
|
|
the 60,000-station directory is searched on the server as you type. There is no
|
|
now-playing API, so this catalogue offers breadth, not history: pick a station
|
|
and the stream speaks for itself.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import httpx
|
|
|
|
from ... import config
|
|
from ...models import Song, Station
|
|
from ..base import RadioProvider, StationPage
|
|
from . import api, fallback
|
|
from . import hero as hero_art
|
|
|
|
__all__ = ["RadioBrowserProvider"]
|
|
|
|
|
|
class RadioBrowserProvider(RadioProvider):
|
|
id = "radiobrowser"
|
|
name = "Radio Browser"
|
|
homepage = "radio-browser.info"
|
|
brand = "RADIO BROWSER"
|
|
tagline = "community directory · live search"
|
|
station_source = "radio-browser.info (paged + search)"
|
|
history_source = ""
|
|
|
|
hero = hero_art.HERO
|
|
hero_lines = ("RADIO BROWSER", "COMMUNITY DIRECTORY", "KEYLESS · OPEN DATA")
|
|
|
|
# A directory has no show schedule and no Bandcamp worth scraping.
|
|
bandcamp = False
|
|
|
|
# The full directory is much larger than the list fetched at startup; the
|
|
# app asks the API when the filter changes.
|
|
server_search = True
|
|
|
|
# The directory is loaded a page at a time, in click-count order.
|
|
paginated = True
|
|
preserve_order = True
|
|
|
|
@property
|
|
def user_agent(self) -> str:
|
|
return f"{config.USER_AGENT}; +https://www.radio-browser.info"
|
|
|
|
async def fetch_stations(self, client: httpx.AsyncClient) -> list[Station]:
|
|
return await api.fetch_stations(client)
|
|
|
|
async def fetch_station_page(
|
|
self, client: httpx.AsyncClient, offset: int = 0
|
|
) -> StationPage:
|
|
return await api.fetch_station_page(client, offset)
|
|
|
|
async def fetch_stations_by_ids(
|
|
self, client: httpx.AsyncClient, station_ids: list[str]
|
|
) -> list[Station]:
|
|
return await api.fetch_stations_by_ids(client, station_ids)
|
|
|
|
async def search_stations(
|
|
self, client: httpx.AsyncClient, query: str
|
|
) -> list[Station]:
|
|
return await api.search_stations(client, query)
|
|
|
|
def load_cached_stations(self) -> list[Station]:
|
|
return api.load_cached_stations()
|
|
|
|
def fallback_stations(self) -> list[Station]:
|
|
return fallback.fallback_stations()
|
|
|
|
async def fetch_history(
|
|
self, client: httpx.AsyncClient, station_id: str
|
|
) -> list[Song]:
|
|
# Radio Browser publishes no now-playing data at all.
|
|
return []
|
|
|
|
def load_cached_history(self, station_id: str) -> list[Song]:
|
|
return []
|
|
|
|
def fallback_urls(self, station: Station) -> list[str]:
|
|
return [entry["url"] for entry in station.sorted_playlists()]
|