Make YCast aware of played streams
Every stream URL is may now be fetched from the YCast server via redirection. This allows for future integration of a "recently played" functionality and an availability check.
This commit is contained in:
parent
8504097e15
commit
7c3161aff9
2 changed files with 51 additions and 16 deletions
|
@ -5,9 +5,11 @@ from flask import Flask, request, url_for, redirect, abort
|
||||||
import ycast.vtuner as vtuner
|
import ycast.vtuner as vtuner
|
||||||
import ycast.radiobrowser as radiobrowser
|
import ycast.radiobrowser as radiobrowser
|
||||||
import ycast.my_stations as my_stations
|
import ycast.my_stations as my_stations
|
||||||
|
import ycast.generic as generic
|
||||||
|
|
||||||
|
|
||||||
PATH_ROOT = 'ycast'
|
PATH_ROOT = 'ycast'
|
||||||
|
PATH_PLAY = 'play'
|
||||||
PATH_SEARCH = 'search'
|
PATH_SEARCH = 'search'
|
||||||
PATH_MY_STATIONS = 'my_stations'
|
PATH_MY_STATIONS = 'my_stations'
|
||||||
PATH_RADIOBROWSER = 'radiobrowser'
|
PATH_RADIOBROWSER = 'radiobrowser'
|
||||||
|
@ -33,12 +35,12 @@ 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):
|
def get_directories_page(subdir, directories, request):
|
||||||
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, request.args):
|
||||||
vtuner_directory = vtuner.Directory(directory.name, url_for(subdir, _external=True, directory=directory.name),
|
vtuner_directory = vtuner.Directory(directory.name, url_for(subdir, _external=True, directory=directory.name),
|
||||||
directory.item_count)
|
directory.item_count)
|
||||||
page.add(vtuner_directory)
|
page.add(vtuner_directory)
|
||||||
|
@ -46,13 +48,16 @@ def get_directories_page(subdir, directories, requestargs):
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
|
||||||
def get_stations_page(stations, requestargs):
|
def get_stations_page(stations, request, tracked=True):
|
||||||
page = vtuner.Page()
|
page = vtuner.Page()
|
||||||
if len(stations) == 0:
|
if len(stations) == 0:
|
||||||
page.add(vtuner.Display("No stations found."))
|
page.add(vtuner.Display("No stations found."))
|
||||||
return page
|
return page
|
||||||
for station in get_paged_elements(stations, requestargs):
|
for station in get_paged_elements(stations, request.args):
|
||||||
page.add(station.to_vtuner())
|
vtuner_station = station.to_vtuner()
|
||||||
|
if tracked:
|
||||||
|
vtuner_station.set_trackurl(request.host_url + PATH_ROOT + '/' + PATH_PLAY + '?id=' + vtuner_station.uid)
|
||||||
|
page.add(vtuner_station)
|
||||||
page.set_count(len(stations))
|
page.set_count(len(stations))
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
@ -81,6 +86,15 @@ def get_paged_elements(items, requestargs):
|
||||||
return items[offset:limit]
|
return items[offset:limit]
|
||||||
|
|
||||||
|
|
||||||
|
def get_station_by_id(stationid):
|
||||||
|
station_id_prefix = generic.get_stationid_prefix(stationid)
|
||||||
|
if station_id_prefix == my_stations.ID_PREFIX:
|
||||||
|
return my_stations.get_station_by_id(generic.get_stationid_without_prefix(stationid))
|
||||||
|
elif station_id_prefix == radiobrowser.ID_PREFIX:
|
||||||
|
return radiobrowser.get_station_by_id(generic.get_stationid_without_prefix(stationid))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
@app.route('/setupapp/<path:path>')
|
@app.route('/setupapp/<path:path>')
|
||||||
def upstream(path):
|
def upstream(path):
|
||||||
if request.args.get('token') == '0':
|
if request.args.get('token') == '0':
|
||||||
|
@ -111,13 +125,13 @@ 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_category_directories()
|
directories = my_stations.get_category_directories()
|
||||||
return get_directories_page('my_stations_category', directories, request.args).to_string()
|
return get_directories_page('my_stations_category', directories, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/<directory>')
|
||||||
def my_stations_category(directory):
|
def my_stations_category(directory):
|
||||||
stations = my_stations.get_stations_by_category(directory)
|
stations = my_stations.get_stations_by_category(directory)
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/')
|
||||||
|
@ -138,43 +152,43 @@ 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_country_directories()
|
directories = radiobrowser.get_country_directories()
|
||||||
return get_directories_page('radiobrowser_country_stations', directories, request.args).to_string()
|
return get_directories_page('radiobrowser_country_stations', directories, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/<directory>')
|
||||||
def radiobrowser_country_stations(directory):
|
def radiobrowser_country_stations(directory):
|
||||||
stations = radiobrowser.get_stations_by_country(directory)
|
stations = radiobrowser.get_stations_by_country(directory)
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_LANGUAGE + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_LANGUAGE + '/')
|
||||||
def radiobrowser_languages():
|
def radiobrowser_languages():
|
||||||
directories = radiobrowser.get_language_directories()
|
directories = radiobrowser.get_language_directories()
|
||||||
return get_directories_page('radiobrowser_language_stations', directories, request.args).to_string()
|
return get_directories_page('radiobrowser_language_stations', directories, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_LANGUAGE + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_LANGUAGE + '/<directory>')
|
||||||
def radiobrowser_language_stations(directory):
|
def radiobrowser_language_stations(directory):
|
||||||
stations = radiobrowser.get_stations_by_language(directory)
|
stations = radiobrowser.get_stations_by_language(directory)
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@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_genre_directories()
|
directories = radiobrowser.get_genre_directories()
|
||||||
return get_directories_page('radiobrowser_genre_stations', directories, request.args).to_string()
|
return get_directories_page('radiobrowser_genre_stations', directories, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/<directory>')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_GENRE + '/<directory>')
|
||||||
def radiobrowser_genre_stations(directory):
|
def radiobrowser_genre_stations(directory):
|
||||||
stations = radiobrowser.get_stations_by_genre(directory)
|
stations = radiobrowser.get_stations_by_genre(directory)
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_POPULAR + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_POPULAR + '/')
|
||||||
def radiobrowser_popular():
|
def radiobrowser_popular():
|
||||||
stations = radiobrowser.get_stations_by_votes()
|
stations = radiobrowser.get_stations_by_votes()
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
@app.route('/' + PATH_ROOT + '/' + PATH_SEARCH + '/')
|
@app.route('/' + PATH_ROOT + '/' + PATH_SEARCH + '/')
|
||||||
|
@ -189,4 +203,18 @@ def station_search():
|
||||||
else:
|
else:
|
||||||
# TODO: we also need to include 'my station' elements
|
# TODO: we also need to include 'my station' elements
|
||||||
stations = radiobrowser.search(query)
|
stations = radiobrowser.search(query)
|
||||||
return get_stations_page(stations, request.args).to_string()
|
return get_stations_page(stations, request).to_string()
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/' + PATH_ROOT + '/' + PATH_PLAY)
|
||||||
|
def get_stream_url():
|
||||||
|
stationid = request.args.get('id')
|
||||||
|
if not stationid:
|
||||||
|
logging.error("Stream URL without station ID requested")
|
||||||
|
abort(400)
|
||||||
|
station = get_station_by_id(stationid)
|
||||||
|
if not station:
|
||||||
|
logging.error("Could not get station with id '%s'", stationid)
|
||||||
|
abort(404)
|
||||||
|
logging.debug("Station with ID '%s' requested", station.id)
|
||||||
|
return redirect(station.url, code=302)
|
||||||
|
|
|
@ -110,6 +110,7 @@ class Station:
|
||||||
self.name = name
|
self.name = name
|
||||||
self.description = description
|
self.description = description
|
||||||
self.url = strip_https(url)
|
self.url = strip_https(url)
|
||||||
|
self.trackurl = None
|
||||||
self.logo = logo
|
self.logo = logo
|
||||||
self.genre = genre
|
self.genre = genre
|
||||||
self.location = location
|
self.location = location
|
||||||
|
@ -117,12 +118,18 @@ class Station:
|
||||||
self.bitrate = bitrate
|
self.bitrate = bitrate
|
||||||
self.bookmark = bookmark
|
self.bookmark = bookmark
|
||||||
|
|
||||||
|
def set_trackurl(self, url):
|
||||||
|
self.trackurl = url
|
||||||
|
|
||||||
def to_xml(self):
|
def to_xml(self):
|
||||||
item = ET.Element('Item')
|
item = ET.Element('Item')
|
||||||
ET.SubElement(item, 'ItemType').text = 'Station'
|
ET.SubElement(item, 'ItemType').text = 'Station'
|
||||||
ET.SubElement(item, 'StationId').text = self.uid
|
ET.SubElement(item, 'StationId').text = self.uid
|
||||||
ET.SubElement(item, 'StationName').text = self.name
|
ET.SubElement(item, 'StationName').text = self.name
|
||||||
ET.SubElement(item, 'StationUrl').text = self.url
|
if self.trackurl:
|
||||||
|
ET.SubElement(item, 'StationUrl').text = self.trackurl
|
||||||
|
else:
|
||||||
|
ET.SubElement(item, 'StationUrl').text = self.url
|
||||||
ET.SubElement(item, 'StationDesc').text = self.description
|
ET.SubElement(item, 'StationDesc').text = self.description
|
||||||
ET.SubElement(item, 'Logo').text = self.logo
|
ET.SubElement(item, 'Logo').text = self.logo
|
||||||
ET.SubElement(item, 'StationFormat').text = self.genre
|
ET.SubElement(item, 'StationFormat').text = self.genre
|
||||||
|
|
Loading…
Reference in a new issue