f2f4c7a908
We now get the playable station URL directly from the Radiobrowser API. This fixes the issue with playlists in the 'url' attribute. Does not work if played station tracking would be disabled. It _could_ work but we would need to create an additional API request for every single listed station, even the ones not enqueued for playing. This would then be way slower and put extra strain on the Radiobrowser API.
154 lines
6 KiB
Python
154 lines
6 KiB
Python
import requests
|
|
import logging
|
|
|
|
from ycast import __version__
|
|
import ycast.vtuner as vtuner
|
|
import ycast.generic as generic
|
|
|
|
MINIMUM_COUNT_GENRE = 5
|
|
MINIMUM_COUNT_COUNTRY = 5
|
|
MINIMUM_COUNT_LANGUAGE = 5
|
|
DEFAULT_STATION_LIMIT = 200
|
|
SHOW_BROKEN_STATIONS = False
|
|
ID_PREFIX = "RB"
|
|
|
|
|
|
def get_json_attr(json, attr):
|
|
try:
|
|
return json[attr]
|
|
except:
|
|
return None
|
|
|
|
|
|
class Station:
|
|
def __init__(self, station_json):
|
|
self.id = generic.generate_stationid_with_prefix(get_json_attr(station_json, 'id'), ID_PREFIX)
|
|
self.name = get_json_attr(station_json, 'name')
|
|
self.url = get_json_attr(station_json, 'url')
|
|
self.icon = get_json_attr(station_json, 'favicon')
|
|
self.tags = get_json_attr(station_json, 'tags').split(',')
|
|
self.country = get_json_attr(station_json, 'country')
|
|
self.language = get_json_attr(station_json, 'language')
|
|
self.votes = get_json_attr(station_json, 'votes')
|
|
self.codec = get_json_attr(station_json, 'codec')
|
|
self.bitrate = get_json_attr(station_json, 'bitrate')
|
|
|
|
def to_vtuner(self):
|
|
return vtuner.Station(self.id, self.name, ', '.join(self.tags), self.url, self.icon,
|
|
self.tags[0], self.country, self.codec, self.bitrate, None)
|
|
|
|
def get_playable_url(self):
|
|
try:
|
|
playable_url_json = request('url/' + generic.get_stationid_without_prefix(self.id))[0]
|
|
self.url = playable_url_json['url']
|
|
except (IndexError, KeyError):
|
|
logging.error("Could not retrieve first playlist item for station with id '%s'", self.id)
|
|
|
|
|
|
def request(url):
|
|
logging.debug("Radiobrowser API request: %s", url)
|
|
headers = {'content-type': 'application/json', 'User-Agent': generic.USER_AGENT + '/' + __version__}
|
|
try:
|
|
response = requests.get('http://www.radio-browser.info/webservice/json/' + url, headers=headers)
|
|
except requests.exceptions.ConnectionError as err:
|
|
logging.error("Connection to Radiobrowser API failed (%s)", err)
|
|
return {}
|
|
if response.status_code != 200:
|
|
logging.error("Could not fetch data from Radiobrowser API (HTML status %s)", response.status_code)
|
|
return {}
|
|
return response.json()
|
|
|
|
|
|
def get_station_by_id(uid):
|
|
station_json = request('stations/byid/' + str(uid))
|
|
if station_json and len(station_json):
|
|
return Station(station_json[0])
|
|
else:
|
|
return None
|
|
|
|
|
|
def search(name, limit=DEFAULT_STATION_LIMIT):
|
|
stations = []
|
|
stations_json = request('stations/search?order=name&reverse=false&limit=' + str(limit) + '&name=' + str(name))
|
|
for station_json in stations_json:
|
|
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
|
|
stations.append(Station(station_json))
|
|
return stations
|
|
|
|
|
|
def get_country_directories():
|
|
country_directories = []
|
|
apicall = 'countries'
|
|
if not SHOW_BROKEN_STATIONS:
|
|
apicall += '?hidebroken=true'
|
|
countries_raw = request(apicall)
|
|
for country_raw in countries_raw:
|
|
if get_json_attr(country_raw, 'name') and get_json_attr(country_raw, 'stationcount') and \
|
|
int(get_json_attr(country_raw, 'stationcount')) > MINIMUM_COUNT_COUNTRY:
|
|
country_directories.append(generic.Directory(get_json_attr(country_raw, 'name'),
|
|
get_json_attr(country_raw, 'stationcount')))
|
|
return country_directories
|
|
|
|
|
|
def get_language_directories():
|
|
language_directories = []
|
|
apicall = 'languages'
|
|
if not SHOW_BROKEN_STATIONS:
|
|
apicall += '?hidebroken=true'
|
|
languages_raw = request(apicall)
|
|
for language_raw in languages_raw:
|
|
if get_json_attr(language_raw, 'name') and get_json_attr(language_raw, 'stationcount') and \
|
|
int(get_json_attr(language_raw, 'stationcount')) > MINIMUM_COUNT_LANGUAGE:
|
|
language_directories.append(generic.Directory(get_json_attr(language_raw, 'name'),
|
|
get_json_attr(language_raw, 'stationcount')))
|
|
return language_directories
|
|
|
|
|
|
def get_genre_directories():
|
|
genre_directories = []
|
|
apicall = 'tags'
|
|
if not SHOW_BROKEN_STATIONS:
|
|
apicall += '?hidebroken=true'
|
|
genres_raw = request(apicall)
|
|
for genre_raw in genres_raw:
|
|
if get_json_attr(genre_raw, 'name') and get_json_attr(genre_raw, 'stationcount') and \
|
|
int(get_json_attr(genre_raw, 'stationcount')) > MINIMUM_COUNT_GENRE:
|
|
genre_directories.append(generic.Directory(get_json_attr(genre_raw, 'name'),
|
|
get_json_attr(genre_raw, 'stationcount')))
|
|
return genre_directories
|
|
|
|
|
|
def get_stations_by_country(country):
|
|
stations = []
|
|
stations_json = request('stations/search?order=name&reverse=false&countryExact=true&country=' + str(country))
|
|
for station_json in stations_json:
|
|
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
|
|
stations.append(Station(station_json))
|
|
return stations
|
|
|
|
|
|
def get_stations_by_language(language):
|
|
stations = []
|
|
stations_json = request('stations/search?order=name&reverse=false&languageExact=true&language=' + str(language))
|
|
for station_json in stations_json:
|
|
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
|
|
stations.append(Station(station_json))
|
|
return stations
|
|
|
|
|
|
def get_stations_by_genre(genre):
|
|
stations = []
|
|
stations_json = request('stations/search?order=name&reverse=false&tagExact=true&tag=' + str(genre))
|
|
for station_json in stations_json:
|
|
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
|
|
stations.append(Station(station_json))
|
|
return stations
|
|
|
|
|
|
def get_stations_by_votes(limit=DEFAULT_STATION_LIMIT):
|
|
stations = []
|
|
stations_json = request('stations?order=votes&reverse=true&limit=' + str(limit))
|
|
for station_json in stations_json:
|
|
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
|
|
stations.append(Station(station_json))
|
|
return stations
|