Compare commits

...

30 commits

Author SHA1 Message Date
Micha LaQua
f349a2686c
Merge pull request #77 from tomtastic/patch-1
Fix API endpoint for get_station_by_id
2020-12-03 13:41:47 +01:00
Micha LaQua
22475e9c3a
Merge pull request #70 from Arduous/patch-1
Update README.md ycast works with a Marantz SR5009
2020-12-03 13:35:08 +01:00
Micha LaQua
1d65195926
Merge pull request #73 from Arduous/master
radiobrowser.py: remove inadequate print statement.
2020-12-03 13:34:38 +01:00
Tom Matthews
25ecc9b668
Fix API endpoint for get_station_by_id
Fixes https://github.com/milaq/YCast/issues/76
2020-11-29 11:20:17 +00:00
Samuel Progin
595dea2fd5
radiobrowser.py: remove inadequate print statement.
The print statement is removed as:
- It is not present in other very similar methods
- It clutters the log
2020-10-24 17:28:38 +02:00
Samuel Progin
a37b86f638
Update README.md ycast works with a Marantz SR5009
Thank you.
2020-10-20 17:50:36 +02:00
milaq
e01d0af1a7 bump version 2020-10-10 17:07:17 +02:00
milaq
9ea3f3c3c9 Merge branch 'master' of github.com:milaq/YCast into master 2020-10-10 16:38:35 +02:00
milaq
f39b65e759 Add dynamic directory displayname
Also capitalize genres and all capitalize languages

Co-authored-by: Jonathan Rawle <git@jonathanrawle.co.uk>
2020-10-10 16:36:44 +02:00
Micha LaQua
00ba3ace66
Merge pull request #55 from mbroz/master
Add Denon DNP-720AE to confirmed devices
2020-10-10 16:03:28 +02:00
Micha LaQua
e799b92ed6
Merge branch 'master' into master 2020-10-10 16:02:46 +02:00
Milan Broz
ab2ac64cc0 Add Denon DNP-720AE to confirmed devices 2020-10-10 16:02:04 +02:00
Micha LaQua
f920d9f286
Merge pull request #60 from 463/patch-1
Add Denon DNP-730AE to confirmed devices
2020-10-10 16:00:19 +02:00
milaq
e893948485 Add Yamaha CRX-N560/MCR-N560 to supported devices
Thanks to @ra666ack for reporting
2020-10-10 15:58:45 +02:00
milaq
dc6bcf19d4 Add instructions for Grundig radios
Co-authored-by: Jakub Janeczko <jjaneczk@gmail.com>
2020-10-10 15:54:12 +02:00
Jakub Janeczko
9cbd4eb254 server: Some devices use capital I in {start,end}Items 2020-10-10 15:48:36 +02:00
Jakub Janeczko
04c40f2b5f add support for navXML.asp and FavXML.asp queries
Some devices use hardcoded links for station list and favourites.
2020-10-10 15:46:41 +02:00
Guido Schmitz
ee5d6ffdb1 Add POST method for Denon Remote App 2020-10-10 15:43:16 +02:00
milaq
0a2aaa163d Radiobrowser: Migrate to new API
Also fix up attributes and countrycode mapping as outlined in migration suggestions at https://api.radio-browser.info/

Co-authored-by: Thomas Endt <thomas.endt@uipath.com>
Co-authored-by: Jonathan Rawle <git@jonathanrawle.co.uk>
2020-10-10 15:20:22 +02:00
463
ae0e3b6c8c
Update README.md
Denon DNP-730AE is working well too
2020-06-30 16:26:47 +02:00
Milan Broz
d40cf3d894 Add Denon DNP-720AE to confirmed devices 2020-06-05 19:29:49 +02:00
milaq
1c296ec089 Add more tested and supported devices 2020-05-16 10:09:39 +02:00
milaq
d0c87277a9 Add more confirmed devices and revise sort order 2020-04-28 23:58:36 +02:00
Jakub Janeczko
544fe5d981 Readme: Add RX-V500D to supported devices
Also add a note about home routers.
2020-02-24 01:19:14 +01:00
milaq
85ee2d6797 Add Denon DRA-100 to confirmed devices 2020-02-24 00:47:03 +01:00
milaq
e17dff463a readme: confirm more devices
Also use underscore instead of an 'x' for model number wildcards
to increase readability.
2020-01-12 16:23:49 +01:00
milaq
b89ac21546 Nginx example: Don't try to resolve ipv6 localhost 2020-01-12 16:07:27 +01:00
milaq
ceb71ab00d Add request host checking to redirects
Notifies the user even without debug logging and makes troubleshooting easier.
2019-09-04 20:52:34 +02:00
milaq
9ce1e19ea3 Add Yamaha RX-Vx77 series to tested devices 2019-09-04 20:52:29 +02:00
milaq
1b4ba071b7 Disable station tracking by default
Station tracking depends on redirects which some AVRs don't do in a discernible manner.
We enable this again when we found out what makes redirects work for the affected models.
2019-08-27 19:37:57 +02:00
7 changed files with 121 additions and 55 deletions

View file

@ -29,29 +29,49 @@ Any reported device helps the community to see which AVRs work properly and whic
### Confirmed working
* Yamaha RX-Vx73 series (RX-V373, RX-V473, RX-V573, RX-V673, RX-V773)
* Yamaha RX-Vx75 series (RX-V375, RX-V475, RX-V575, RX-V675, RX-V775)
* Denon AVR-X_000 series (AVR-X1000, AVR-2000, AVR-X3000, AVR-X4000)
* Denon AVR-1912
* Denon AVR-X2200W
* Denon CEOL piccolo N5
* Denon CEOL N9
* Denon DNP-720AE
* Denon DNP-730AE
* Denon DRA-100
* Marantz Melody Media M-CR610
* Marantz NR1506
* Marantz NR1605
* Marantz NA6005
* Marantz NA8005
* Marantz SR5009
* Onkyo TX-NR414
* Onkyo TX-NR5009
* Onkyo TX-NR616
* Yamaha R-N301
* Yamaha R-N500
* Yamaha RX-A810
* Yamaha RX-A820
* Yamaha RX-A830
* Onkyo TX-NR414
* Marantz Melody Media M-CR610
* Yamaha CRX-N560/MCR-N560
* Yamaha RX-V_71 series with network connectivity (RX-V671, RX-V771)
* Yamaha RX-V_73 series with network connectivity (RX-V473, RX-V573, RX-V673, RX-V773)
* Yamaha RX-V_75 series (RX-V375, RX-V475, RX-V575, RX-V675, RX-V775)
* Yamaha RX-V_77 series (RX-V377, RX-V477, RX-V577, RX-V677, RX-V777)
* Yamaha RX-V3067
* Yamaha RX-V500D
### Unconfirmed/Experimental
* Yamaha RX-Vx77 series (RX-V377, RX-V477, RX-V577, RX-V677, RX-V777)
* Yamaha RX-Vx79 series (RX-V379, RX-V479, RX-V579, RX-V679, RX-V779)
* Yamaha RX-Vx81 series (RX-V381, RX-V481, RX-V581, RX-V681, RX-V781)
* Denon AVR-X_100W series (AVR-X1100W, AVR-2100W, AVR-X3100W, AVR-X4100W)
* Denon AVR-X_300W series (AVR-X1300W, AVR-2300W, AVR-X3300W)
* Yamaha RX-A1060
* Yamaha CX-A5000
* Yamaha RX-S600D
* Yamaha RX-S601D
* Yamaha WX-030
* Yamaha RX-A1060
* Yamaha RX-V2700
* Yamaha RX-V3800
* Yamaha CX-A5000
* Denon AVR-Xx000 series (AVR-X1000, AVR-2000, AVR-X3000, AVR-X4000)
* Denon AVR-Xx100W series (AVR-X1100W, AVR-2100W, AVR-X3100W, AVR-X4100W)
* Denon AVR-Xx300W series (AVR-X1300W, AVR-2300W, AVR-X3300W)
* Yamaha RX-V_79 series (RX-V379, RX-V479, RX-V579, RX-V679, RX-V779)
* Yamaha RX-V_81 series (RX-V381, RX-V481, RX-V581, RX-V681, RX-V781)
* Yamaha WX-030
## Dependencies:
Python version: `3`
@ -64,15 +84,17 @@ Python packages:
## Usage
YCast really does not need much computing power nor bandwidth, i.e. you can run it on a low-spec RISC machine like a Raspberry Pi.
YCast really does not need much computing power nor bandwidth, i.e. you can run it on a low-spec RISC machine like a Raspberry Pi or a home router.
### DNS entries
You need to create a manual entry in your DNS server (read 'Router' for most home users). `vtuner.com` (more specifically `*.vtuner.com`) should point to the machine YCast is running on. Alternatively, in case you only want to forward specific vendors, the following entries may be configured:
You need to create a manual entry in your DNS server (read 'Router' for most home users). The `*.vtuner.com` domain should point to the machine YCast is running on.
Specifically the following entries may be configured instead of a wildcard entry:
* Yamaha AVRs: `radioyamaha.vtuner.com` (and optionally `radioyamaha2.vtuner.com`)
* Onkyo AVRs: `onkyo.vtuner.com` (and optionally `onkyo2.vtuner.com`)
* Denon/Marantz AVRs: `denon.vtuner.com` (and optionally `denon2.vtuner.com`)
* Grundig radios: `grundig.vtuner.com`, `grundig.radiosetup.com` (and optionally `grundig2.vtuner.com` and `grundig2.radiosetup.com`)
### Running the server

View file

@ -13,6 +13,6 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8010;
proxy_pass http://127.0.0.1:8010;
}
}

View file

@ -1 +1 @@
__version__ = '1.0.0'
__version__ = '1.1.0'

View file

@ -7,9 +7,13 @@ CACHE_PATH = VAR_PATH + '/cache'
class Directory:
def __init__(self, name, item_count):
def __init__(self, name, item_count, displayname=None):
self.name = name
self.item_count = item_count
if displayname:
self.displayname = displayname
else:
self.displayname = name
def generate_stationid_with_prefix(uid, prefix):

View file

@ -5,6 +5,7 @@ from ycast import __version__
import ycast.vtuner as vtuner
import ycast.generic as generic
API_ENDPOINT = "http://all.api.radio-browser.info"
MINIMUM_COUNT_GENRE = 5
MINIMUM_COUNT_COUNTRY = 5
MINIMUM_COUNT_LANGUAGE = 5
@ -22,12 +23,12 @@ def get_json_attr(json, attr):
class Station:
def __init__(self, station_json):
self.id = generic.generate_stationid_with_prefix(get_json_attr(station_json, 'id'), ID_PREFIX)
self.id = generic.generate_stationid_with_prefix(get_json_attr(station_json, 'stationuuid'), ID_PREFIX)
self.name = get_json_attr(station_json, 'name')
self.url = get_json_attr(station_json, 'url')
self.icon = get_json_attr(station_json, 'favicon')
self.tags = get_json_attr(station_json, 'tags').split(',')
self.country = get_json_attr(station_json, 'country')
self.countrycode = get_json_attr(station_json, 'countrycode')
self.language = get_json_attr(station_json, 'language')
self.votes = get_json_attr(station_json, 'votes')
self.codec = get_json_attr(station_json, 'codec')
@ -35,7 +36,7 @@ class Station:
def to_vtuner(self):
return vtuner.Station(self.id, self.name, ', '.join(self.tags), self.url, self.icon,
self.tags[0], self.country, self.codec, self.bitrate, None)
self.tags[0], self.countrycode, self.codec, self.bitrate, None)
def get_playable_url(self):
try:
@ -49,7 +50,7 @@ def request(url):
logging.debug("Radiobrowser API request: %s", url)
headers = {'content-type': 'application/json', 'User-Agent': generic.USER_AGENT + '/' + __version__}
try:
response = requests.get('http://www.radio-browser.info/webservice/json/' + url, headers=headers)
response = requests.get(API_ENDPOINT + '/json/' + url, headers=headers)
except requests.exceptions.ConnectionError as err:
logging.error("Connection to Radiobrowser API failed (%s)", err)
return {}
@ -60,7 +61,7 @@ def request(url):
def get_station_by_id(uid):
station_json = request('stations/byid/' + str(uid))
station_json = request('stations/byuuid/' + str(uid))
if station_json and len(station_json):
return Station(station_json[0])
else:
@ -71,7 +72,7 @@ def search(name, limit=DEFAULT_STATION_LIMIT):
stations = []
stations_json = request('stations/search?order=name&reverse=false&limit=' + str(limit) + '&name=' + str(name))
for station_json in stations_json:
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == 1:
stations.append(Station(station_json))
return stations
@ -100,7 +101,8 @@ def get_language_directories():
if get_json_attr(language_raw, 'name') and get_json_attr(language_raw, 'stationcount') and \
int(get_json_attr(language_raw, 'stationcount')) > MINIMUM_COUNT_LANGUAGE:
language_directories.append(generic.Directory(get_json_attr(language_raw, 'name'),
get_json_attr(language_raw, 'stationcount')))
get_json_attr(language_raw, 'stationcount'),
get_json_attr(language_raw, 'name').title()))
return language_directories
@ -114,7 +116,8 @@ def get_genre_directories():
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:
genre_directories.append(generic.Directory(get_json_attr(genre_raw, 'name'),
get_json_attr(genre_raw, 'stationcount')))
get_json_attr(genre_raw, 'stationcount'),
get_json_attr(genre_raw, 'name').capitalize()))
return genre_directories
@ -122,7 +125,7 @@ def get_stations_by_country(country):
stations = []
stations_json = request('stations/search?order=name&reverse=false&countryExact=true&country=' + str(country))
for station_json in stations_json:
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == 1:
stations.append(Station(station_json))
return stations
@ -131,7 +134,7 @@ def get_stations_by_language(language):
stations = []
stations_json = request('stations/search?order=name&reverse=false&languageExact=true&language=' + str(language))
for station_json in stations_json:
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == 1:
stations.append(Station(station_json))
return stations
@ -140,7 +143,7 @@ def get_stations_by_genre(genre):
stations = []
stations_json = request('stations/search?order=name&reverse=false&tagExact=true&tag=' + str(genre))
for station_json in stations_json:
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == 1:
stations.append(Station(station_json))
return stations
@ -149,6 +152,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:
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == '1':
if SHOW_BROKEN_STATIONS or get_json_attr(station_json, 'lastcheckok') == 1:
stations.append(Station(station_json))
return stations

View file

@ -1,4 +1,5 @@
import logging
import re
from flask import Flask, request, url_for, redirect, abort, make_response
@ -21,6 +22,7 @@ PATH_RADIOBROWSER_LANGUAGE = 'language'
PATH_RADIOBROWSER_GENRE = 'genre'
PATH_RADIOBROWSER_POPULAR = 'popular'
station_tracking = False
my_stations_enabled = False
app = Flask(__name__)
@ -45,14 +47,15 @@ def get_directories_page(subdir, directories, request):
page.set_count(1)
return page
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.displayname,
url_for(subdir, _external=True, directory=directory.name),
directory.item_count)
page.add(vtuner_directory)
page.set_count(len(directories))
return page
def get_stations_page(stations, request, tracked=True):
def get_stations_page(stations, request):
page = vtuner.Page()
if len(stations) == 0:
page.add(vtuner.Display("No stations found"))
@ -60,7 +63,7 @@ def get_stations_page(stations, request, tracked=True):
return page
for station in get_paged_elements(stations, request.args):
vtuner_station = station.to_vtuner()
if tracked:
if station_tracking:
vtuner_station.set_trackurl(request.host_url + PATH_ROOT + '/' + PATH_PLAY + '?id=' + vtuner_station.uid)
vtuner_station.icon = request.host_url + PATH_ROOT + '/' + PATH_ICON + '?id=' + vtuner_station.uid
page.add(vtuner_station)
@ -71,6 +74,8 @@ def get_stations_page(stations, request, tracked=True):
def get_paged_elements(items, requestargs):
if requestargs.get('startitems'):
offset = int(requestargs.get('startitems')) - 1
elif requestargs.get('startItems'):
offset = int(requestargs.get('startItems')) - 1
elif requestargs.get('start'):
offset = int(requestargs.get('start')) - 1
else:
@ -80,6 +85,8 @@ def get_paged_elements(items, requestargs):
return []
if requestargs.get('enditems'):
limit = int(requestargs.get('enditems'))
elif 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:
@ -104,7 +111,15 @@ def get_station_by_id(stationid, additional_info=False):
return None
@app.route('/setupapp/<path:path>')
def vtuner_redirect(url):
if request and request.host and not re.search("^[A-Za-z0-9]+\.vtuner\.com$", request.host):
logging.warning("You are not accessing a YCast redirect with a whitelisted host url (*.vtuner.com). "
"Some AVRs have problems with this. The requested host was: %s", request.host)
return redirect(url, code=302)
@app.route('/setupapp/<path:path>',
methods=['GET', 'POST'])
def upstream(path):
if request.args.get('token') == '0':
return vtuner.get_init_token()
@ -112,14 +127,22 @@ def upstream(path):
return station_search()
if 'statxml.asp' in path and request.args.get('id'):
return get_station_info()
if 'navXML.asp' in path:
return radiobrowser_landing()
if 'FavXML.asp' in path:
return my_stations_landing()
if 'loginXML.asp' in path:
return landing()
logging.error("Unhandled upstream query (/setupapp/%s)", path)
abort(404)
@app.route('/', defaults={'path': ''})
@app.route('/' + PATH_ROOT + '/', defaults={'path': ''})
@app.route('/',
defaults={'path': ''},
methods=['GET', 'POST'])
@app.route('/' + PATH_ROOT + '/',
defaults={'path': ''},
methods=['GET', 'POST'])
def landing(path=''):
page = vtuner.Page()
page.add(vtuner.Directory('Radiobrowser', url_for('radiobrowser_landing', _external=True), 4))
@ -132,19 +155,22 @@ def landing(path=''):
return page.to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/')
@app.route('/' + PATH_ROOT + '/' + PATH_MY_STATIONS + '/',
methods=['GET', 'POST'])
def my_stations_landing():
directories = my_stations.get_category_directories()
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>',
methods=['GET', 'POST'])
def my_stations_category(directory):
stations = my_stations.get_stations_by_category(directory)
return get_stations_page(stations, request).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/')
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/',
methods=['GET', 'POST'])
def radiobrowser_landing():
page = vtuner.Page()
page.add(vtuner.Directory('Genres', url_for('radiobrowser_genres', _external=True),
@ -159,49 +185,57 @@ def radiobrowser_landing():
return page.to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/')
@app.route('/' + PATH_ROOT + '/' + PATH_RADIOBROWSER + '/' + PATH_RADIOBROWSER_COUNTRY + '/',
methods=['GET', 'POST'])
def radiobrowser_countries():
directories = radiobrowser.get_country_directories()
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>',
methods=['GET', 'POST'])
def radiobrowser_country_stations(directory):
stations = radiobrowser.get_stations_by_country(directory)
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 + '/',
methods=['GET', 'POST'])
def radiobrowser_languages():
directories = radiobrowser.get_language_directories()
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>',
methods=['GET', 'POST'])
def radiobrowser_language_stations(directory):
stations = radiobrowser.get_stations_by_language(directory)
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 + '/',
methods=['GET', 'POST'])
def radiobrowser_genres():
directories = radiobrowser.get_genre_directories()
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>',
methods=['GET', 'POST'])
def radiobrowser_genre_stations(directory):
stations = radiobrowser.get_stations_by_genre(directory)
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 + '/',
methods=['GET', 'POST'])
def radiobrowser_popular():
stations = radiobrowser.get_stations_by_votes()
return get_stations_page(stations, request).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_SEARCH + '/')
@app.route('/' + PATH_ROOT + '/' + PATH_SEARCH + '/',
methods=['GET', 'POST'])
def station_search():
query = request.args.get('search')
if not query or len(query) < 3:
@ -215,7 +249,8 @@ def station_search():
return get_stations_page(stations, request).to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_PLAY)
@app.route('/' + PATH_ROOT + '/' + PATH_PLAY,
methods=['GET', 'POST'])
def get_stream_url():
stationid = request.args.get('id')
if not stationid:
@ -226,16 +261,17 @@ def get_stream_url():
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)
return vtuner_redirect(station.url)
@app.route('/' + PATH_ROOT + '/' + PATH_STATION)
def get_station_info(tracked=True):
@app.route('/' + PATH_ROOT + '/' + PATH_STATION,
methods=['GET', 'POST'])
def get_station_info():
stationid = request.args.get('id')
if not stationid:
logging.error("Station info without station ID requested")
abort(400)
station = get_station_by_id(stationid, additional_info=not tracked)
station = get_station_by_id(stationid, additional_info=(not station_tracking))
if not station:
logging.error("Could not get station with id '%s'", stationid)
page = vtuner.Page()
@ -243,7 +279,7 @@ def get_station_info(tracked=True):
page.set_count(1)
return page.to_string()
vtuner_station = station.to_vtuner()
if tracked:
if station_tracking:
vtuner_station.set_trackurl(request.host_url + PATH_ROOT + '/' + PATH_PLAY + '?id=' + vtuner_station.uid)
vtuner_station.icon = request.host_url + PATH_ROOT + '/' + PATH_ICON + '?id=' + vtuner_station.uid
page = vtuner.Page()
@ -252,7 +288,8 @@ def get_station_info(tracked=True):
return page.to_string()
@app.route('/' + PATH_ROOT + '/' + PATH_ICON)
@app.route('/' + PATH_ROOT + '/' + PATH_ICON,
methods=['GET', 'POST'])
def get_station_icon():
stationid = request.args.get('id')
if not stationid:

View file

@ -137,7 +137,7 @@ class Station:
ET.SubElement(item, 'Logo').text = self.icon
ET.SubElement(item, 'StationFormat').text = self.genre
ET.SubElement(item, 'StationLocation').text = self.location
ET.SubElement(item, 'StationBandWidth').text = self.bitrate
ET.SubElement(item, 'StationBandWidth').text = str(self.bitrate)
ET.SubElement(item, 'StationMime').text = self.mime
ET.SubElement(item, 'Relia').text = '3'
ET.SubElement(item, 'Bookmark').text = self.bookmark