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:
parent
ed6baa692e
commit
16387a3f50
4
ycast/generic.py
Normal file
4
ycast/generic.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
class Directory:
|
||||||
|
def __init__(self, name, item_count):
|
||||||
|
self.name = name
|
||||||
|
self.item_count = item_count
|
|
@ -3,6 +3,7 @@ import logging
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import ycast.vtuner as vtuner
|
import ycast.vtuner as vtuner
|
||||||
|
import ycast.generic as generic
|
||||||
|
|
||||||
ID_PREFIX = "MY_"
|
ID_PREFIX = "MY_"
|
||||||
|
|
||||||
|
@ -24,13 +25,13 @@ def set_config(config):
|
||||||
global config_file
|
global config_file
|
||||||
if config:
|
if config:
|
||||||
config_file = config
|
config_file = config
|
||||||
if get_stations():
|
if get_stations_yaml():
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_stations():
|
def get_stations_yaml():
|
||||||
try:
|
try:
|
||||||
with open(config_file, 'r') as f:
|
with open(config_file, 'r') as f:
|
||||||
my_stations = yaml.safe_load(f)
|
my_stations = yaml.safe_load(f)
|
||||||
|
@ -43,17 +44,17 @@ def get_stations():
|
||||||
return my_stations
|
return my_stations
|
||||||
|
|
||||||
|
|
||||||
def get_categories():
|
def get_category_directories():
|
||||||
my_stations_yaml = get_stations()
|
my_stations_yaml = get_stations_yaml()
|
||||||
categories = []
|
categories = []
|
||||||
if my_stations_yaml:
|
if my_stations_yaml:
|
||||||
for category in 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
|
return categories
|
||||||
|
|
||||||
|
|
||||||
def get_stations_by_category(category):
|
def get_stations_by_category(category):
|
||||||
my_stations_yaml = get_stations()
|
my_stations_yaml = get_stations_yaml()
|
||||||
stations = []
|
stations = []
|
||||||
if my_stations_yaml and category in my_stations_yaml:
|
if my_stations_yaml and category in my_stations_yaml:
|
||||||
for station_name in my_stations_yaml[category]:
|
for station_name in my_stations_yaml[category]:
|
||||||
|
|
|
@ -2,11 +2,12 @@ import requests
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import ycast.vtuner as vtuner
|
import ycast.vtuner as vtuner
|
||||||
|
import ycast.generic as generic
|
||||||
|
|
||||||
MINIMUM_COUNT_GENRE = 5
|
MINIMUM_COUNT_GENRE = 5
|
||||||
MINIMUM_COUNT_COUNTRY = 5
|
MINIMUM_COUNT_COUNTRY = 5
|
||||||
MINIMUM_BITRATE = 64
|
|
||||||
DEFAULT_STATION_LIMIT = 200
|
DEFAULT_STATION_LIMIT = 200
|
||||||
|
SHOW_BROKEN_STATIONS = False
|
||||||
ID_PREFIX = "RB_"
|
ID_PREFIX = "RB_"
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ class Station:
|
||||||
|
|
||||||
|
|
||||||
def request(url):
|
def request(url):
|
||||||
|
logging.debug("Radiobrowser API request: %s", url)
|
||||||
headers = {'content-type': 'application/json', 'User-Agent': 'YCast'}
|
headers = {'content-type': 'application/json', 'User-Agent': 'YCast'}
|
||||||
response = requests.get('http://www.radio-browser.info/webservice/json/' + url, headers=headers)
|
response = requests.get('http://www.radio-browser.info/webservice/json/' + url, headers=headers)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
|
@ -51,48 +53,56 @@ def get_station_by_id(uid):
|
||||||
|
|
||||||
def search(name, limit=DEFAULT_STATION_LIMIT):
|
def search(name, limit=DEFAULT_STATION_LIMIT):
|
||||||
stations = []
|
stations = []
|
||||||
stations_json = request('stations/search?order=name&reverse=false&bitrateMin=' +
|
stations_json = request('stations/search?order=name&reverse=false&limit=' + str(limit) + '&name=' + str(name))
|
||||||
str(MINIMUM_BITRATE) + '&limit=' + str(limit) + '&name=' + str(name))
|
|
||||||
for station_json in stations_json:
|
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
|
return stations
|
||||||
|
|
||||||
|
|
||||||
def get_countries():
|
def get_country_directories():
|
||||||
countries = []
|
country_directories = []
|
||||||
countries_raw = request('countries')
|
apicall = 'countries'
|
||||||
|
if not SHOW_BROKEN_STATIONS:
|
||||||
|
apicall += '?hidebroken=true'
|
||||||
|
countries_raw = request(apicall)
|
||||||
for country_raw in countries_raw:
|
for country_raw in countries_raw:
|
||||||
if get_json_attr(country_raw, 'name') and get_json_attr(country_raw, 'stationcount') and \
|
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:
|
int(get_json_attr(country_raw, 'stationcount')) > MINIMUM_COUNT_COUNTRY:
|
||||||
countries.append(get_json_attr(country_raw, 'name'))
|
country_directories.append(generic.Directory(get_json_attr(country_raw, 'name'),
|
||||||
return countries
|
get_json_attr(country_raw, 'stationcount')))
|
||||||
|
return country_directories
|
||||||
|
|
||||||
|
|
||||||
def get_genres():
|
def get_genre_directories():
|
||||||
genres = []
|
genre_directories = []
|
||||||
genres_raw = request('tags?hidebroken=true')
|
apicall = 'tags'
|
||||||
|
if not SHOW_BROKEN_STATIONS:
|
||||||
|
apicall += '?hidebroken=true'
|
||||||
|
genres_raw = request(apicall)
|
||||||
for genre_raw in genres_raw:
|
for genre_raw in genres_raw:
|
||||||
if get_json_attr(genre_raw, 'name') and get_json_attr(genre_raw, 'stationcount') and \
|
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:
|
int(get_json_attr(genre_raw, 'stationcount')) > MINIMUM_COUNT_GENRE:
|
||||||
genres.append(get_json_attr(genre_raw, 'name'))
|
genre_directories.append(generic.Directory(get_json_attr(genre_raw, 'name'),
|
||||||
return genres
|
get_json_attr(genre_raw, 'stationcount')))
|
||||||
|
return genre_directories
|
||||||
|
|
||||||
|
|
||||||
def get_stations_by_country(country):
|
def get_stations_by_country(country):
|
||||||
stations = []
|
stations = []
|
||||||
stations_json = request('stations/search?order=name&reverse=false&bitrateMin=' +
|
stations_json = request('stations/search?order=name&reverse=false&countryExact=true&country=' + str(country))
|
||||||
str(MINIMUM_BITRATE) + '&countryExact=true&country=' + str(country))
|
|
||||||
for station_json in stations_json:
|
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
|
return stations
|
||||||
|
|
||||||
|
|
||||||
def get_stations_by_genre(genre):
|
def get_stations_by_genre(genre):
|
||||||
stations = []
|
stations = []
|
||||||
stations_json = request('stations/search?order=name&reverse=false&bitrateMin=' +
|
stations_json = request('stations/search?order=name&reverse=false&tagExact=true&tag=' + str(genre))
|
||||||
str(MINIMUM_BITRATE) + '&tagExact=true&tag=' + str(genre))
|
|
||||||
for station_json in stations_json:
|
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
|
return stations
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,5 +110,6 @@ def get_stations_by_votes(limit=DEFAULT_STATION_LIMIT):
|
||||||
stations = []
|
stations = []
|
||||||
stations_json = request('stations?order=votes&reverse=true&limit=' + str(limit))
|
stations_json = request('stations?order=votes&reverse=true&limit=' + str(limit))
|
||||||
for station_json in stations_json:
|
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
|
return stations
|
||||||
|
|
|
@ -32,20 +32,14 @@ def check_my_stations_feature(config):
|
||||||
my_stations_enabled = my_stations.set_config(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()
|
page = vtuner.Page()
|
||||||
if len(directories) == 0:
|
if len(directories) == 0:
|
||||||
page.add(vtuner.Display("No entries found."))
|
page.add(vtuner.Display("No entries found."))
|
||||||
return page
|
return page
|
||||||
for directory in get_paged_elements(directories, requestargs):
|
for directory in get_paged_elements(directories, requestargs):
|
||||||
vtuner_directory = vtuner.Directory(directory, url_for(subdir, _external=True, directory=directory))
|
vtuner_directory = vtuner.Directory(directory.name, url_for(subdir, _external=True, directory=directory.name),
|
||||||
if item_count_function:
|
directory.item_count)
|
||||||
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
|
|
||||||
page.add(vtuner_directory)
|
page.add(vtuner_directory)
|
||||||
page.set_count(len(directories))
|
page.set_count(len(directories))
|
||||||
return page
|
return page
|
||||||
|
@ -96,7 +90,7 @@ def landing(path):
|
||||||
page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True), 4))
|
page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True), 4))
|
||||||
if my_stations_enabled:
|
if my_stations_enabled:
|
||||||
page.add(vtuner.Directory('My Stations', url_for('my_stations_landing', _external=True),
|
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:
|
else:
|
||||||
page.add(vtuner.Display("'My Stations' feature not configured."))
|
page.add(vtuner.Display("'My Stations' feature not configured."))
|
||||||
return page.to_string()
|
return page.to_string()
|
||||||
|
@ -106,9 +100,8 @@ def landing(path):
|
||||||
def my_stations_landing():
|
def my_stations_landing():
|
||||||
page = vtuner.Page()
|
page = vtuner.Page()
|
||||||
page.add(vtuner.Previous(url_for("landing", _external=True)))
|
page.add(vtuner.Previous(url_for("landing", _external=True)))
|
||||||
directories = my_stations.get_categories()
|
directories = my_stations.get_category_directories()
|
||||||
return get_directories_page('my_stations_category', directories, request.args,
|
return get_directories_page('my_stations_category', directories, request.args).to_string()
|
||||||
my_stations.get_stations_by_category).to_string()
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/<directory>')
|
||||||
|
@ -122,9 +115,9 @@ def radiobrowser_landing():
|
||||||
page = vtuner.Page()
|
page = vtuner.Page()
|
||||||
page.add(vtuner.Previous(url_for('landing', _external=True)))
|
page.add(vtuner.Previous(url_for('landing', _external=True)))
|
||||||
page.add(vtuner.Directory('Genres', url_for('radiobrowser_genres', _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),
|
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),
|
page.add(vtuner.Directory('Most Popular', url_for('radiobrowser_popular', _external=True),
|
||||||
len(radiobrowser.get_stations_by_votes())))
|
len(radiobrowser.get_stations_by_votes())))
|
||||||
page.add(vtuner.Search('Search', url_for('radiobrowser_search', _external=True, path='')))
|
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 + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/')
|
||||||
def radiobrowser_countries():
|
def radiobrowser_countries():
|
||||||
directories = radiobrowser.get_countries()
|
directories = radiobrowser.get_country_directories()
|
||||||
return get_directories_page('radiobrowser_country_stations', directories, request.args,
|
return get_directories_page('radiobrowser_country_stations', directories, request.args).to_string()
|
||||||
radiobrowser.get_stations_by_country).to_string()
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/<directory>')
|
@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 + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/')
|
||||||
def radiobrowser_genres():
|
def radiobrowser_genres():
|
||||||
directories = radiobrowser.get_genres()
|
directories = radiobrowser.get_genre_directories()
|
||||||
return get_directories_page('radiobrowser_genre_stations', directories, request.args,
|
return get_directories_page('radiobrowser_genre_stations', directories, request.args).to_string()
|
||||||
radiobrowser.get_stations_by_genre).to_string()
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/<directory>')
|
||||||
|
|
Loading…
Reference in a new issue