Exemple #1
0
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()]
Exemple #2
0
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