Rework directory handling

This greatly improves loading times and takes some load off the APIs.

 * Add generic directory class to also hold item count
 * Radiobrowser: Get station count directly from API
 * Optionally show broken stations and their count
 * Remove minimum station bitrate to not filter away some listings
 * Improve code wording
 * Log API requests
This commit is contained in:
milaq 2019-08-18 13:50:38 +02:00
parent ed6baa692e
commit 16387a3f50
4 changed files with 55 additions and 48 deletions

4
ycast/generic.py Normal file
View file

@ -0,0 +1,4 @@
class Directory:
def __init__(self, name, item_count):
self.name = name
self.item_count = item_count

View file

@ -3,6 +3,7 @@ import logging
import yaml
import ycast.vtuner as vtuner
import ycast.generic as generic
ID_PREFIX = "MY_"
@ -24,13 +25,13 @@ def set_config(config):
global config_file
if config:
config_file = config
if get_stations():
if get_stations_yaml():
return True
else:
return False
def get_stations():
def get_stations_yaml():
try:
with open(config_file, 'r') as f:
my_stations = yaml.safe_load(f)
@ -43,17 +44,17 @@ def get_stations():
return my_stations
def get_categories():
my_stations_yaml = get_stations()
def get_category_directories():
my_stations_yaml = get_stations_yaml()
categories = []
if my_stations_yaml:
for category in my_stations_yaml:
categories.append(category)
categories.append(generic.Directory(category, len(get_stations_by_category(category))))
return categories
def get_stations_by_category(category):
my_stations_yaml = get_stations()
my_stations_yaml = get_stations_yaml()
stations = []
if my_stations_yaml and category in my_stations_yaml:
for station_name in my_stations_yaml[category]:

View file

@ -2,11 +2,12 @@ import requests
import logging
import ycast.vtuner as vtuner
import ycast.generic as generic
MINIMUM_COUNT_GENRE = 5
MINIMUM_COUNT_COUNTRY = 5
MINIMUM_BITRATE = 64
DEFAULT_STATION_LIMIT = 200
SHOW_BROKEN_STATIONS = False
ID_PREFIX = "RB_"
@ -36,6 +37,7 @@ class Station:
def request(url):
logging.debug("Radiobrowser API request: %s", url)
headers = {'content-type': 'application/json', 'User-Agent': 'YCast'}
response = requests.get('http://www.radio-browser.info/webservice/json/' + url, headers=headers)
if response.status_code != 200:
@ -51,48 +53,56 @@ def get_station_by_id(uid):
def search(name, limit=DEFAULT_STATION_LIMIT):
stations = []
stations_json = request('stations/search?order=name&reverse=false&bitrateMin=' +
str(MINIMUM_BITRATE) + '&limit=' + str(limit) + '&name=' + str(name))
stations_json = request('stations/search?order=name&reverse=false&limit=' + str(limit) + '&name=' + str(name))
for station_json in stations_json:
stations.append(Station(station_json))
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
stations.append(Station(station_json))
return stations
def get_countries():
countries = []
countries_raw = request('countries')
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:
countries.append(get_json_attr(country_raw, 'name'))
return countries
country_directories.append(generic.Directory(get_json_attr(country_raw, 'name'),
get_json_attr(country_raw, 'stationcount')))
return country_directories
def get_genres():
genres = []
genres_raw = request('tags?hidebroken=true')
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:
genres.append(get_json_attr(genre_raw, 'name'))
return genres
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&bitrateMin=' +
str(MINIMUM_BITRATE) + '&countryExact=true&country=' + str(country))
stations_json = request('stations/search?order=name&reverse=false&countryExact=true&country=' + str(country))
for station_json in stations_json:
stations.append(Station(station_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&bitrateMin=' +
str(MINIMUM_BITRATE) + '&tagExact=true&tag=' + str(genre))
stations_json = request('stations/search?order=name&reverse=false&tagExact=true&tag=' + str(genre))
for station_json in stations_json:
stations.append(Station(station_json))
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
stations.append(Station(station_json))
return stations
@ -100,5 +110,6 @@ 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:
stations.append(Station(station_json))
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
stations.append(Station(station_json))
return stations

View file

@ -32,20 +32,14 @@ def check_my_stations_feature(config):
my_stations_enabled = my_stations.set_config(config)
def get_directories_page(subdir, directories, requestargs, item_count_function=None):
def get_directories_page(subdir, directories, requestargs):
page = vtuner.Page()
if len(directories) == 0:
page.add(vtuner.Display("No entries found."))
return page
for directory in get_paged_elements(directories, requestargs):
vtuner_directory = vtuner.Directory(directory, url_for(subdir, _external=True, directory=directory))
if item_count_function:
try:
item_count = len(item_count_function(directory))
vtuner_directory.set_item_count(item_count)
except TypeError:
logging.error("Could not get item count of directory '%s'", directory)
pass
vtuner_directory = vtuner.Directory(directory.name, url_for(subdir, _external=True, directory=directory.name),
directory.item_count)
page.add(vtuner_directory)
page.set_count(len(directories))
return page
@ -96,7 +90,7 @@ def landing(path):
page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True), 4))
if my_stations_enabled:
page.add(vtuner.Directory('My Stations', url_for('my_stations_landing', _external=True),
len(my_stations.get_categories())))
len(my_stations.get_category_directories())))
else:
page.add(vtuner.Display("'My Stations' feature not configured."))
return page.to_string()
@ -106,9 +100,8 @@ def landing(path):
def my_stations_landing():
page = vtuner.Page()
page.add(vtuner.Previous(url_for("landing", _external=True)))
directories = my_stations.get_categories()
return get_directories_page('my_stations_category', directories, request.args,
my_stations.get_stations_by_category).to_string()
directories = my_stations.get_category_directories()
return get_directories_page('my_stations_category', directories, request.args).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/<directory>')
@ -122,9 +115,9 @@ def radiobrowser_landing():
page = vtuner.Page()
page.add(vtuner.Previous(url_for('landing', _external=True)))
page.add(vtuner.Directory('Genres', url_for('radiobrowser_genres', _external=True),
len(radiobrowser.get_genres())))
len(radiobrowser.get_genre_directories())))
page.add(vtuner.Directory('Countries', url_for('radiobrowser_countries', _external=True),
len(radiobrowser.get_countries())))
len(radiobrowser.get_country_directories())))
page.add(vtuner.Directory('Most Popular', url_for('radiobrowser_popular', _external=True),
len(radiobrowser.get_stations_by_votes())))
page.add(vtuner.Search('Search', url_for('radiobrowser_search', _external=True, path='')))
@ -133,9 +126,8 @@ def radiobrowser_landing():
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/')
def radiobrowser_countries():
directories = radiobrowser.get_countries()
return get_directories_page('radiobrowser_country_stations', directories, request.args,
radiobrowser.get_stations_by_country).to_string()
directories = radiobrowser.get_country_directories()
return get_directories_page('radiobrowser_country_stations', directories, request.args).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/<directory>')
@ -146,9 +138,8 @@ def radiobrowser_country_stations(directory):
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/')
def radiobrowser_genres():
directories = radiobrowser.get_genres()
return get_directories_page('radiobrowser_genre_stations', directories, request.args,
radiobrowser.get_stations_by_genre).to_string()
directories = radiobrowser.get_genre_directories()
return get_directories_page('radiobrowser_genre_stations', directories, request.args).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/<directory>')