diff --git a/README.rst b/README.rst index a0fb964..8f80ea7 100644 --- a/README.rst +++ b/README.rst @@ -35,8 +35,6 @@ Mopidy-RadioNet to your Mopidy configuration file:: [radionet] enabled = true - username = alice666.9 - password = secret language = pl # or net, de, at, fr, pt, es, dk, se, it min_bitrate = 96 @@ -50,6 +48,10 @@ Project resources Changelog ========= + +v0.2.1 Changes in radio.net +---------------------------------------- + v0.2.0 Python 3 ---------------------------------------- diff --git a/mopidy_radionet/__init__.py b/mopidy_radionet/__init__.py index e0035ac..8b6c2f1 100644 --- a/mopidy_radionet/__init__.py +++ b/mopidy_radionet/__init__.py @@ -6,7 +6,7 @@ import os from mopidy import config, ext -__version__ = '0.2.0' +__version__ = '0.2.1' logger = logging.getLogger(__name__) @@ -24,8 +24,6 @@ class Extension(ext.Extension): def get_config_schema(self): schema = super(Extension, self).get_config_schema() - schema['username'] = config.String() - schema['password'] = config.Secret() schema['language'] = config.String() schema['min_bitrate'] = config.String() return schema diff --git a/mopidy_radionet/backend.py b/mopidy_radionet/backend.py index eb2b845..5752e2b 100644 --- a/mopidy_radionet/backend.py +++ b/mopidy_radionet/backend.py @@ -26,8 +26,6 @@ class RadioNetBackend(pykka.ThreadingActor, backend.Backend): self.library = RadioNetLibraryProvider(backend=self) self.uri_schemes = ['radionet'] - self.username = config['radionet']['username'] - self.password = config['radionet']['password'] self.radionet.min_bitrate = int(config['radionet']['min_bitrate']) self.radionet.set_lang(str(config['radionet']['language'])) @@ -43,9 +41,6 @@ class RadioNetBackend(pykka.ThreadingActor, backend.Backend): self.set_update_timeout() if force or time.time() > self.update_timeout: - self.radionet.login(self.username, self.password) - self.radionet.get_bookmarks() - self.radionet.get_my_stations_streams() self.radionet.get_top_stations() self.radionet.get_local_stations() self.set_update_timeout() diff --git a/mopidy_radionet/ext.conf b/mopidy_radionet/ext.conf index ace9bc2..749507c 100644 --- a/mopidy_radionet/ext.conf +++ b/mopidy_radionet/ext.conf @@ -1,6 +1,4 @@ [radionet] enabled = true -username = alice666.9 -password = secret language = pl min_bitrate = 96 diff --git a/mopidy_radionet/library.py b/mopidy_radionet/library.py index 5df4ce3..c059974 100644 --- a/mopidy_radionet/library.py +++ b/mopidy_radionet/library.py @@ -12,6 +12,9 @@ logger = logging.getLogger(__name__) class RadioNetLibraryProvider(backend.LibraryProvider): root_directory = Ref.directory(uri='radionet:root', name='Radio.net') + def __init__(self, backend): + super().__init__(backend) + def lookup(self, uri): if not uri.startswith('radionet:'): @@ -28,7 +31,7 @@ class RadioNetLibraryProvider(backend.LibraryProvider): album = Album( artists=[artist], name=radio_data.description + ' / ' + radio_data.continent + - ' / ' + radio_data.country + ' - ' + radio_data.city, + ' / ' + radio_data.country + ' - ' + radio_data.city, uri='radionet:station:%s' % (identifier)) track = Track( @@ -38,7 +41,6 @@ class RadioNetLibraryProvider(backend.LibraryProvider): genre=radio_data.genres, comment=radio_data.description, uri=radio_data.stream_url) - return [track] return [] @@ -50,11 +52,6 @@ class RadioNetLibraryProvider(backend.LibraryProvider): tracks = [] variant, identifier = self.parse_uri(uri) if variant == 'root': - if self.backend.radionet.fav_stations: - directories.append( - self.ref_directory( - "radionet:category:favstations", "My stations") - ) if self.backend.radionet.local_stations: directories.append( self.ref_directory( @@ -65,24 +62,20 @@ class RadioNetLibraryProvider(backend.LibraryProvider): self.ref_directory( "radionet:category:top100", "Top 100") ) + return directories elif variant == 'category' and identifier: - if identifier == "favstations": - for station in self.backend.radionet.fav_stations: - tracks.append(self.station_to_ref(station)) if identifier == "localstations": for station in self.backend.radionet.local_stations: tracks.append(self.station_to_ref(station)) if identifier == "top100": for station in self.backend.radionet.top_stations: tracks.append(self.station_to_ref(station)) + tracks.sort(key=lambda ref: ref.name) + return tracks else: logger.debug('Unknown URI: %s', uri) return [] - tracks.sort(key=lambda ref: ref.name) - - return directories + tracks - def search(self, query=None, uris=None, exact=False): result = [] @@ -104,7 +97,8 @@ class RadioNetLibraryProvider(backend.LibraryProvider): def station_to_track(self, station): ref = self.station_to_ref(station) - return Track(uri=ref.uri, name=ref.name) + return Track(uri=ref.uri, name=ref.name, album=Album(uri=ref.uri, name=ref.name), + artists=[Artist(uri=ref.uri, name=ref.name)]) def ref_directory(self, uri, name): return Ref.directory(uri=uri, name=name) diff --git a/mopidy_radionet/radionet.py b/mopidy_radionet/radionet.py index f4cdc84..709a010 100644 --- a/mopidy_radionet/radionet.py +++ b/mopidy_radionet/radionet.py @@ -10,7 +10,6 @@ from mopidy import httpclient import requests - logger = logging.getLogger(__name__) @@ -28,27 +27,23 @@ class Station(object): class RadioNetClient(object): - base_url = 'https://radio.net/' - api_base_url = 'https://api.radio.net/info/v2/' session = requests.Session() api_key = None - user_login = None + api_prefix = None min_bitrate = 96 max_top_stations = 100 station_bookmarks = None - fav_stations = [] + stations_images = [] top_stations = [] local_stations = [] search_results = [] - username = None - password = None - def __init__(self, proxy_config=None, user_agent=None): super(RadioNetClient, self).__init__() + self.session = requests.Session() if proxy_config is not None: proxy = httpclient.format_proxy(proxy_config) @@ -62,12 +57,10 @@ class RadioNetClient(object): langs = ['net', 'de', 'at', 'fr', 'pt', 'es', 'dk', 'se', 'it', 'pl'] if lang in langs: self.base_url = self.base_url.replace(".net", "." + lang) - self.api_base_url = self.api_base_url.replace(".net", "." + lang) else: - logging.error("Radio.net not supported language: " - str(lang)) + logging.error("Radio.net not supported language: %s", str(lang)) def flush(self): - self.fav_stations = [] self.top_stations = [] self.local_stations = [] self.search_results = [] @@ -79,14 +72,16 @@ class RadioNetClient(object): if self.api_key is not None: return - try: - tmp_str = self.session.get(self.base_url) - m = re.search('apiKey ?= ?[\'|"](.*)[\'|"];', tmp_str.content.decode()) - self.api_key = m.group(1) - logger.info('Radio.net: APIKEY %s' % self.api_key) - except Exception: - logger.error('Radio.net: Failed to connect %s retrying' - ' on next browse.' % self.base_url) + tmp_str = self.session.get(self.base_url) + + apiprefix_search = re.search('apiPrefix ?: ?\'(.*)\',?', tmp_str.content.decode()) + self.api_prefix = apiprefix_search.group(1) + + apikey_search = re.search('apiKey ?: ?[\'|"](.*)[\'|"],?', tmp_str.content.decode()) + self.api_key = apikey_search.group(1) + + logger.info('Radio.net: APIPREFIX %s' % self.api_prefix) + logger.info('Radio.net: APIKEY %s' % self.api_key) def do_post(self, api_sufix, url_params=None, payload=None): self.get_api_key() @@ -94,8 +89,9 @@ class RadioNetClient(object): if 'apikey' in url_params.keys(): url_params['apikey'] = self.api_key - response = self.session.post(self.api_base_url + api_sufix, + response = self.session.post(self.api_prefix + api_sufix, params=url_params, data=payload) + return response def do_get(self, api_sufix, url_params=None): @@ -104,123 +100,14 @@ class RadioNetClient(object): if 'apikey' in url_params.keys(): url_params['apikey'] = self.api_key - response = self.session.get(self.api_base_url + api_sufix, - params=url_params) + response = self.session.get(self.api_prefix + api_sufix, + params=url_params) + return response - def check_auth(self): - url_params = { - 'apikey': self.api_key, - '_': self.current_milli_time(), - } - logger.debug('Radio.net: Check auth.') - api_sufix = 'user/account' - - response = self.do_post(api_sufix, url_params) - - json = response.json() - self.user_login = json['login'] - if len(self.user_login) == 0: - self.auth = False - else: - self.auth = True - - def login(self, username, password): - self.check_auth() - - if self.auth: - return - - self.username = username - self.password = password - - url_params = { - 'apikey': self.api_key, - '_': self.current_milli_time(), - } - - logger.debug('Radio.net: Login.') - api_sufix = 'user/login' - payload = { - 'login': username, - 'password': password, - } - response = self.do_post(api_sufix, url_params, payload) - - if response.status_code is not 200: - logger.error('Radio.net: Login error. ' + response.text) - else: - json = response.json() - self.user_login = json['login'] - - if self.user_login == username: - logger.debug('Radio.net: Login successful.') - - def logout(self): - url_params = { - 'apikey': self.api_key, - '_': self.current_milli_time(), - } - api_sufix = 'user/logout' - response = self.do_post(api_sufix, url_params) - - if response.status_code is not 200: - logger.error('Radio.net: Error logout.') - else: - json = response.json() - if len(json['login']) > 0: - logger.error('Radio.net: Error logout.') - else: - logger.info('Radio.net: Logout successful.') - - self.session.close() - - def get_bookmarks(self): - self.station_bookmarks = None - - url_params = { - 'apikey': self.api_key, - '_': self.current_milli_time(), - 'list': 'STATION', - } - api_sufix = 'user/bookmarks' - - response = self.do_post(api_sufix, url_params) - - if response.status_code is not 200: - logger.error('Radio.net: ' + response.text) - else: - logger.debug('Radio.net: Done get bookmarks') - json = response.json() - self.station_bookmarks = json['stationBookmarks'] - - def __get_stream_url(self, stream_json, bitrate): - stream_url = None - - for stream in stream_json: - if int(stream['bitRate']) >= bitrate and \ - stream['streamStatus'] == 'VALID': - stream_url = stream['streamUrl'] - break - - if stream_url is None and len(stream_json) > 0: - stream_url = stream_json[0]['streamUrl'] - - return stream_url - - def get_my_stations_streams(self): - self.fav_stations = [] - for station_item in self.station_bookmarks['pageItems']: - station = self.get_station_by_id(station_item['id']) - if station.playable: - self.fav_stations.append(station) - - logger.info('Radio.net: Loaded ' + str(len(self.fav_stations)) + - ' my stations.') - def get_station_by_id(self, station_id): - api_sufix = 'search/station' + api_suffix = '/search/station' url_params = { 'apikey': self.api_key, @@ -228,7 +115,7 @@ class RadioNetClient(object): 'station': station_id, } - response = self.do_get(api_sufix, url_params) + response = self.do_get(api_suffix, url_params) if response.status_code is not 200: logger.error('Radio.net: Error on get station by id ' + @@ -238,26 +125,26 @@ class RadioNetClient(object): logger.debug('Radio.net: Done get top stations list') json = response.json() - tmpStation = Station() - tmpStation.id = json['id'] - tmpStation.continent = json['continent'] - tmpStation.country = json['country'] - tmpStation.city = json['city'] - tmpStation.genres = ', '.join(json["genres"]) - tmpStation.name = json['name'] - tmpStation.stream_url = self.__get_stream_url( + station = Station() + station.id = json['id'] + station.continent = json['continent'] + station.country = json['country'] + station.city = json['city'] + station.genres = ', '.join(json["genres"]) + station.name = json['name'] + station.stream_url = self.get_stream_url( json['streamUrls'], self.min_bitrate) - tmpStation.image = json['logo300x300'] - tmpStation.description = json['shortDescription'] + station.image = json['logo100x100'] + station.description = json['shortDescription'] if json['playable'] == 'PLAYABLE': - tmpStation.playable = True + station.playable = True - return tmpStation + return station def get_local_stations(self): self.local_stations = [] - api_sufix = 'search/localstations' + api_suffix = '/search/localstations' url_params = { 'apikey': self.api_key, @@ -266,7 +153,7 @@ class RadioNetClient(object): 'sizeperpage': 100, } - response = self.do_post(api_sufix, url_params) + response = self.do_post(api_suffix, url_params) if response.status_code is not 200: logger.error('Radio.net: Get local stations error. ' + @@ -275,17 +162,17 @@ class RadioNetClient(object): logger.debug('Radio.net: Done get local stations list') json = response.json() for match in json['categories'][0]['matches']: - station = self.get_station_by_id(match['id']) - if station: - if station.playable: - self.local_stations.append(station) + station = self.get_station_by_id(match['id']) + if station: + if station.playable: + self.local_stations.append(station) logger.info('Radio.net: Loaded ' + str(len(self.local_stations)) + ' local stations.') def get_top_stations(self): self.top_stations = [] - api_sufix = 'search/topstations' + api_suffix = '/search/topstations' url_params = { 'apikey': self.api_key, @@ -294,7 +181,7 @@ class RadioNetClient(object): 'sizeperpage': 100, } - response = self.do_post(api_sufix, url_params) + response = self.do_post(api_suffix, url_params) if response.status_code is not 200: logger.error('Radio.net: Get top stations error. ' + response.text) @@ -302,10 +189,10 @@ class RadioNetClient(object): logger.debug('Radio.net: Done get top stations list') json = response.json() for match in json['categories'][0]['matches']: - station = self.get_station_by_id(match['id']) - if station: - if station.playable: - self.top_stations.append(station) + station = self.get_station_by_id(match['id']) + if station: + if station.playable: + self.top_stations.append(station) logger.info('Radio.net: Loaded ' + str(len(self.top_stations)) + ' top stations.') @@ -314,7 +201,7 @@ class RadioNetClient(object): if page_index == 1: self.search_results = [] - api_sufix = 'search/stationsonly' + api_suffix = '/search/stationsonly' url_params = { 'apikey': self.api_key, '_': self.current_milli_time(), @@ -322,7 +209,7 @@ class RadioNetClient(object): 'pageindex': page_index, } - response = self.do_post(api_sufix, url_params) + response = self.do_post(api_suffix, url_params) if response.status_code is not 200: logger.error('Radio.net: Search error ' + response.text) @@ -330,9 +217,9 @@ class RadioNetClient(object): logger.debug('Radio.net: Done search') json = response.json() for match in json['categories'][0]['matches']: - station = self.get_station_by_id(match['id']) - if station and station.playable: - self.search_results.append(station) + station = self.get_station_by_id(match['id']) + if station and station.playable: + self.search_results.append(station) number_pages = int(json['numberPages']) if number_pages >= page_index: @@ -340,3 +227,17 @@ class RadioNetClient(object): else: logger.info('Radio.net: Found ' + str(len(self.search_results)) + ' stations.') + + def get_stream_url(self, stream_json, bit_rate): + stream_url = None + + for stream in stream_json: + if int(stream['bitRate']) >= bit_rate and \ + stream['streamStatus'] == 'VALID': + stream_url = stream['streamUrl'] + break + + if stream_url is None and len(stream_json) > 0: + stream_url = stream_json[0]['streamUrl'] + + return stream_url diff --git a/tests/test_extension.py b/tests/test_extension.py index 354750f..df9e449 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -17,7 +17,5 @@ def test_get_config_schema(): schema = ext.get_config_schema() - assert 'username' in schema - assert 'password' in schema assert 'language' in schema assert 'min_bitrate' in schema diff --git a/tests/test_radionet.py b/tests/test_radionet.py index 7c5ae7f..582e222 100644 --- a/tests/test_radionet.py +++ b/tests/test_radionet.py @@ -5,48 +5,24 @@ from mopidy_radionet.radionet import RadioNetClient class RadioNetClientTest(unittest.TestCase): - username = 'alice666.9' - password = 'secret' - def test_get_api_key(self): radionet = RadioNetClient() radionet.get_api_key() self.assertIsNotNone(radionet.api_key) - def test_login(self): - radionet = RadioNetClient() - radionet.login(self.username, self.password) - self.assertEqual(radionet.user_login, self.username) - - def test_get_bookmarks(self): - radionet = RadioNetClient() - radionet.login(self.username, self.password) - radionet.get_bookmarks() - self.assertIsNotNone(radionet.station_bookmarks) - - def test_get_bookmarks_station_streams(self): - radionet = RadioNetClient() - radionet.login(self.username, self.password) - radionet.get_bookmarks() - radionet.get_my_stations_streams() - self.assertGreater(len(radionet.fav_stations), 0) - def test_get_top_stations(self): radionet = RadioNetClient() - radionet.login(self.username, self.password) radionet.get_top_stations() self.assertGreater(len(radionet.top_stations), 0) def test_get_local_stations(self): radionet = RadioNetClient() - radionet.login(self.username, self.password) radionet.get_local_stations() self.assertGreater(len(radionet.local_stations), 0) def test_do_search(self): radionet = RadioNetClient() - radionet.login(self.username, self.password) radionet.do_search("radio ram") self.assertGreater(len(radionet.search_results), 0)