def __init__(self): self.nombre_radios_pais = [] self.url_radios_pais = [] self.resultado_pais_busqueda_nombre = [] self.resultado_pais_busqueda_numero = [] self.resultado_pais_busqueda_abreviado = [] self.nombre_busqueda_general_radio = [] self.url_busqueda_general_radio = [] self.nombre_idioma = [] self.cantidad_idioma = [] self.busqueda_nombre_idioma = [] self.busqueda_cantidad_idioma = [] self.nombre_tag = [] self.cantidad_tag = [] self.busqueda_nombre_tag = [] self.busqueda_cantidad_tag = [] self.paises_radio_español = [] self.paises_radio_abreviado = [] self.paises_numero_emisoras = [] self.paises_numero_total_emisoras = "" self.rb = RadioBrowser() self.datos_pais = self.rb.countries()
def cmd_rb_play(bot, user, text, command, parameter): global log log.debug('cmd: Play a station by ID') if not parameter: log.debug('rbplay without parameter') msg = tr('rb_play_empty') bot.send_msg(msg, text) else: log.debug('cmd: Retreiving url for station ID ' + parameter) rb = RadioBrowser() rstation = rb.station_by_uuid(parameter) stationname = rstation[0]['name'] country = rstation[0]['countrycode'] codec = rstation[0]['codec'] bitrate = rstation[0]['bitrate'] genre = rstation[0]['tags'] homepage = rstation[0]['homepage'] url = rstation[0]['url'] msg = 'Radio station added to playlist:' msg += '<table><tr><th>ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th><th>Homepage</th></tr>' + \ f"<tr><td>{parameter}</td><td>{stationname}</td><td>{genre}</td><td>{codec}/{bitrate}</td><td>{country}</td><td>{homepage}</td></tr></table>" log.debug(f'cmd: Added station to playlist {stationname}') bot.send_msg(msg, text) if url != "-1": log.info('cmd: Found url: ' + url) music_wrapper = get_cached_wrapper_from_scrap(type='radio', url=url, name=stationname, user=user) var.playlist.append(music_wrapper) log.info("cmd: add to playlist: " + music_wrapper.format_debug_string()) bot.async_download_next() else: log.info('cmd: No playable url found.') msg += "No playable url found for this station, please try another station." bot.send_msg(msg, text)
def __init__(self): self.nombre_radios_pais = [] self.url_radios_pais = [] self.resultado_pais_busqueda_nombre = [] self.resultado_pais_busqueda_numero = [] self.resultado_pais_busqueda_abreviado = [] self.nombre_busqueda_general_radio = [] self.url_busqueda_general_radio = [] self.nombre_idioma = [] self.cantidad_idioma = [] self.busqueda_nombre_idioma = [] self.busqueda_cantidad_idioma = [] self.nombre_tag = [] self.cantidad_tag = [] self.busqueda_nombre_tag = [] self.busqueda_cantidad_tag = [] self.paises_radio_español = [] self.paises_radio_abreviado = [] self.paises_numero_emisoras = [] self.paises_numero_total_emisoras = "" expire_after = timedelta(days=3) session = CachedSession( cache_name=os.path.join(globalVars.appArgs.configPath, "zRadio", "cache"), backend='sqlite', expire_after=expire_after) self.rb = RadioBrowser(session=session) self.datos_pais = self.rb.countries()
def CPS_match_query_phrase(self, phrase): # Look for regex matches # Play (radio|station|stream) <data> match = re.search(self.translate_regex('radio'), phrase) try: data = re.sub(self.translate_regex('radio'), '', phrase) rb = RadioBrowser() stations = rb.search(name=data, bitrateMin='128') stations != [] self.log.info('CPS Match (radio): ' + stations[0]['name'] + ' | ' + stations[0]['url']) if match: return (stations[0]['name'], CPSMatchLevel.EXACT, { "station": stations[0]["name"], "url": stations[0]["url"], "image": stations[0]['favicon'] }) else: return (stations[0]['name'], CPSMatchLevel.TITLE, { "station": stations[0]["name"], "url": stations[0]["url"], "image": stations[0]['favicon'] }) except Exception: return None
def match_genre(phrase): """Takes the user utterance and attempts to match a genre of station, returning the most popular of that genre. :param phrase: User utterance :type phrase: str :return: A tuple containing the original phrase, the CPS.MatchLevel, and a dictionary containing the resolved stream URL. :rtype: tuple """ # Strip 'a' and 'station' from phrases like 'Play a jazz station.'. stripped_phrase = phrase.lower().replace("a ", "").replace(" station", "") try: rb = RadioBrowser() except Exception as e: LOG.exception("Failed to load pyradios" + repr(e)) LOG.info(f"Searching for a {stripped_phrase} station") results = rb.search(tag=stripped_phrase, order="votes") parsed = json.loads(json.dumps(results)) if len(parsed) > 0: LOG.info(f"Found {parsed[0]['name']} ({parsed[0]['url_resolved']})") return phrase, CPSMatchLevel.EXACT, {"url": parsed[0]["url_resolved"]} else: match_station_name(phrase)
def cmd_rb_query(bot, user, text, command, parameter): global log log.info('cmd: Querying radio stations') if not parameter: log.debug('rbquery without parameter') msg = tr('rb_query_empty') bot.send_msg(msg, text) else: log.debug('cmd: Found query parameter: ' + parameter) rb = RadioBrowser() rb_stations = rb.search(name=parameter, name_exact=False) msg = tr('rb_query_result') msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th><th>Genre</th><th>Codec/Bitrate</th><th>Country</th></tr>' if not rb_stations: log.debug(f"cmd: No matches found for rbquery {parameter}") bot.send_msg(f"Radio-Browser found no matches for {parameter}", text) else: for s in rb_stations: station_id = s['stationuuid'] station_name = s['name'] country = s['countrycode'] codec = s['codec'] bitrate = s['bitrate'] genre = s['tags'] msg += f"<tr><td>{station_id}</td><td>{station_name}</td><td>{genre}</td><td>{codec}/{bitrate}</td><td>{country}</td></tr>" msg += '</table>' # Full message as html table if len(msg) <= 5000: bot.send_msg(msg, text) # Shorten message if message too long (stage I) else: log.debug('Result too long stage I') msg = tr('rb_query_result') + ' (shortened L1)' msg += '\n<table><tr><th>!rbplay ID</th><th>Station Name</th></tr>' for s in rb_stations: station_id = s['stationuuid'] station_name = s['name'] msg += f'<tr><td>{station_id}</td><td>{station_name}</td>' msg += '</table>' if len(msg) <= 5000: bot.send_msg(msg, text) # Shorten message if message too long (stage II) else: log.debug('Result too long stage II') msg = tr('rb_query_result') + ' (shortened L2)' msg += '!rbplay ID - Station Name' for s in rb_stations: station_id = s['stationuuid'] station_name = s['name'][:12] msg += f'{station_id} - {station_name}' if len(msg) <= 5000: bot.send_msg(msg, text) # Message still too long else: bot.send_msg( 'Query result too long to post (> 5000 characters), please try another query.', text)
def match_station_name(phrase): """Takes the user utterance and attempts to match a specific station :param phrase: User utterance :type phrase: str :return: A tuple containing the original phrase, the CPS.MatchLevel, and a dictionary containing the resolved stream URL. :rtype: tuple """ numbers_regex = r"\b(one|two|three|four|five|six|seven|eight|nine)\b" try: rb = RadioBrowser() except Exception as e: LOG.exception("Failed to load pyradios" + repr(e)) LOG.info(f"Searching for {phrase}") results = rb.search(name=phrase) parsed = json.loads(json.dumps(results)) if len(parsed) > 0: # If an exatch match has been found return. LOG.info(f"Found {parsed[0]['name']} ({parsed[0]['url_resolved']})") return phrase, CPSMatchLevel.EXACT, {"url": parsed[0]["url_resolved"]} elif re.search(" [0-9]+ ", phrase): # If no match has been found, replace any digits (1,2,3) with text # (one, two, three) and repeat search. num = re.findall("[0-9]+", phrase) inf_eng = inflect.engine() for number in num: phrase = phrase.replace(num, inf_eng.number_to_words(number)) match_station_name(phrase) elif re.search(numbers_regex, phrase): # As above but reversed: change strings to ints and repeat search. num = re.findall(numbers_regex, phrase) for number in num: phrase = phrase.replace(number, str(w2n.word_to_num(number))) match_station_name(phrase) else: return None
class Handler: def __init__(self): self.API = None self.response = None self.target_station = None self.API = RadioBrowser() def station_validator(self): if len(self.response) == 0: log.error("No stations found by the name") sys.exit(0) if len(self.response) > 1: log.info("Multiple stations found by the name") stations_name = "" for station in self.response: # stations_name = stations_name + "," + station["name"] log.info("name: {} | id: {} | country: {}".format( station["name"], station["stationuuid"], station["country"])) log.info(stations_name) sys.exit(0) if len(self.response) == 1: log.info("Station found: {}".format(self.response[0]["name"])) log.debug(self.response[0]) self.target_station = self.response[0] self.API.click_counter(self.target_station["stationuuid"]) def play_by_station_name(self, _name=None): print(_name) self.response = self.API.search(name=_name, name_exact=False) self.station_validator() def play_by_station_uuid(self, _uuid): print(_uuid) # Pyradios by default don't let you search by uuid # a trick is to call click_counter(uuid) directly to get the statioon info is_ok = "false" try: self.target_station = self.API.click_counter(_uuid) log.debug(self.target_station) is_ok = self.target_station["ok"] except Exception as e: log.error("Could not find a station by the UUID") sys.exit(0) self.API.search(name=self.target_station["name"], name_exact=True) # againg register a valid click if is_ok == "false": res = self.API.click_counter(self.target_station["stationuuid"]) log.debug(res)
class Raspado_Radios(): def __init__(self): self.nombre_radios_pais = [] self.url_radios_pais = [] self.resultado_pais_busqueda_nombre = [] self.resultado_pais_busqueda_numero = [] self.resultado_pais_busqueda_abreviado = [] self.nombre_busqueda_general_radio = [] self.url_busqueda_general_radio = [] self.nombre_idioma = [] self.cantidad_idioma = [] self.busqueda_nombre_idioma = [] self.busqueda_cantidad_idioma = [] self.nombre_tag = [] self.cantidad_tag = [] self.busqueda_nombre_tag = [] self.busqueda_cantidad_tag = [] self.paises_radio_español = [] self.paises_radio_abreviado = [] self.paises_numero_emisoras = [] self.paises_numero_total_emisoras = "" self.rb = RadioBrowser() self.datos_pais = self.rb.countries() def Paises_Español(self): claves = Raspado_Radios.keys_only(diccionario) valores = Raspado_Radios.values_only(diccionario) for i in range(len(self.datos_pais)): self.paises_radio_abreviado.append(self.datos_pais[i]["name"]) for i in self.paises_radio_abreviado: try: indice = valores.index(i.upper()) self.paises_radio_español.append(claves[indice]) except: pass def Paises_Bandera(self): for i in range(len(self.datos_pais)): self.paises_radio_abreviado.append(self.datos_pais[i]["name"]) def Paises_Cantidad_Emisoras(self): for i in range(len(self.datos_pais)): self.paises_numero_emisoras.append( self.datos_pais[i]["stationcount"]) def Suma_Total_Emisoras_Paises(self): self.temporal = [] for i in range(len(self.datos_pais)): self.temporal.append(self.datos_pais[i]["stationcount"]) self.paises_numero_total_emisoras = 0 for i in self.temporal: self.paises_numero_total_emisoras = self.paises_numero_total_emisoras + i def Actualizar_Pais(self): self.paises_radio_español = [] self.paises_radio_abreviado = [] self.paises_numero_emisoras = [] self.paises_numero_total_emisoras = "" Raspado_Radios.Paises_Español(self) Raspado_Radios.Paises_Bandera(self) Raspado_Radios.Paises_Cantidad_Emisoras(self) Raspado_Radios.Suma_Total_Emisoras_Paises(self) def Buscar_Pais(self, valor): self.resultado_pais_busqueda_nombre = [] self.resultado_pais_busqueda_numero = [] self.resultado_pais_busqueda_abreviado = [] for item in self.paises_radio_español: if valor.lower() in item.lower(): self.resultado_pais_busqueda_nombre.append(item) for i in self.resultado_pais_busqueda_nombre: posicion = self.paises_radio_español.index(i) self.resultado_pais_busqueda_numero.append( self.paises_numero_emisoras[posicion]) self.resultado_pais_busqueda_abreviado.append( self.paises_radio_abreviado[posicion]) def Resultado_Paises(self, valor): datos_frame = self.rb.stations_by_countrycode(valor) self.nombre_radios_pais = [] self.url_radios_pais = [] for i in range(0, len(datos_frame)): self.nombre_radios_pais.append(datos_frame[i]["name"]) self.url_radios_pais.append(datos_frame[i]["url"]) def Buscar_Radio_General(self, valor, valor1=True): datos_frame = self.rb.search(name=valor, name_exact=valor1) self.nombre_busqueda_general_radio = [] self.url_busqueda_general_radio = [] for i in range(0, len(datos_frame)): self.nombre_busqueda_general_radio.append(datos_frame[i]["name"]) self.url_busqueda_general_radio.append(datos_frame[i]["url"]) def Resultado_Idioma(self): datos_lenguaje = self.rb.languages() self.nombre_idioma = [] self.cantidad_idioma = [] for i in range(len(datos_lenguaje)): self.nombre_idioma.append(datos_lenguaje[i]["name"]) self.cantidad_idioma.append(datos_lenguaje[i]["stationcount"]) def Buscar_Idioma(self, valor): datos_lenguaje = self.rb.languages() temp_name = [] temp_count = [] for i in range(len(datos_lenguaje)): temp_name.append(datos_lenguaje[i]["name"]) temp_count.append(datos_lenguaje[i]["stationcount"]) self.busqueda_nombre_idioma = [] self.busqueda_cantidad_idioma = [] for item in temp_name: if valor.lower() in item.lower(): self.busqueda_nombre_idioma.append(item) for i in self.busqueda_nombre_idioma: posicion = temp_name.index(i) self.busqueda_cantidad_idioma.append(temp_count[posicion]) def Resultado_Idioma_Global(self, valor): pandas_radio_lenguaje = self.rb.stations_by_language(valor) self.nombre_radios_pais = [] self.url_radios_pais = [] for i in range(0, len(pandas_radio_lenguaje)): self.nombre_radios_pais.append(pandas_radio_lenguaje[i]["name"]) self.url_radios_pais.append(pandas_radio_lenguaje[i]["url"]) def Resultado_Tag(self): datos_genero = self.rb.tags() self.nombre_tag = [] self.cantidad_tag = [] for i in range(len(datos_genero)): self.nombre_tag.append(datos_genero[i]["name"]) self.cantidad_tag.append(datos_genero[i]["stationcount"]) def Buscar_Tag(self, valor): datos_genero = self.rb.tags() temp_name = [] temp_count = [] for i in range(len(datos_genero)): temp_name.append(datos_genero[i]["name"]) temp_count.append(datos_genero[i]["stationcount"]) self.busqueda_nombre_tag = [] self.busqueda_cantidad_tag = [] for item in temp_name: if valor.lower() in item.lower(): self.busqueda_nombre_tag.append(item) for i in self.busqueda_nombre_tag: posicion = temp_name.index(i) self.busqueda_cantidad_tag.append(temp_count[posicion]) def Resultado_Tag_Global(self, valor): pandas_tag = self.rb.stations_by_tag(valor) self.nombre_radios_pais = [] self.url_radios_pais = [] for i in range(0, len(pandas_tag)): self.nombre_radios_pais.append(pandas_tag[i]["name"]) self.url_radios_pais.append(pandas_tag[i]["url"]) def saber_pais_conexion(self): url = 'http://ipinfo.io/json' response = urlopen(url) data = json.load(response) IP = data['ip'] org = data['org'] city = data['city'] country = data['country'] region = data['region'] return country def load_obj(name): with open(name, 'rb') as f: return pickle.load(f) def save_obj(obj, name): with open(name, 'wb') as f: pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL) def keys_only(flat_dict): return [k for k, v in flat_dict.items()] def values_only(flat_dict): return [v for k, v in flat_dict.items()]
from pyradios import RadioBrowser rb = RadioBrowser() def get_radio(radio_title): stantions = rb.stations_by_name(radio_title) if stantions == []: return {} stantion = sorted(stantions, key=lambda k: k['votes'], reverse=True)[0] return { "title": stantion['name'], "duration": "radio", "file": stantion['url_resolved'], "cover": stantion.get("favicon") }
def __init__(self): self.API = None self.response = None self.target_station = None self.API = RadioBrowser()
def rb(): return RadioBrowser(base_url=BASE_URL)
def init(self, settings, q): self.module_path = os.path.dirname(os.path.abspath(__file__)) try: lang = gettext.translation('pext_module_radio', localedir=os.path.join( self.module_path, 'locale'), languages=[settings['_locale']]) except FileNotFoundError: lang = gettext.NullTranslations() print("No {} translation available for pext_module_radio".format( settings['_locale'])) lang.install() self.rb = RadioBrowser() self.settings = settings self.q = q self.favourites = [] try: with open(os.path.join(self.module_path, "_user_favourites.txt"), "r") as favourites_file: for favourite in favourites_file: self.favourites.append(favourite.strip()) except IOError: pass self.cached = { 'countries': { 'time': 0 }, 'codecs': { 'time': 0 }, 'languages': { 'time': 0 }, 'tags': { 'time': 0 } } self.cachedStations = { '_favourites': { 'time': 0 }, 'countries': {}, 'codecs': {}, 'languages': {}, 'tags': {}, 'topvote': { 'time': 0 }, 'topclick': { 'time': 0 }, 'lastclick': { 'time': 0 }, 'lastchange': { 'time': 0 } } self.nowPlaying = None if not which("ffplay"): self.q.put([ Action.critical_error, _("ffplay is not installed, please install it.") ]) return self._get_entries()
class Module(ModuleBase): def init(self, settings, q): self.module_path = os.path.dirname(os.path.abspath(__file__)) try: lang = gettext.translation('pext_module_radio', localedir=os.path.join( self.module_path, 'locale'), languages=[settings['_locale']]) except FileNotFoundError: lang = gettext.NullTranslations() print("No {} translation available for pext_module_radio".format( settings['_locale'])) lang.install() self.rb = RadioBrowser() self.settings = settings self.q = q self.favourites = [] try: with open(os.path.join(self.module_path, "_user_favourites.txt"), "r") as favourites_file: for favourite in favourites_file: self.favourites.append(favourite.strip()) except IOError: pass self.cached = { 'countries': { 'time': 0 }, 'codecs': { 'time': 0 }, 'languages': { 'time': 0 }, 'tags': { 'time': 0 } } self.cachedStations = { '_favourites': { 'time': 0 }, 'countries': {}, 'codecs': {}, 'languages': {}, 'tags': {}, 'topvote': { 'time': 0 }, 'topclick': { 'time': 0 }, 'lastclick': { 'time': 0 }, 'lastchange': { 'time': 0 } } self.nowPlaying = None if not which("ffplay"): self.q.put([ Action.critical_error, _("ffplay is not installed, please install it.") ]) return self._get_entries() def _cache_expired(self, cache): return cache['time'] < time.time() - 600 def _entry_depth(self, text): if self._menu_to_type(text) in self.cached: return 2 else: return 1 def _menu_to_type(self, text): if text == _('Favourites'): return '_favourites' elif text == _('By Country'): return 'countries' elif text == _('By Codec'): return 'codecs' elif text == _('By Language'): return 'languages' elif text == _('By Tags'): return 'tags' elif text == _('By Votes'): return 'topvote' elif text == _('By Most Tune-Ins'): return 'topclick' elif text == _('By Most Recent Listener'): return 'lastclick' elif text == _('By Most Recent Change'): return 'lastchange' else: raise ValueError("Invalid text") def _get_stations_by_menu_type(self, search_type): if search_type == 'countries': return self.rb.countries() elif search_type == 'codecs': return self.rb.codecs() elif search_type == 'languages': return self.rb.languages() elif search_type == 'tags': return self.rb.tags() else: return self._search_stations_by_type(search_type) def _search_stations_by_type(self, search_type, search_term=None): if search_type == 'countries': return self.rb.stations_by_country(search_term, True) elif search_type == 'codecs': return self.rb.stations_by_codec(search_term, True) elif search_type == 'languages': return self.rb.stations_by_language(search_term, True) elif search_type == 'tags': return self.rb.stations_by_tag(search_term, True) elif search_type == 'topvote': return self.rb.stations(order='votes') elif search_type == 'topclick': return self.rb.stations(order='clickcount') elif search_type == 'lastclick': return self.rb.stations(order='clicktimestamp') elif search_type == 'lastchange': return self.rb.stations(order='lastchangetime') else: raise ValueError("Invalid type") def _get_entries(self): if self.favourites: self.q.put([Action.add_entry, _('Favourites')]) self.q.put([Action.add_entry, _('By Country')]) self.q.put([Action.add_entry, _('By Codec')]) self.q.put([Action.add_entry, _('By Language')]) self.q.put([Action.add_entry, _('By Tags')]) self.q.put([Action.add_entry, _('By Votes')]) self.q.put([Action.add_entry, _('By Most Tune-Ins')]) self.q.put([Action.add_entry, _('By Most Recent Listener')]) self.q.put([Action.add_entry, _('By Most Recent Change')]) if self.settings['_api_version'] < [0, 11, 0] and self.nowPlaying: if self.nowPlaying['process']: self.q.put([Action.add_command, _('mute')]) else: self.q.put([Action.add_command, _('unmute')]) self.q.put([Action.add_command, _('stop')]) self.q.put([Action.add_command, _('vote')]) def _get_list(self, path): self.q.put([Action.replace_entry_list, []]) if self._cache_expired(self.cached[path]): self.cached[path] = { 'time': time.time(), 'data': self._get_stations_by_menu_type(path) } for entry in self.cached[path]['data']: self.q.put([ Action.add_entry, _('{} ({} stations)').format(entry['name'], entry['stationcount']) ]) def _get_stations(self, search_type, search_term): if search_type == '_favourites': if self._cache_expired(self.cachedStations[search_type]): data = [] for favourite in self.favourites: station_data = self.rb.station_by_uuid(favourite) if station_data: data.append(station_data[0]) self.cachedStations[search_type] = { 'time': time.time(), 'data': data } return self.cachedStations[search_type] if search_term: if search_term not in self.cachedStations[ search_type] or self._cache_expired( self.cachedStations[search_type][search_term]): self.cachedStations[search_type][search_term] = { 'time': time.time(), 'data': self._search_stations_by_type(search_type, search_term) } return self.cachedStations[search_type][search_term] if self._cache_expired(self.cachedStations[search_type]): self.cachedStations[search_type] = { 'time': time.time(), 'data': self._search_stations_by_type(search_type) } return self.cachedStations[search_type] def _list_stations(self, search_type, search_term): self.q.put([Action.replace_entry_list, []]) cache = self._get_stations(search_type, search_term) for entry in cache['data']: self.q.put([Action.add_entry, entry['name']]) if self.settings['_api_version'] >= [0, 3, 1]: self.q.put([ Action.set_entry_info, entry['name'], _("<b>{}</b><br/><br/><b>Bitrate: </b>{} kbps<br/><b>Codec: </b>{}<br/><b>Language: </b>{}<br/><b>Location: </b>{}<br/><b>Tags: </b>{}<br/><b>Homepage: </b><a href='{}'>{}</a>" ).format( html.escape(entry['name']), html.escape(str(entry['bitrate'])), html.escape(entry['codec']), html.escape(entry['language']), "{}, {}".format(html.escape(entry['state']), html.escape(entry['country'])) if entry['state'] else html.escape(entry['country']), html.escape(", ".join(entry['tags'].split(",")) if entry['tags'] else "None"), html.escape(entry['homepage']), html.escape(entry['homepage'])) ]) if self.settings['_api_version'] >= [ 0, 6, 0 ] and search_type == '_favourites': self.q.put([ Action.set_entry_context, entry['name'], [_("Unfavourite")] ]) def _play_station(self, byType, searchTerm, stationName): self._stop_playing() if searchTerm: cache = self.cachedStations[byType][searchTerm] else: cache = self.cachedStations[byType] for station in cache['data']: if station['name'] == stationName: station_uuid = station['stationuuid'] station_info = station break response = self.rb.click_counter(station_uuid) if response['ok'] == 'false': self.q.put([Action.add_error, response['message']]) return False # TODO: Replace ffplay with something more easily scriptable that # preferably notifies us of song changes on the station. self.nowPlaying = { 'id': station_uuid, 'name': stationName, 'url': response['url'], 'process': None } if self.settings['_api_version'] >= [0, 6, 0]: self.q.put([ Action.set_base_info, _("<b>Tuned into:</b><br/>{}<br/><br/><b>Bitrate: </b>{} kbps<br/><b>Codec: </b>{}<br/><b>Language: </b>{}<br/><b>Location: </b>{}<br/><b>Tags: </b>{}<br/><b>Homepage: </b><a href='{}'>{}</a>" ).format( html.escape(station_info['name']), html.escape(str(station_info['bitrate'])), html.escape(station_info['codec']), html.escape(station_info['language']), "{}, {}".format(html.escape(station_info['state']), html.escape(station_info['country'])) if station_info['state'] else html.escape( station_info['country']), html.escape(", ".join(station_info['tags'].split(",")) if station_info['tags'] else "None"), html.escape(station_info['homepage']), html.escape(station_info['homepage'])) ]) self._toggle_mute() return True def _toggle_mute(self): """Toggle mute. While this function technically disconnects or connects to the station, instead of just muting, it is simpler code-wise and has the added benefit of saving bandwidth. TODO: Replace this with an actual mute function. """ if self.nowPlaying: if self.nowPlaying['process']: os.kill(self.nowPlaying['process'].pid, SIGTERM) self.nowPlaying['process'] = None self.q.put([ Action.set_header, _('Tuned into {} (muted)').format(self.nowPlaying['name']) ]) if self.settings['_api_version'] >= [0, 6, 0]: self.q.put([ Action.set_base_context, [_("Unmute"), _("Stop"), _("Favourite"), _("Vote up")] ]) else: self.q.put([ Action.set_header, _('Tuned into {}').format(self.nowPlaying['name']) ]) self.nowPlaying['process'] = Popen([ 'ffplay', '-nodisp', '-nostats', '-loglevel', '0', self.nowPlaying['url'] ]) if self.settings['_api_version'] >= [0, 6, 0]: self.q.put([ Action.set_base_context, [_("Mute"), _("Stop"), _("Favourite"), _("Vote up")] ]) def _stop_playing(self): if self.nowPlaying: if self.nowPlaying['process']: os.kill(self.nowPlaying['process'].pid, SIGTERM) self.nowPlaying = None self.q.put([Action.set_header]) if self.settings['_api_version'] >= [0, 6, 0]: self.q.put([Action.set_base_info]) self.q.put([Action.set_base_context]) def _add_to_favourites(self, station_id): with open(os.path.join(self.module_path, "_user_favourites.txt"), "a") as favourites_file: favourites_file.write('{}\n'.format(station_id)) self.favourites.append(station_id) self.cachedStations['_favourites'] = {'time': 0} def _remove_from_favourites(self, station_name): for station in self._get_stations('_favourites', '')['data']: if station['name'] == station_name: self.favourites.remove(station['stationuuid']) with open( os.path.join(self.module_path, "_user_favourites.txt"), "w") as favourites_file: for favourite in self.favourites: favourites_file.write('{}\n'.format(favourite)) self.cachedStations['_favourites'] = {'time': 0} return self.q.put([ Action.add_error, _('Could not find {} in favourites').format(station_name) ]) def _vote_station(self): result = self.rb.client.get('vote/{}'.format(self.nowPlaying['id'])) if result['ok']: self.q.put([ Action.add_message, _('Voted for station {}').format(self.nowPlaying['name']) ]) else: self.q.put([ Action.add_error, _('Failed to vote for {}: {}').format(self.nowPlaying['name'], result['message']) ]) def stop(self): self._stop_playing() def selection_made(self, selection): if self.settings['_api_version'] >= [ 0, 6, 0 ] and len(selection) > 0 and selection[-1]['context_option']: if selection[-1]['type'] == SelectionType.none: if selection[-1]['context_option'] in [_('Mute'), _('Unmute')]: self._toggle_mute() elif selection[-1]['context_option'] == _('Stop'): self._stop_playing() elif selection[-1]['context_option'] == _('Favourite'): self._add_to_favourites(self.nowPlaying['id']) elif selection[-1]['context_option'] == _('Vote up'): self._vote_station() elif selection[-1]['context_option'] == _("Unfavourite"): self._remove_from_favourites(selection[-1]['value']) if not self.favourites: self.q.put([Action.set_selection, []]) return self.q.put([Action.set_selection, selection[:-1]]) return self.q.put([Action.replace_command_list, []]) if len(selection) == 0: self.q.put([Action.replace_entry_list, []]) self._get_entries() elif len(selection) == 1: # Force station list when no subcategories if self._entry_depth(selection[0]['value']) == 1: self._list_stations(self._menu_to_type(selection[0]['value']), '') return menu_text = selection[0]['value'] self._get_list(self._menu_to_type(menu_text)) elif len(selection) == 2: # Force playing when no subcategories if self._entry_depth(selection[0]['value']) == 1: if self._play_station( self._menu_to_type(selection[0]['value']), '', selection[1]['value']): self.q.put([Action.close]) else: self.q.put([Action.set_selection, selection[:-1]]) return # Remove station count from search term search_term = selection[1]['value'][:selection[1]['value']. rfind('(')].rstrip() self._list_stations(self._menu_to_type(selection[0]['value']), search_term) elif len(selection) == 3: # Remove station count from search term search_term = selection[1]['value'][:selection[1]['value']. rfind('(')].rstrip() if self._play_station(self._menu_to_type(selection[0]['value']), search_term, selection[2]['value']): self.q.put([Action.close]) else: self.q.put([Action.set_selection, selection[:-1]]) else: self.q.put([ Action.critical_error, _('Unexpected selection_made value: {}').format(selection) ]) def process_response(self, response): pass
def rb(): _rb = RadioBrowser() return _rb
def rb(): _rb = RadioBrowser() _rb.base_url = BASE_URL return _rb