diff --git a/ycast/my_stations.py b/ycast/my_stations.py new file mode 100644 index 0000000..dc6c11f --- /dev/null +++ b/ycast/my_stations.py @@ -0,0 +1,61 @@ +import logging + +import yaml + +import ycast.vtuner as vtuner + +ID_PREFIX = "MY_" + +config_file = 'my_stations.yml' + + +class Station: + def __init__(self, name, url, category): + self.id = ID_PREFIX + '000000' # TODO: generate meaningful ID + self.name = name + self.url = url + self.tag = category + + def to_vtuner(self): + return vtuner.Station(self.id, self.name, self.tag, self.url, None, self.tag, None, None, None, None) + + +def set_config(config): + global config_file + if config: + config_file = config + if get_stations(): + return True + else: + return False + + +def get_stations(): + try: + with open(config_file, 'r') as f: + my_stations = yaml.safe_load(f) + except FileNotFoundError: + logging.error("Station configuration '%s' not found", config_file) + return None + except yaml.YAMLError as e: + logging.error("Station configuration format error: %s", e) + return None + return my_stations + + +def get_categories(): + my_stations_yaml = get_stations() + categories = [] + if my_stations_yaml: + for category in my_stations_yaml: + categories.append(category) + return categories + + +def get_stations_by_category(category): + my_stations_yaml = get_stations() + stations = [] + if my_stations_yaml and category in my_stations_yaml: + for station_name in my_stations_yaml[category]: + stations.append(Station(station_name, my_stations_yaml[category][station_name], category)) + return stations diff --git a/ycast/server.py b/ycast/server.py index 6b4372d..ac4163f 100644 --- a/ycast/server.py +++ b/ycast/server.py @@ -5,42 +5,32 @@ from flask import Flask, request, url_for import ycast.vtuner as vtuner import ycast.radiobrowser as radiobrowser +import ycast.my_stations as my_stations PATH_ROOT = 'ycast' -PATH_CUSTOM_STATIONS = 'my_stations' +PATH_MY_STATIONS = 'my_stations' PATH_RADIOBROWSER = 'radiobrowser' PATH_RADIOBROWSER_COUNTRY = 'country' PATH_RADIOBROWSER_GENRE = 'genre' PATH_RADIOBROWSER_POPULAR = 'popular' PATH_RADIOBROWSER_SEARCH = 'search' -my_stations = {} +my_stations_enabled = False app = Flask(__name__) def run(config, address='0.0.0.0', port=8010): try: - get_stations(config) + check_my_stations_feature(config) app.run(host=address, port=port) except PermissionError: logging.error("No permission to create socket. Are you trying to use ports below 1024 without elevated rights?") -def get_stations(config): - global my_stations - if not config: - logging.warning("If you want to use the 'My Stations' feature, please supply a valid station configuration") - return - try: - with open(config, 'r') as f: - my_stations = yaml.safe_load(f) - except FileNotFoundError: - logging.error("Station configuration '%s' not found", config) - return - except yaml.YAMLError as e: - logging.error("Config error: %s", e) - return +def check_my_stations_feature(config): + global my_stations_enabled + my_stations_enabled = my_stations.set_config(config) def get_directories_page(subdir, directories, requestargs): @@ -112,36 +102,25 @@ def landing(path): return vtuner.get_init_token() page = vtuner.Page() page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True))) - page.add(vtuner.Directory('My Stations', url_for('custom_stations_landing', _external=True))) + if my_stations_enabled: + page.add(vtuner.Directory('My Stations', url_for('my_stations_landing', _external=True))) + else: + page.add(vtuner.Display("'My Stations' feature not configured.")) return page.to_string() -@app.route('/' + PATH_ROOT + '/' + PATH_CUSTOM_STATIONS + '/') -def custom_stations_landing(): +@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/') +def my_stations_landing(): page = vtuner.Page() page.add(vtuner.Previous(url_for("landing", _external=True))) - if not my_stations: - page.add(vtuner.Display("No stations found")) - else: - for category in sorted(my_stations, key=str.lower): - directory = vtuner.Directory(category, url_for('custom_stations_category', - _external=True, category=category)) - page.add(directory) - return page.to_string() + directories = my_stations.get_categories() + return get_directories_page('my_stations_category', directories, request.args).to_string() -@app.route('/' + PATH_ROOT + '/' + PATH_CUSTOM_STATIONS + '/') -def custom_stations_category(category): - page = vtuner.Page() - page.add(vtuner.Previous(url_for('custom_stations_landing', _external=True))) - if category not in my_stations: - page.add(vtuner.Display("Category '" + category + "' not found")) - else: - for station in sorted(my_stations[category], key=str.lower): - station = vtuner.Station(None, station, None, my_stations[category][station], - None, None, None, None, None, None) - page.add(station) - return page.to_string() +@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/') +def my_stations_category(directory): + stations = my_stations.get_stations_by_category(directory) + return get_stations_page(stations, request.args).to_string() @app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/')