From 4accb0bef18a7d2f6bbf312d43898213f4f2a58e Mon Sep 17 00:00:00 2001 From: milaq Date: Sat, 17 Aug 2019 23:52:55 +0200 Subject: [PATCH] Paging: Improve sanity checks and add in 'DirCount' support Some AVRs want to know the folder item count before entering it. --- ycast/server.py | 45 +++++++++++++++++++++++++++++++-------------- ycast/vtuner.py | 7 ++++++- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/ycast/server.py b/ycast/server.py index 2d02515..b016464 100644 --- a/ycast/server.py +++ b/ycast/server.py @@ -32,13 +32,21 @@ def check_my_stations_feature(config): my_stations_enabled = my_stations.set_config(config) -def get_directories_page(subdir, directories, requestargs): +def get_directories_page(subdir, directories, requestargs, item_count_function=None): page = vtuner.Page() if len(directories) == 0: page.add(vtuner.Display("No entries found.")) return page for directory in get_paged_elements(directories, requestargs): - page.add(vtuner.Directory(directory, url_for(subdir, _external=True, directory=directory))) + 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 + page.add(vtuner_directory) page.set_count(len(directories)) return page @@ -61,18 +69,20 @@ def get_paged_elements(items, requestargs): offset = int(requestargs.get('start')) - 1 else: offset = 0 + if offset > len(items): + logging.warning("Paging offset larger than item count") + return [] if requestargs.get('enditems'): limit = int(requestargs.get('enditems')) elif requestargs.get('start') and requestargs.get('howmany'): limit = int(requestargs.get('start')) - 1 + int(requestargs.get('howmany')) else: limit = len(items) - if offset > len(items): - offset = len(items) + if limit < offset: + logging.warning("Paging limit smaller than offset") + return [] if limit > len(items): limit = len(items) - if limit < offset: - limit = offset return items[offset:limit] @@ -83,9 +93,10 @@ def landing(path): if request.args.get('token') == '0': return vtuner.get_init_token() page = vtuner.Page() - page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True))) + 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))) + page.add(vtuner.Directory('My Stations', url_for('my_stations_landing', _external=True), + len(my_stations.get_categories()))) else: page.add(vtuner.Display("'My Stations' feature not configured.")) return page.to_string() @@ -96,7 +107,8 @@ 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).to_string() + return get_directories_page('my_stations_category', directories, request.args, + my_stations.get_stations_by_category).to_string() @app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/') @@ -109,9 +121,12 @@ def my_stations_category(directory): 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))) - page.add(vtuner.Directory('Countries', url_for('radiobrowser_countries', _external=True))) - page.add(vtuner.Directory('Most Popular', url_for('radiobrowser_popular', _external=True))) + page.add(vtuner.Directory('Genres', url_for('radiobrowser_genres', _external=True), + len(radiobrowser.get_genres()))) + page.add(vtuner.Directory('Countries', url_for('radiobrowser_countries', _external=True), + len(radiobrowser.get_countries()))) + 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=''))) return page.to_string() @@ -119,7 +134,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).to_string() + return get_directories_page('radiobrowser_country_stations', directories, request.args, + radiobrowser.get_stations_by_country).to_string() @app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/') @@ -131,7 +147,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).to_string() + return get_directories_page('radiobrowser_genre_stations', directories, request.args, + radiobrowser.get_stations_by_genre).to_string() @app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/') diff --git a/ycast/vtuner.py b/ycast/vtuner.py index cca93c4..ecd18f9 100644 --- a/ycast/vtuner.py +++ b/ycast/vtuner.py @@ -86,9 +86,10 @@ class Search: class Directory: - def __init__(self, title, destination): + def __init__(self, title, destination, item_count=-1): self.title = title self.destination = destination + self.item_count = item_count def append_to_xml(self, xml): item = etree.SubElement(xml, 'Item') @@ -96,8 +97,12 @@ class Directory: etree.SubElement(item, 'Title').text = self.title etree.SubElement(item, 'UrlDir').text = add_bogus_parameter(self.destination) etree.SubElement(item, 'UrlDirBackUp').text = add_bogus_parameter(self.destination) + etree.SubElement(item, 'DirCount').text = str(self.item_count) return item + def set_item_count(self, item_count): + self.item_count = item_count + class Station: def __init__(self, uid, name, description, url, logo, genre, location, mime, bitrate, bookmark):