Exemple #1
0
    def __get_data(self, item, global_filter_lang_id):

        dict_filtered_shows = filetools.get_node_from_data_json(item.channel, TAG_TVSHOW_FILTER)
        tvshow = item.show.lower().strip()

        global_filter_language = config.get_setting(global_filter_lang_id, item.channel)

        if tvshow in dict_filtered_shows.keys():

            self.result = ResultFilter({TAG_ACTIVE: dict_filtered_shows[tvshow][TAG_ACTIVE],
                                        TAG_LANGUAGE: dict_filtered_shows[tvshow][TAG_LANGUAGE],
                                        TAG_QUALITY_ALLOWED: dict_filtered_shows[tvshow][TAG_QUALITY_ALLOWED]})

        # opcion general "no filtrar"
        elif global_filter_language != 0:
            from core import channeltools
            list_controls, dict_settings = channeltools.get_channel_controls_settings(item.channel)

            for control in list_controls:
                if control["id"] == global_filter_lang_id:

                    try:
                        language = control["lvalues"][global_filter_language]
                        # logger.debug("language %s" % language)
                    except:
                        logger.error("No se ha encontrado el valor asociado al codigo '%s': %s" %
                                     (global_filter_lang_id, global_filter_language))
                        break

                    self.result = ResultFilter({TAG_ACTIVE: True, TAG_LANGUAGE: language, TAG_QUALITY_ALLOWED: []})
                    break
Exemple #2
0
    def __get_data(self, item, global_filter_lang_id):

        dict_filtered_shows = jsontools.get_node_from_file(item.channel, TAG_TVSHOW_FILTER)
        tvshow = item.show.lower().strip()

        global_filter_language = config.get_setting(global_filter_lang_id, item.channel)

        if tvshow in list(dict_filtered_shows.keys()):

            self.result = ResultFilter({TAG_ACTIVE: dict_filtered_shows[tvshow][TAG_ACTIVE],
                                        TAG_LANGUAGE: dict_filtered_shows[tvshow][TAG_LANGUAGE],
                                        TAG_QUALITY_ALLOWED: dict_filtered_shows[tvshow][TAG_QUALITY_ALLOWED]})

        # general option "do not filter"
        elif global_filter_language != 0:
            from core import channeltools
            list_controls, dict_settings = channeltools.get_channel_controls_settings(item.channel)

            for control in list_controls:
                if control["id"] == global_filter_lang_id:

                    try:
                        language = control["lvalues"][global_filter_language]
                        # logger.debug("language %s" % language)
                    except:
                        logger.error("The value associated with the code was not found '%s': %s" % (global_filter_lang_id, global_filter_language))
                        break

                    self.result = ResultFilter({TAG_ACTIVE: True, TAG_LANGUAGE: language, TAG_QUALITY_ALLOWED: []})
                    break
Exemple #3
0
    def start(self, list_controls=None, dict_values=None, title="Opciones", callback=None, item=None,
              custom_button=None, channelpath = None):
        logger.info("[xbmc_config_menu] start")

        # Ruta para las imagenes de la ventana
        self.mediapath = os.path.join(config.get_runtime_path(), 'resources', 'skins', 'Default', 'media')

        # Capturamos los parametros
        self.list_controls = list_controls
        self.values = dict_values
        self.title = title
        self.callback = callback
        self.item = item
        
        
        if type(custom_button) == dict:
          self.custom_button = {} 
          self.custom_button["label"] = custom_button.get("label", "")
          self.custom_button["function"] = custom_button.get("function", "")
          self.custom_button["visible"] = bool(custom_button.get("visible", True))
          self.custom_button["close"] = bool(custom_button.get("close", False))
        else:
          self.custom_button = None
          

        # Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal
        if not channelpath:
          channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename
        self.channel = os.path.basename(channelpath).replace(".py", "")

        # Si no tenemos list_controls, hay que sacarlos del xml del canal
        if not self.list_controls:

            # Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
            if os.path.join(config.get_runtime_path(), "channels") in channelpath:

                # La llamada se hace desde un canal
                self.list_controls, default_values = channeltools.get_channel_controls_settings(self.channel)

            # En caso contrario salimos
            else:
                return None

        # Si no se pasan dict_values, creamos un dict en blanco
        if self.values is None:
            self.values = {}

        # Ponemos el titulo
        if self.title == "":
            self.title = str(config.get_localized_string(30100)) + " -- " + self.channel.capitalize()

        elif self.title.startswith('@') and unicode(self.title[1:]).isnumeric():
            self.title = config.get_localized_string(int(self.title[1:]))

        # Muestra la ventana
        self.return_value = None
        self.doModal()
        return self.return_value
    def start(self, list_controls=None, dict_values=None, title="Opciones", callback=None, item=None,
              custom_button=None, channelpath = None):
        logger.info("[xbmc_config_menu] start")

        # Ruta para las imagenes de la ventana
        self.mediapath = os.path.join(config.get_runtime_path(), 'resources', 'skins', 'Default', 'media')

        # Capturamos los parametros
        self.list_controls = list_controls
        self.values = dict_values
        self.title = title
        self.callback = callback
        self.item = item
        
        
        if type(custom_button) == dict:
          self.custom_button = {} 
          self.custom_button["label"] = custom_button.get("label", "")
          self.custom_button["function"] = custom_button.get("function", "")
          self.custom_button["visible"] = bool(custom_button.get("visible", True))
          self.custom_button["close"] = bool(custom_button.get("close", False))
        else:
          self.custom_button = None
          

        # Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal
        if not channelpath:
          channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename
        self.channel = os.path.basename(channelpath).replace(".py", "")

        # Si no tenemos list_controls, hay que sacarlos del xml del canal
        if not self.list_controls:

            # Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
            if os.path.join(config.get_runtime_path(), "channels") in channelpath:

                # La llamada se hace desde un canal
                self.list_controls, default_values = channeltools.get_channel_controls_settings(self.channel)

            # En caso contrario salimos
            else:
                return None

        # Si no se pasan dict_values, creamos un dict en blanco
        if self.values is None:
            self.values = {}

        # Ponemos el titulo
        if self.title == "":
            self.title = str(config.get_localized_string(30100)) + " -- " + self.channel.capitalize()

        elif self.title.startswith('@') and unicode(self.title[1:]).isnumeric():
            self.title = config.get_localized_string(int(self.title[1:]))

        # Muestra la ventana
        self.return_value = None
        self.doModal()
        return self.return_value
def get_channel_setting(name, channel):
    """
    Retorna el valor de configuracion del parametro solicitado.

    Devuelve el valor del parametro 'name' en la configuracion propia del canal 'channel'.

    Si se especifica el nombre del canal busca en la ruta \addon_data\plugin.video.pelisalacarta\settings_channels el archivo channel_data.json
    y lee el valor del parametro 'name'. Si el archivo channel_data.json no existe busca en la carpeta channels el archivo
    channel.xml y crea un archivo channel_data.json antes de retornar el valor solicitado.

    Parametros:
    name -- nombre del parametro
    channel [ -- nombre del canal

    Retorna:
    value -- El valor del parametro 'name'

    """
    #Creamos la carpeta si no existe
    if not os.path.exists(os.path.join(config.get_data_path(), "settings_channels")):
      os.mkdir(os.path.join(config.get_data_path(), "settings_channels"))

    file_settings= os.path.join(config.get_data_path(), "settings_channels", channel+"_data.json")
    dict_settings ={}

    if os.path.exists(file_settings):
        # Obtenemos configuracion guardada de ../settings/channel_data.json
        try:
            dict_file = jsontools.load_json(open(file_settings, "r").read())
            if isinstance(dict_file, dict) and dict_file.has_key('settings'):
              dict_settings = dict_file['settings']
        except EnvironmentError:
            logger.info("ERROR al leer el archivo: {0}".format(file_settings))

    if len(dict_settings) == 0 or not dict_settings.has_key(name):
        # Obtenemos controles del archivo ../channels/channel.xml
        from core import channeltools
        try:
          list_controls, default_settings = channeltools.get_channel_controls_settings(channel)
        except:
          default_settings = {}
        if  default_settings.has_key(name): # Si el parametro existe en el channel.xml creamos el channel_data.json
            default_settings.update(dict_settings)
            dict_settings = default_settings
            dict_file = {}
            dict_file['settings']= dict_settings
            # Creamos el archivo ../settings/channel_data.json
            json_data = jsontools.dump_json(dict_file).encode("utf-8")
            try:
                open(file_settings, "w").write(json_data)
            except EnvironmentError:
                logger.info("[config.py] ERROR al salvar el archivo: {0}".format(file_settings))

    # Devolvemos el valor del parametro local 'name' si existe
    if dict_settings.has_key(name):
      return dict_settings[name]
    else:
      return None
Exemple #6
0
def get_languages(channel):
    '''
    Obtiene los idiomas desde el xml del canal

    :param channel: str
    :return: list
    '''
    logger.info()
    list_language =['No filtrar']
    list_controls, dict_settings = channeltools.get_channel_controls_settings(channel)
    for control in list_controls:
        if control["id"] == 'filter_languages':
            list_language = control["lvalues"]

    return list_language
Exemple #7
0
def conf_tools(item):
    logger.info()

    # Activar o desactivar canales
    if item.extra == "channels_onoff":
        if config.get_platform(
                True
        )['num_version'] >= 17.0:  # A partir de Kodi 16 se puede usar multiselect, y de 17 con preselect
            return channels_onoff(item)

        import channelselector
        from core import channeltools

        channel_list = channelselector.filterchannels("allchannelstatus")

        excluded_channels = [
            'url',
            'search',
            'videolibrary',
            'setting',
            'news',
            # 'help',
            'downloads'
        ]

        list_controls = []
        try:
            list_controls.append({
                'id':
                "all_channels",
                'type':
                "list",
                'label':
                config.get_localized_string(60594),
                'default':
                0,
                'enabled':
                True,
                'visible':
                True,
                'lvalues': [
                    '',
                    config.get_localized_string(60591),
                    config.get_localized_string(60592),
                    config.get_localized_string(60593)
                ]
            })

            for channel in channel_list:
                # Si el canal esta en la lista de exclusiones lo saltamos
                if channel.channel not in excluded_channels:

                    channel_parameters = channeltools.get_channel_parameters(
                        channel.channel)

                    status_control = ""
                    status = config.get_setting("enabled", channel.channel)
                    # si status no existe es que NO HAY valor en _data.json
                    if status is None:
                        status = channel_parameters["active"]
                        logger.debug("%s | Status (XML): %s" %
                                     (channel.channel, status))
                        if not status:
                            status_control = config.get_localized_string(60595)
                    else:
                        logger.debug("%s  | Status: %s" %
                                     (channel.channel, status))

                    control = {
                        'id': channel.channel,
                        'type': "bool",
                        'label': channel_parameters["title"] + status_control,
                        'default': status,
                        'enabled': True,
                        'visible': True
                    }
                    list_controls.append(control)

                else:
                    continue

        except:
            import traceback
            logger.error("Error: %s" % traceback.format_exc())
        else:
            return platformtools.show_channel_settings(
                list_controls=list_controls,
                item=item.clone(channel_list=channel_list),
                caption=config.get_localized_string(60596),
                callback="channel_status",
                custom_button={"visible": False})

    # Comprobacion de archivos channel_data.json
    elif item.extra == "lib_check_datajson":
        itemlist = []
        import channelselector
        from core import channeltools
        channel_list = channelselector.filterchannels("allchannelstatus")

        # Tener una lista de exclusion no tiene mucho sentido por que se comprueba si channel.json tiene "settings",
        # pero por si acaso se deja
        excluded_channels = ['url', 'setting', 'help']

        try:
            import os
            from core import jsontools
            for channel in channel_list:

                list_status = None
                default_settings = None

                # Se comprueba si el canal esta en la lista de exclusiones
                if channel.channel not in excluded_channels:
                    # Se comprueba que tenga "settings", sino se salta
                    list_controls, dict_settings = channeltools.get_channel_controls_settings(
                        channel.channel)

                    if not list_controls:
                        itemlist.append(
                            Item(channel=CHANNELNAME,
                                 title=channel.title +
                                 config.get_localized_string(60569),
                                 action="",
                                 folder=False,
                                 thumbnail=channel.thumbnail))
                        continue
                        # logger.info(channel.channel + " SALTADO!")

                    # Se cargan los ajustes del archivo json del canal
                    file_settings = os.path.join(
                        config.get_data_path(), "settings_channels",
                        channel.channel + "_data.json")
                    dict_settings = {}
                    dict_file = {}
                    if filetools.exists(file_settings):
                        # logger.info(channel.channel + " Tiene archivo _data.json")
                        channeljson_exists = True
                        # Obtenemos configuracion guardada de ../settings/channel_data.json
                        try:
                            dict_file = jsontools.load(
                                open(file_settings, "rb").read())
                            if isinstance(dict_file,
                                          dict) and 'settings' in dict_file:
                                dict_settings = dict_file['settings']
                        except EnvironmentError:
                            logger.error("ERROR al leer el archivo: %s" %
                                         file_settings)
                    else:
                        # logger.info(channel.channel + " No tiene archivo _data.json")
                        channeljson_exists = False

                    if channeljson_exists:
                        try:
                            datajson_size = filetools.getsize(file_settings)
                        except:
                            import traceback
                            logger.error(channel.title +
                                         config.get_localized_string(60570) %
                                         traceback.format_exc())
                    else:
                        datajson_size = None

                    # Si el _data.json esta vacio o no existe...
                    if (len(dict_settings)
                            and datajson_size) == 0 or not channeljson_exists:
                        # Obtenemos controles del archivo ../channels/channel.json
                        needsfix = True
                        try:
                            # Se cargan los ajustes por defecto
                            list_controls, default_settings = channeltools.get_channel_controls_settings(
                                channel.channel)
                            # logger.info(channel.title + " | Default: %s" % default_settings)
                        except:
                            import traceback
                            logger.error(channel.title +
                                         config.get_localized_string(60570) %
                                         traceback.format_exc())
                            # default_settings = {}

                        # Si _data.json necesita ser reparado o no existe...
                        if needsfix or not channeljson_exists:
                            if default_settings is not None:
                                # Creamos el channel_data.json
                                default_settings.update(dict_settings)
                                dict_settings = default_settings
                                dict_file['settings'] = dict_settings
                                # Creamos el archivo ../settings/channel_data.json
                                json_data = jsontools.dump(dict_file)
                                try:
                                    open(file_settings, "wb").write(json_data)
                                    # logger.info(channel.channel + " - Archivo _data.json GUARDADO!")
                                    # El channel_data.json se ha creado/modificado
                                    list_status = config.get_localized_string(
                                        60560)
                                except EnvironmentError:
                                    logger.error(
                                        "ERROR al salvar el archivo: %s" %
                                        file_settings)
                            else:
                                if default_settings is None:
                                    list_status = config.get_localized_string(
                                        60571)

                    else:
                        # logger.info(channel.channel + " - NO necesita correccion!")
                        needsfix = False

                    # Si se ha establecido el estado del canal se añade a la lista
                    if needsfix is not None:
                        if needsfix:
                            if not channeljson_exists:
                                list_status = config.get_localized_string(
                                    60588)
                                list_colour = "red"
                            else:
                                list_status = config.get_localized_string(
                                    60589)
                                list_colour = "green"
                        else:
                            # Si "needsfix" es "false" y "datjson_size" es None habra
                            # ocurrido algun error
                            if datajson_size is None:
                                list_status = config.get_localized_string(
                                    60590)
                                list_colour = "red"
                            else:
                                list_status = config.get_localized_string(
                                    60589)
                                list_colour = "green"

                    if list_status is not None:
                        itemlist.append(
                            Item(channel=CHANNELNAME,
                                 title=channel.title + list_status,
                                 action="",
                                 folder=False,
                                 thumbnail=channel.thumbnail,
                                 text_color=list_colour))
                    else:
                        logger.error("Algo va mal con el canal %s" %
                                     channel.channel)

                # Si el canal esta en la lista de exclusiones lo saltamos
                else:
                    continue
        except:
            import traceback
            logger.error("Error: %s" % traceback.format_exc())

        return itemlist
Exemple #8
0
def conf_tools(item):
    logger.info()

    # Activar o desactivar canales
    if item.extra == "channels_onoff":
        import channelselector
        from core import channeltools

        channel_list = channelselector.filterchannels("allchannelstatus")

        excluded_channels = ['tengourl',
                             'buscador',
                             'biblioteca',
                             'configuracion',
                             'novedades',
                             'personal',
                             'ayuda',
                             'descargas']

        list_controls = []
        try:
            list_controls.append({'id': "all_channels",
                                  'type': "list",
                                  'label': "Todos los canales",
                                  'default': 0,
                                  'enabled': True,
                                  'visible': True,
                                  'lvalues': ['',
                                              'Activar todos',
                                              'Desactivar todos',
                                              'Establecer estado por defecto']})

            for channel in channel_list:
                # Si el canal esta en la lista de exclusiones lo saltamos
                if channel.channel not in excluded_channels:

                    channel_parameters = channeltools.get_channel_parameters(channel.channel)

                    status_control = ""
                    status = config.get_setting("enabled", channel.channel)
                    # si status no existe es que NO HAY valor en _data.json
                    if status is None:
                        status = channel_parameters["active"]
                        logger.debug("%s | Status (XML): %s" % (channel.channel, status))
                        if not status:
                            status_control = " [COLOR grey](Desactivado por defecto)[/COLOR]"
                    else:
                        logger.debug("%s  | Status: %s" % (channel.channel, status))

                    control = {'id': channel.channel,
                               'type': "bool",
                               'label': channel_parameters["title"] + status_control,
                               'default': status,
                               'enabled': True,
                               'visible': True}
                    list_controls.append(control)

                else:
                    continue

        except:
            import traceback
            logger.error("Error: %s" % traceback.format_exc())
        else:
            return platformtools.show_channel_settings(list_controls=list_controls,
                                                       item=item.clone(channel_list=channel_list),
                                                       caption="Canales",
                                                       callback="channel_status",
                                                       custom_button={"visible": False})

    # Comprobacion de archivos channel_data.json
    elif item.extra == "lib_check_datajson":
        itemlist = []
        import channelselector
        from core import channeltools
        channel_list = channelselector.filterchannels("allchannelstatus")

        # Tener una lista de exclusion no tiene mucho sentido por que se comprueba si
        # el xml tiene "settings", pero por si acaso se deja
        excluded_channels = ['tengourl',
                             'configuracion',
                             'personal',
                             'ayuda']

        try:
            import os
            from core import jsontools
            for channel in channel_list:

                list_status = None
                default_settings = None

                # Se comprueba si el canal esta en la lista de exclusiones
                if channel.channel not in excluded_channels:
                    # Se comprueba que tenga "settings", sino se salta
                    jsonchannel = channeltools.get_channel_json(channel.channel)
                    if not jsonchannel.get("settings"):
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + " - No tiene ajustes por defecto",
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail))
                        continue
                        # logger.info(channel.channel + " SALTADO!")

                    # Se cargan los ajustes del archivo json del canal
                    file_settings = os.path.join(config.get_data_path(), "settings_channels",
                                                 channel.channel + "_data.json")
                    dict_settings = {}
                    dict_file = {}
                    if filetools.exists(file_settings):
                        # logger.info(channel.channel + " Tiene archivo _data.json")
                        channeljson_exists = True
                        # Obtenemos configuracion guardada de ../settings/channel_data.json
                        try:
                            dict_file = jsontools.load_json(open(file_settings, "rb").read())
                            if isinstance(dict_file, dict) and 'settings' in dict_file:
                                dict_settings = dict_file['settings']
                        except EnvironmentError:
                            logger.error("ERROR al leer el archivo: %s" % file_settings)
                    else:
                        # logger.info(channel.channel + " No tiene archivo _data.json")
                        channeljson_exists = False

                    if channeljson_exists == True:
                        try:
                            datajson_size = filetools.getsize(file_settings)
                        except:
                            import traceback
                            logger.error(channel.title + " | Detalle del error: %s" % traceback.format_exc())
                    else:
                        datajson_size = None

                    # Si el _data.json esta vacio o no existe...
                    if (len(dict_settings) and datajson_size) == 0 or channeljson_exists == False:
                        # Obtenemos controles del archivo ../channels/channel.xml
                        needsfix = True
                        try:
                            # Se cargan los ajustes por defecto
                            list_controls, default_settings = channeltools.get_channel_controls_settings(channel.channel)
                            # logger.info(channel.title + " | Default: %s" % default_settings)
                        except:
                            import traceback
                            logger.error(channel.title + " | Detalle del error: %s" % traceback.format_exc())
                            # default_settings = {}

                        # Si _data.json necesita ser reparado o no existe...
                        if needsfix == True or channeljson_exists == False:
                            if default_settings is not None:
                                # Creamos el channel_data.json
                                default_settings.update(dict_settings)
                                dict_settings = default_settings
                                dict_file['settings'] = dict_settings
                                # Creamos el archivo ../settings/channel_data.json
                                json_data = jsontools.dump_json(dict_file)
                                try:
                                    open(file_settings, "wb").write(json_data)
                                    # logger.info(channel.channel + " - Archivo _data.json GUARDADO!")
                                    # El channel_data.json se ha creado/modificado
                                    list_status = " - [COLOR red] CORREGIDO!![/COLOR]"
                                except EnvironmentError:
                                    logger.error("ERROR al salvar el archivo: %s" % file_settings)
                            else:
                                if default_settings is None:
                                    list_status = " - [COLOR red] Imposible cargar los ajustes por defecto![/COLOR]"

                    else:
                        # logger.info(channel.channel + " - NO necesita correccion!")
                        needsfix = False

                    # Si se ha establecido el estado del canal se añade a la lista
                    if needsfix is not None:
                        if needsfix == True:
                            if channeljson_exists == False:
                                list_status = " - Ajustes creados"
                                list_colour = "red"
                            else:
                                list_status = " - No necesita corrección"
                                list_colour = "green"
                        else:
                            # Si "needsfix" es "false" y "datjson_size" es None habra
                            # ocurrido algun error
                            if datajson_size is None:
                                list_status = " - Ha ocurrido algun error"
                                list_colour = "red"
                            else:
                                list_status = " - No necesita corrección"
                                list_colour = "green"

                    if list_status is not None:
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + list_status,
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail,
                                             text_color=list_colour))
                    else:
                        logger.error("Algo va mal con el canal %s" % channel.channel)

                # Si el canal esta en la lista de exclusiones lo saltamos
                else:
                    continue
        except:
            import traceback
            logger.error("Error: %s" % traceback.format_exc())

        return itemlist
Exemple #9
0
def setting_channel_new(item):
    import xbmcgui

    # Cargar lista de opciones (canales activos del usuario y que permitan búsqueda global)
    # ------------------------
    lista = []
    ids = []
    lista_lang = []
    lista_ctgs = []
    channels_list = channelselector.filterchannels('all')
    for channel in channels_list:
        if channel.action == '':
            continue

        channel_parameters = channeltools.get_channel_parameters(
            channel.channel)

        # No incluir si en la configuracion del canal no existe "include_in_global_search"
        if not channel_parameters['include_in_global_search']:
            continue

        lbl = '%s' % channel_parameters['language']
        lbl += ' %s' % ', '.join(
            config.get_localized_category(categ)
            for categ in channel_parameters['categories'])

        it = xbmcgui.ListItem(channel.title, lbl)
        it.setArt({'thumb': channel.thumbnail, 'fanart': channel.fanart})
        lista.append(it)
        ids.append(channel.channel)
        lista_lang.append(channel_parameters['language'])
        lista_ctgs.append(channel_parameters['categories'])

    # Diálogo para pre-seleccionar
    # ----------------------------
    preselecciones = [
        'Buscar con la selección actual', 'Modificar selección actual',
        'Modificar partiendo de Recomendados',
        'Modificar partiendo de Frecuentes', 'Modificar partiendo de Todos',
        'Modificar partiendo de Ninguno', 'Modificar partiendo de Castellano',
        'Modificar partiendo de Latino'
    ]
    presel_values = [
        'skip', 'actual', 'recom', 'freq', 'all', 'none', 'cast', 'lat'
    ]

    categs = [
        'movie', 'tvshow', 'documentary', 'anime', 'vos', 'direct', 'torrent'
    ]
    if config.get_setting('adult_mode') > 0:
        categs.append('adult')
    for c in categs:
        preselecciones.append('Modificar partiendo de %s' %
                              config.get_localized_category(c))
        presel_values.append(c)

    if item.action == 'setting_channel':  # Configuración de los canales incluídos en la búsqueda
        del preselecciones[0]
        del presel_values[0]
    # else: # Llamada desde "buscar en otros canales" (se puede saltar la selección e ir directo a la búsqueda)

    ret = platformtools.dialog_select(config.get_localized_string(59994),
                                      preselecciones)
    if ret == -1:
        return False  # pedido cancel
    if presel_values[ret] == 'skip':
        return True  # continuar sin modificar
    elif presel_values[ret] == 'none':
        preselect = []
    elif presel_values[ret] == 'all':
        preselect = range(len(ids))
    elif presel_values[ret] in ['cast', 'lat']:
        preselect = []
        for i, lg in enumerate(lista_lang):
            if presel_values[ret] in lg or '*' in lg:
                preselect.append(i)
    elif presel_values[ret] == 'actual':
        preselect = []
        for i, canal in enumerate(ids):
            channel_status = config.get_setting('include_in_global_search',
                                                canal)
            if channel_status:
                preselect.append(i)

    elif presel_values[ret] == 'recom':
        preselect = []
        for i, canal in enumerate(ids):
            _not, set_canal_list = channeltools.get_channel_controls_settings(
                canal)
            if set_canal_list.get('include_in_global_search', False):
                preselect.append(i)

    elif presel_values[ret] == 'freq':
        preselect = []
        for i, canal in enumerate(ids):
            frequency = channeltools.get_channel_setting('frequency', canal, 0)
            if frequency > 0:
                preselect.append(i)
    else:
        preselect = []
        for i, ctgs in enumerate(lista_ctgs):
            if presel_values[ret] in ctgs:
                preselect.append(i)

    # Diálogo para seleccionar
    # ------------------------
    ret = xbmcgui.Dialog().multiselect(config.get_localized_string(59994),
                                       lista,
                                       preselect=preselect,
                                       useDetails=True)
    if not ret:
        return False  # pedido cancel
    seleccionados = [ids[i] for i in ret]

    # Guardar cambios en canales para la búsqueda
    # -------------------------------------------
    for canal in ids:
        channel_status = config.get_setting('include_in_global_search', canal)
        # if not channel_status:
        #     channel_status = True

        if channel_status and canal not in seleccionados:
            config.set_setting('include_in_global_search', False, canal)
        elif not channel_status and canal in seleccionados:
            config.set_setting('include_in_global_search', True, canal)

    return True
Exemple #10
0
def setting_channel_new(item):
    import xbmcgui

    # Load list of options (active user channels that allow global search)
    lista = []
    ids = []
    lista_lang = []
    lista_ctgs = []
    channels_list = channelselector.filterchannels('all')
    for channel in channels_list:
        if channel.action == '':
            continue

        channel_parameters = channeltools.get_channel_parameters(channel.channel)

        # Do not include if "include_in_global_search" does not exist in the channel configuration
        if not channel_parameters['include_in_global_search']:
            continue

        lbl = '%s' % channel_parameters['language']
        lbl += ' %s' % ', '.join(config.get_localized_category(categ) for categ in channel_parameters['categories'])

        it = xbmcgui.ListItem(channel.title, lbl)
        it.setArt({'thumb': channel.thumbnail, 'fanart': channel.fanart})
        lista.append(it)
        ids.append(channel.channel)
        lista_lang.append(channel_parameters['language'])
        lista_ctgs.append(channel_parameters['categories'])

    # Pre-select dialog
    preselecciones = [
        config.get_localized_string(70570),
        config.get_localized_string(70571),
        # 'Modificar partiendo de Recomendados',
        # 'Modificar partiendo de Frecuentes',
        config.get_localized_string(70572),
        config.get_localized_string(70573),
        # 'Modificar partiendo de Castellano',
        # 'Modificar partiendo de Latino'
    ]
    # presel_values = ['skip', 'actual', 'recom', 'freq', 'all', 'none', 'cast', 'lat']
    presel_values = ['skip', 'actual', 'all', 'none']

    categs = ['movie', 'tvshow', 'documentary', 'anime', 'vos', 'direct', 'torrent']
    for c in categs:
        preselecciones.append(config.get_localized_string(70577) + config.get_localized_category(c))
        presel_values.append(c)

    if item.action == 'setting_channel':  # Configuración de los canales incluídos en la búsqueda
        del preselecciones[0]
        del presel_values[0]
    # else: # Call from "search on other channels" (you can skip the selection and go directly to the search)

    ret = platformtools.dialog_select(config.get_localized_string(59994), preselecciones)
    if ret == -1:
        return False  # order cancel
    if presel_values[ret] == 'skip':
        return True  # continue unmodified
    elif presel_values[ret] == 'none':
        preselect = []
    elif presel_values[ret] == 'all':
        preselect = list(range(len(ids)))
    elif presel_values[ret] in ['cast', 'lat']:
        preselect = []
        for i, lg in enumerate(lista_lang):
            if presel_values[ret] in lg or '*' in lg:
                preselect.append(i)
    elif presel_values[ret] == 'actual':
        preselect = []
        for i, canal in enumerate(ids):
            channel_status = config.get_setting('include_in_global_search', canal)
            if channel_status:
                preselect.append(i)

    elif presel_values[ret] == 'recom':
        preselect = []
        for i, canal in enumerate(ids):
            _not, set_canal_list = channeltools.get_channel_controls_settings(canal)
            if set_canal_list.get('include_in_global_search', False):
                preselect.append(i)

    elif presel_values[ret] == 'freq':
        preselect = []
        for i, canal in enumerate(ids):
            frequency = channeltools.get_channel_setting('frequency', canal, 0)
            if frequency > 0:
                preselect.append(i)
    else:
        preselect = []
        for i, ctgs in enumerate(lista_ctgs):
            if presel_values[ret] in ctgs:
                preselect.append(i)

    # Dialog to select
    ret = platformtools.dialog_multiselect(config.get_localized_string(59994), lista, preselect=preselect, useDetails=True)

    if ret == None: return False  # order cancel
    seleccionados = [ids[i] for i in ret]

    # Save changes to search channels
    for canal in ids:
        channel_status = config.get_setting('include_in_global_search', canal)
        # if not channel_status:
        #     channel_status = True

        if channel_status and canal not in seleccionados:
            config.set_setting('include_in_global_search', False, canal)
        elif not channel_status and canal in seleccionados:
            config.set_setting('include_in_global_search', True, canal)

    return True
Exemple #11
0
    def show_channel_settings(self,
                              list_controls=None,
                              dict_values=None,
                              caption="",
                              callback=None,
                              item=None,
                              custom_button=None,
                              channelpath=None):
        from core import config
        from core import channeltools
        import inspect
        if not os.path.isdir(
                os.path.join(config.get_data_path(), "settings_channels")):
            os.mkdir(os.path.join(config.get_data_path(), "settings_channels"))

        title = caption

        if type(custom_button) == dict:
            custom_button = {
                "label": custom_button.get("label", ""),
                "function": custom_button.get("function", ""),
                "visible": bool(custom_button.get("visible", True)),
                "close": bool(custom_button.get("close", False))
            }

        else:
            custom_button = None

        #Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal
        if not channelpath:
            channelpath = inspect.currentframe(
            ).f_back.f_back.f_code.co_filename
        channelname = os.path.basename(channelpath).replace(".py", "")

        #Si no tenemos list_controls, hay que sacarlos del xml del canal
        if not list_controls:

            #Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
            if os.path.join(config.get_runtime_path(),
                            "channels") in channelpath:

                # La llamada se hace desde un canal
                list_controls, default_values = channeltools.get_channel_controls_settings(
                    channelname)

            #En caso contrario salimos
            else:
                return None

        #Si no se pasan dict_values, creamos un dict en blanco
        if dict_values == None:
            dict_values = {}

        #Ponemos el titulo
        if caption == "":
            caption = str(config.get_localized_string(
                30100)) + " -- " + channelname.capitalize()
        elif caption.startswith('@') and unicode(caption[1:]).isnumeric():
            caption = config.get_localized_string(int(caption[1:]))

        JsonData = {}
        JsonData["action"] = "OpenConfig"
        JsonData["data"] = {}
        JsonData["data"]["title"] = caption
        JsonData["data"]["custom_button"] = custom_button
        JsonData["data"]["items"] = []

        # Añadir controles
        for c in list_controls:
            if not "default" in c: c["default"] = ""
            if not "color" in c: c["color"] = "auto"
            if not "label" in c: continue

            #Obtenemos el valor
            if not c["id"] in dict_values:
                if not callback:
                    c["value"] = config.get_setting(c["id"], channelname)
                else:
                    c["value"] = c["default"]

            # Translation
            if c['label'].startswith('@') and unicode(
                    c['label'][1:]).isnumeric():
                c['label'] = str(config.get_localized_string(c['label'][1:]))
            if c["label"].endswith(":"): c["label"] = c["label"][:-1]

            if c['type'] == 'list':
                lvalues = []
                for li in c['lvalues']:
                    if li.startswith('@') and unicode(li[1:]).isnumeric():
                        lvalues.append(str(config.get_localized_string(
                            li[1:])))
                    else:
                        lvalues.append(li)
                c['lvalues'] = lvalues

            JsonData["data"]["items"].append(c)

        ID = self.send_message(JsonData)
        close = False

        while True:
            data = self.get_data(ID)
            if type(data) == dict:
                JsonData["action"] = "HideLoading"
                JsonData["data"] = {}
                self.send_message(JsonData)

                for v in data:
                    if data[v] == "true": data[v] = True
                    if data[v] == "false": data[v] = False
                    if unicode(data[v]).isnumeric(): data[v] = int(data[v])

                if not callback:
                    for v in data:
                        config.set_setting(v, data[v], channelname)
                    return None

                else:
                    exec "from channels import " + channelname + " as cb_channel"
                    exec "return_value = cb_channel." + callback + "(item, data)"
                    return return_value

            elif data == "custom_button":
                try:
                    cb_channel = __import__('channels.%s' % channelname, None,
                                            None,
                                            ["channels.%s" % channelname])
                except ImportError:
                    logger.error('Imposible importar %s' % channelname)

                else:
                    return_value = getattr(cb_channel,
                                           custom_button['function'])(item)
                    if custom_button["close"] == True:
                        return return_value

            elif data == False:
                return None
Exemple #12
0
def agrupa_datos(url,
                 post=None,
                 referer=True,
                 json=False,
                 proxy=True,
                 forced_proxy=None,
                 proxy_retries=1,
                 force_check=False,
                 force_login=True):
    global host, account

    if force_check or force_login:
        verify_login(force_check=force_check, force_login=force_login)

    headers = {'Referer': host}
    if 'episodes' in url or 'buscar' in url:
        headers['Referer'] += 'episodios'

    if not referer:
        headers.pop('Referer')
    # if cookie:
    #     headers.update('Cookie:' 'language=es')
    if isinstance(referer, str):
        headers.update({'Referer': referer})

    if host in host_blacklist:
        list_controls, dict_settings = channeltools.get_channel_controls_settings(
            "hdfull")
        config.set_setting("current_host",
                           dict_settings['current_host'],
                           channel="hdfull")
        host = dict_settings['current_host']

    parsed = urlparse.urlparse(host)

    if len(parsed.path) > 1:
        parse_url = "https://%s/" % parsed.netloc
        config.set_setting("current_host", parse_url, channel="hdfull")

    url = re.sub(r'http(?:s|)://[^/]+/', host, url)
    page = httptools.downloadpage(url,
                                  post=post,
                                  headers=headers,
                                  ignore_response_code=True,
                                  proxy=proxy,
                                  forced_proxy=forced_proxy,
                                  proxy_retries=proxy_retries)

    if not page.sucess:
        list_controls, dict_settings = channeltools.get_channel_controls_settings(
            "hdfull")
        if dict_settings['current_host'] != config.get_setting(
                "current_host", channel="hdfull", default=""):
            config.set_setting("current_host",
                               dict_settings['current_host'],
                               channel="hdfull")
            host = dict_settings['current_host']
            return agrupa_datos(url,
                                post=post,
                                referer=referer,
                                json=json,
                                proxy=True,
                                forced_proxy='ProxyWeb',
                                proxy_retries=0)
    if not page.sucess and not proxy:
        return agrupa_datos(url,
                            post=post,
                            referer=referer,
                            json=json,
                            proxy=True,
                            forced_proxy='ProxyWeb',
                            proxy_retries=0)
    if not page.sucess:
        account = False
        config.set_setting("logged", False, channel="hdfull")

    new_host = scrapertools.find_single_match(
        page.data, r'location.replace\("(http(?:s|)://\w+.hdfull.\w{2,4})')

    backup = scrapertools.find_single_match(
        page.data, r'onclick="redirect\(\)"><strong>(http[^<]+)')
    if not new_host and backup and 'dominio temporalmente' in page.data:
        new_host = backup
    if new_host:

        if not new_host.endswith('/'):
            new_host += '/'
        config.set_setting("current_host", new_host, channel="hdfull")
        url = re.sub(host, new_host, url)

        host = config.get_setting("current_host", channel="hdfull")

        return agrupa_datos(url, post=post, referer=referer, json=json)

    if json:
        return page.json
    # if raw:
    #     return page.data

    data = page.data
    if PY3 and isinstance(data, bytes):
        data = "".join(chr(x) for x in bytes(data))
    ## Agrupa los datos
    data = re.sub(r'\n|\r|\t|&nbsp;|<br>|<!--.*?-->', '', data)
    data = re.sub(r'\s+', ' ', data)
    data = re.sub(r'>\s<', '><', data)
    return data
Exemple #13
0
def conf_tools(item):
    logger.info()

    # Activar/Desactivar canales
    if item.extra == "channels_onoff":
        import channelselector
        from core import channeltools
        from platformcode import platformtools

        channel_list = channelselector.filterchannels("allchannelstatus")

        channel_language = config.get_setting("channel_language")
        if channel_language == "":
            channel_language = "all"

        excluded_channels = ['tengourl',
                             'buscador',
                             'libreria',
                             'configuracion',
                             'novedades',
                             'personal',
                             'ayuda']

        list_controls = []
        try:
            list_controls.append({'id': "all_channels",
                                  'type': "list",
                                  'label': "Todos los canales",
                                  'default': 0,
                                  'enabled': True,
                                  'visible': True,
                                  'lvalues': ['',
                                              'Activar todos',
                                              'Desactivar todos',
                                              'Establecer estado por defecto']})

            for channel in channel_list:
                # Si el canal esta en la lista de exclusiones lo saltamos
                if channel.channel not in excluded_channels:
                    # Se cargan los ajustes del archivo json del canal
                    jsonchannel = channeltools.get_channel_json(channel.channel)
                    if jsonchannel.get("settings") or jsonchannel.get("active"):
                        channel_parameters = channeltools.get_channel_parameters(channel.channel)

                        # No incluir si es un canal para adultos, y el modo adulto está desactivado
                        if (channel_parameters["adult"] == "true" and
                                config.get_setting("adult_mode") == "false"):
                            continue

                        # No incluir si el canal es en un idioma filtrado
                        if (channel_language != "all" and
                                channel_parameters["language"] != channel_language):
                            continue

                        xml_status = None
                        status = None
                        xml_status = channel_parameters["active"]
                        status_control = ""

                        if config.get_setting("enabled", channel.channel):
                            status = config.get_setting("enabled", channel.channel)
                            # logger.info(channel.channel + " | Status: " + str(status))
                        else:
                            status = xml_status
                            # logger.info(channel.channel + " | Status (XML): " + str(status))

                        # Se establece el estado
                        if status == "false" or status is False:
                            status = False
                        elif status == "true" or status is True:
                            status = True

                        if xml_status == "false":
                            status_control = " [COLOR grey](Desactivado por defecto)[/COLOR]"

                        if status is not None:
                            control = {'id': channel.channel,
                                       'type': "bool",
                                       'label': channel_parameters["title"] + status_control,
                                       'default': status,
                                       'enabled': True,
                                       'visible': True}

                            list_controls.append(control)

                    else:
                        logger.info("Algo va mal con el canal " + channel.channel)
                else:
                    continue
            return platformtools.show_channel_settings(list_controls=list_controls,
                                                       caption="Activar/Desactivar canales",
                                                       callback="channel_status")
        except:
            import traceback
            from platformcode import platformtools
            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
            platformtools.dialog_notification("Error",
                                              "Se ha producido un error con el canal" +
                                              channel.title)

    # Comprobacion de archivos channel_data.json
    elif item.extra == "lib_check_datajson":
        itemlist = []
        import channelselector
        from core import channeltools
        channel_list = channelselector.filterchannels("allchannelstatus")

        # Tener una lista de exclusion no tiene mucho sentido por que se comprueba si
        # el xml tiene "settings", pero por si acaso se deja
        excluded_channels = ['tengourl',
                             'configuracion',
                             'personal',
                             'ayuda']

        try:
            import os
            from core import jsontools
            for channel in channel_list:

                needsfix = None
                list_status = None
                list_controls = None
                default_settings = None
                channeljson_exists = None

                # Se convierte el "channel.channel" del canal biblioteca para que no de error
                if channel.channel == "libreria":
                    channel.channel = "biblioteca"

                # Se comprueba si el canal esta en la lista de exclusiones
                if channel.channel not in excluded_channels:
                    # Se comprueba que tenga "settings", sino se salta
                    jsonchannel = channeltools.get_channel_json(channel.channel)
                    if not jsonchannel.get("settings"):
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + " - No tiene ajustes por defecto",
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail))
                        continue
                        # logger.info(channel.channel + " SALTADO!")

                    # Se cargan los ajustes del archivo json del canal
                    file_settings = os.path.join(config.get_data_path(), "settings_channels",
                                                 channel.channel + "_data.json")
                    dict_settings = {}
                    dict_file = {}
                    if filetools.exists(file_settings):
                        # logger.info(channel.channel + " Tiene archivo _data.json")
                        channeljson_exists = "true"
                        # Obtenemos configuracion guardada de ../settings/channel_data.json
                        try:
                            dict_file = jsontools.load_json(open(file_settings, "rb").read())
                            if isinstance(dict_file, dict) and 'settings' in dict_file:
                                dict_settings = dict_file['settings']
                        except EnvironmentError:
                            logger.info("ERROR al leer el archivo: {0}".format(file_settings))
                    else:
                        # logger.info(channel.channel + " No tiene archivo _data.json")
                        channeljson_exists = "false"

                    if channeljson_exists == "true":
                        try:
                            datajson_size = filetools.getsize(file_settings)
                        except:
                            import traceback
                            logger.info(channel.title +
                                        " | Detalle del error: %s" % traceback.format_exc())
                    else:
                        datajson_size = None

                    # Si el _data.json esta vacio o no existe...
                    if (len(dict_settings) and datajson_size) == 0 or channeljson_exists == "false":
                        # Obtenemos controles del archivo ../channels/channel.xml
                        needsfix = "true"
                        try:
                            # Se cargan los ajustes por defecto
                            list_controls, default_settings = channeltools.get_channel_controls_settings(channel.channel)
                            # logger.info(channel.title + " | Default: %s" % default_settings)
                        except:
                            import traceback
                            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
                            # default_settings = {}

                        # Si _data.json necesita ser reparado o no existe...
                        if needsfix == "true" or channeljson_exists == "false":
                            if default_settings is not None:
                                # Creamos el channel_data.json
                                default_settings.update(dict_settings)
                                dict_settings = default_settings
                                dict_file['settings'] = dict_settings
                                # Creamos el archivo ../settings/channel_data.json
                                json_data = jsontools.dump_json(dict_file)
                                try:
                                    open(file_settings, "wb").write(json_data)
                                    # logger.info(channel.channel + " - Archivo _data.json GUARDADO!")
                                    # El channel_data.json se ha creado/modificado
                                    list_status = " - [COLOR red] CORREGIDO!![/COLOR]"
                                except EnvironmentError:
                                    logger.info("ERROR al salvar el archivo: {0}".format(file_settings))
                            else:
                                if default_settings is None:
                                    list_status = " - [COLOR red] Imposible cargar los ajustes por defecto![/COLOR]"

                    else:
                        # logger.info(channel.channel + " - NO necesita correccion!")
                        needsfix = "false"

                    # Si se ha establecido el estado del canal se añade a la lista
                    if needsfix is not None:
                        if needsfix == "true":
                            if channeljson_exists == "false":
                                list_status = " - [COLOR red] Ajustes creados!![/COLOR]"
                            else:
                                list_status = " - [COLOR green] No necesita correccion[/COLOR]"
                        else:
                            # Si "needsfix" es "false" y "datjson_size" es None habra
                            # ocurrido algun error
                            if datajson_size is None:
                                list_status = " - [COLOR red] Ha ocurrido algun error[/COLOR]"
                            else:
                                list_status = " - [COLOR green] No necesita correccion[/COLOR]"

                    if list_status is not None:
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + list_status,
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail))
                    else:
                        logger.info("Algo va mal con el canal " + channel.channel)

                # Si el canal esta en la lista de exclusiones lo saltamos
                else:
                    continue
        except:
            import traceback
            from platformcode import platformtools
            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
            platformtools.dialog_notification("Error",
                                              "Se ha producido un error con el canal" +
                                              channel.title)
        return itemlist

    else:
        from platformcode import platformtools
        platformtools.dialog_notification("pelisalacarta", "Error!")
        platformtools.itemlist_update(Item(channel=CHANNELNAME, action="submenu_tools"))
Exemple #14
0
    def show_channel_settings(self,
                              list_controls=None,
                              dict_values=None,
                              caption="",
                              callback=None,
                              item=None,
                              custom_button=None,
                              channelpath=None):
        from platformcode import config
        from core import channeltools
        from core import servertools
        import inspect
        if not os.path.isdir(
                os.path.join(config.get_data_path(), "settings_channels")):
            os.mkdir(os.path.join(config.get_data_path(), "settings_channels"))

        title = caption

        if type(custom_button) == dict:
            custom_button = {
                "label": custom_button.get("label", ""),
                "function": custom_button.get("function", ""),
                "visible": bool(custom_button.get("visible", True)),
                "close": bool(custom_button.get("close", False))
            }

        else:
            custom_button = None

        # Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal
        if not channelpath:
            channelpath = inspect.currentframe(
            ).f_back.f_back.f_code.co_filename
        channelname = os.path.basename(channelpath).split(".")[0]
        ch_type = os.path.basename(os.path.dirname(channelpath))

        # Si no tenemos list_controls, hay que sacarlos del json del canal
        if not list_controls:

            # Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
            if os.path.join(config.get_runtime_path(),
                            "channels") in channelpath:

                # La llamada se hace desde un canal
                list_controls, default_values = channeltools.get_channel_controls_settings(
                    channelname)
                kwargs = {"channel": channelname}

            # Si la ruta del canal esta en la carpeta "servers", obtenemos los controles y valores mediante servertools
            elif os.path.join(config.get_runtime_path(),
                              "servers") in channelpath:
                # La llamada se hace desde un server
                list_controls, default_values = servertools.get_server_controls_settings(
                    channelname)
                kwargs = {"server": channelname}

            # En caso contrario salimos
            else:
                return None

        # Si no se pasan dict_values, creamos un dict en blanco
        if dict_values == None:
            dict_values = {}

        # Ponemos el titulo
        if caption == "":
            caption = str(config.get_localized_string(
                30100)) + " -- " + channelname.capitalize()
        elif caption.startswith('@') and unicode(caption[1:]).isnumeric():
            caption = config.get_localized_string(int(caption[1:]))

        JsonData = {}
        JsonData["action"] = "OpenConfig"
        JsonData["data"] = {}
        JsonData["data"]["title"] = self.kodi_labels_to_html(caption)
        JsonData["data"]["custom_button"] = custom_button
        JsonData["data"]["items"] = []

        # Añadir controles
        for c in list_controls:
            if not "default" in c: c["default"] = ""
            if not "color" in c: c["color"] = "auto"
            if not "label" in c: continue

            # Obtenemos el valor
            if "id" in c:
                if not c["id"] in dict_values:
                    if not callback:
                        c["value"] = config.get_setting(c["id"], **kwargs)
                    else:
                        c["value"] = c["default"]

                    dict_values[c["id"]] = c["value"]

                else:
                    c["value"] = dict_values[c["id"]]

            # Translation
            if c['label'].startswith('@') and unicode(
                    c['label'][1:]).isnumeric():
                c['label'] = str(config.get_localized_string(c['label'][1:]))
            if c["label"].endswith(":"): c["label"] = c["label"][:-1]

            if c['type'] == 'list':
                lvalues = []
                for li in c['lvalues']:
                    if li.startswith('@') and unicode(li[1:]).isnumeric():
                        lvalues.append(str(config.get_localized_string(
                            li[1:])))
                    else:
                        lvalues.append(li)
                c['lvalues'] = lvalues

            c["label"] = self.kodi_labels_to_html(c["label"])

            JsonData["data"]["items"].append(c)

        ID = self.send_message(JsonData)
        close = False

        while True:
            data = self.get_data(ID)
            if type(data) == dict:
                JsonData["action"] = "HideLoading"
                JsonData["data"] = {}
                self.send_message(JsonData)

                for v in data:
                    if data[v] == "true": data[v] = True
                    if data[v] == "false": data[v] = False
                    if unicode(data[v]).isnumeric(): data[v] = int(data[v])

                if callback and '.' in callback:
                    package, callback = callback.rsplit('.', 1)
                else:
                    package = '%s.%s' % (ch_type, channelname)

                cb_channel = None
                try:
                    cb_channel = __import__(package, None, None, [package])
                except ImportError:
                    logger.error('Imposible importar %s' % package)

                if callback:
                    # Si existe una funcion callback la invocamos ...
                    return getattr(cb_channel, callback)(item, data)
                else:
                    # si no, probamos si en el canal existe una funcion 'cb_validate_config' ...
                    try:
                        return getattr(cb_channel, 'cb_validate_config')(item,
                                                                         data)
                    except AttributeError:
                        # ... si tampoco existe 'cb_validate_config'...
                        for v in data:
                            config.set_setting(v, data[v], **kwargs)

            elif data == "custom_button":
                if '.' in callback:
                    package, callback = callback.rsplit('.', 1)
                else:
                    package = '%s.%s' % (ch_type, channelname)
                try:
                    cb_channel = __import__(package, None, None, [package])
                except ImportError:
                    logger.error('Imposible importar %s' % package)
                else:
                    return_value = getattr(
                        cb_channel, custom_button['function'])(item,
                                                               dict_values)
                    if custom_button["close"] == True:
                        return return_value
                    else:
                        JsonData["action"] = "custom_button"
                        JsonData["data"] = {}
                        JsonData["data"]["values"] = dict_values
                        JsonData["data"]["return_value"] = return_value
                        ID = self.send_message(JsonData)

            elif data == False:
                return None
def conf_tools(item):
    logger.info()

    # Activar o desactivar canales
    if item.extra == "channels_onoff":
        import channelselector
        from core import channeltools

        channel_list = channelselector.filterchannels("allchannelstatus")

        channel_language = config.get_setting("channel_language")
        if channel_language == "":
            channel_language = "all"

        excluded_channels = ['tengourl',
                             'buscador',
                             'libreria',
                             'configuracion',
                             'novedades',
                             'personal',
                             'ayuda',
                             'descargas']

        list_controls = []
        try:
            list_controls.append({'id': "all_channels",
                                  'type': "list",
                                  'label': "Todos los canales",
                                  'default': 0,
                                  'enabled': True,
                                  'visible': True,
                                  'lvalues': ['',
                                              'Activar todos',
                                              'Desactivar todos',
                                              'Establecer estado por defecto']})

            for channel in channel_list:
                # Si el canal esta en la lista de exclusiones lo saltamos
                if channel.channel not in excluded_channels:
                    # Se cargan los ajustes del archivo json del canal
                    jsonchannel = channeltools.get_channel_json(channel.channel)
                    if jsonchannel.get("settings") or jsonchannel.get("active"):
                        channel_parameters = channeltools.get_channel_parameters(channel.channel)

                        # No incluir si es un canal para adultos, y el modo adulto está desactivado
                        if (channel_parameters["adult"] == "true" and
                                config.get_setting("adult_mode") == "0"):
                            continue

                        # No incluir si el canal es en un idioma filtrado
                        if (channel_language != "all" and
                                channel_parameters["language"] != channel_language):
                            continue

                        status = None
                        xml_status = channel_parameters["active"].replace("t", "T").replace("f", "F")
                        xml_status = eval(xml_status)

                        if config.get_setting("enabled", channel.channel):
                            status = config.get_setting("enabled", channel.channel)
                            status = status.replace("t", "T").replace("f", "F")
                            status = eval(status)
                            # logger.info(channel.channel + " | Status: " + str(status))
                        else:
                            status = xml_status
                            # logger.info(channel.channel + " | Status (XML): " + str(status))

                        status_control = ""
                        if not xml_status:
                            status_control = " [COLOR grey](Desactivado por defecto)[/COLOR]"

                        if status is not None:
                            control = {'id': channel.channel,
                                       'type': "bool",
                                       'label': channel_parameters["title"] + status_control,
                                       'default': status,
                                       'enabled': True,
                                       'visible': True}
                            list_controls.append(control)

                    else:
                        logger.info("Algo va mal con el canal " + channel.channel)
                else:
                    continue

            return platformtools.show_channel_settings(list_controls=list_controls,
                                                       caption="Canales",
                                                       callback="channel_status",
                                                       custom_button={"visible": False})
        except:
            import traceback
            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
            platformtools.dialog_notification("Error",
                                              "Se ha producido un error con el canal %s" %
                                              channel.title)

    # Comprobacion de archivos channel_data.json
    elif item.extra == "lib_check_datajson":
        itemlist = []
        import channelselector
        from core import channeltools
        channel_list = channelselector.filterchannels("allchannelstatus")

        # Tener una lista de exclusion no tiene mucho sentido por que se comprueba si
        # el xml tiene "settings", pero por si acaso se deja
        excluded_channels = ['tengourl',
                             'configuracion',
                             'personal',
                             'ayuda']

        try:
            import os
            from core import jsontools
            for channel in channel_list:

                needsfix = None
                list_status = None
                list_controls = None
                default_settings = None
                channeljson_exists = None

                # Se convierte el "channel.channel" del canal biblioteca para que no de error
                if channel.channel == "libreria":
                    channel.channel = "biblioteca"

                # Se comprueba si el canal esta en la lista de exclusiones
                if channel.channel not in excluded_channels:
                    # Se comprueba que tenga "settings", sino se salta
                    jsonchannel = channeltools.get_channel_json(channel.channel)
                    if not jsonchannel.get("settings"):
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + " - No tiene ajustes por defecto",
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail))
                        continue
                        # logger.info(channel.channel + " SALTADO!")

                    # Se cargan los ajustes del archivo json del canal
                    file_settings = os.path.join(config.get_data_path(), "settings_channels",
                                                 channel.channel + "_data.json")
                    dict_settings = {}
                    dict_file = {}
                    if filetools.exists(file_settings):
                        # logger.info(channel.channel + " Tiene archivo _data.json")
                        channeljson_exists = "true"
                        # Obtenemos configuracion guardada de ../settings/channel_data.json
                        try:
                            dict_file = jsontools.load_json(open(file_settings, "rb").read())
                            if isinstance(dict_file, dict) and 'settings' in dict_file:
                                dict_settings = dict_file['settings']
                        except EnvironmentError:
                            logger.info("ERROR al leer el archivo: %s" % file_settings)
                    else:
                        # logger.info(channel.channel + " No tiene archivo _data.json")
                        channeljson_exists = "false"

                    if channeljson_exists == "true":
                        try:
                            datajson_size = filetools.getsize(file_settings)
                        except:
                            import traceback
                            logger.info(channel.title +
                                        " | Detalle del error: %s" % traceback.format_exc())
                    else:
                        datajson_size = None

                    # Si el _data.json esta vacio o no existe...
                    if (len(dict_settings) and datajson_size) == 0 or channeljson_exists == "false":
                        # Obtenemos controles del archivo ../channels/channel.xml
                        needsfix = "true"
                        try:
                            # Se cargan los ajustes por defecto
                            list_controls, default_settings = channeltools.get_channel_controls_settings(channel.channel)
                            # logger.info(channel.title + " | Default: %s" % default_settings)
                        except:
                            import traceback
                            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
                            # default_settings = {}

                        # Si _data.json necesita ser reparado o no existe...
                        if needsfix == "true" or channeljson_exists == "false":
                            if default_settings is not None:
                                # Creamos el channel_data.json
                                default_settings.update(dict_settings)
                                dict_settings = default_settings
                                dict_file['settings'] = dict_settings
                                # Creamos el archivo ../settings/channel_data.json
                                json_data = jsontools.dump_json(dict_file)
                                try:
                                    open(file_settings, "wb").write(json_data)
                                    # logger.info(channel.channel + " - Archivo _data.json GUARDADO!")
                                    # El channel_data.json se ha creado/modificado
                                    list_status = " - [COLOR red] CORREGIDO!![/COLOR]"
                                except EnvironmentError:
                                    logger.info("ERROR al salvar el archivo: %s" % file_settings)
                            else:
                                if default_settings is None:
                                    list_status = " - [COLOR red] Imposible cargar los ajustes por defecto![/COLOR]"

                    else:
                        # logger.info(channel.channel + " - NO necesita correccion!")
                        needsfix = "false"

                    # Si se ha establecido el estado del canal se añade a la lista
                    if needsfix is not None:
                        if needsfix == "true":
                            if channeljson_exists == "false":
                                list_status = " - Ajustes creados"
                                list_colour = "red"
                            else:
                                list_status = " - No necesita correccion"
                                list_colour = "green"
                        else:
                            # Si "needsfix" es "false" y "datjson_size" es None habra
                            # ocurrido algun error
                            if datajson_size is None:
                                list_status = " - Ha ocurrido algun error"
                                list_colour = "red"
                            else:
                                list_status = " - No necesita correccion"
                                list_colour = "green"

                    if list_status is not None:
                        itemlist.append(Item(channel=CHANNELNAME,
                                             title=channel.title + list_status,
                                             action="", folder=False,
                                             thumbnail=channel.thumbnail,
                                             text_color=list_colour))
                    else:
                        logger.info("Algo va mal con el canal %s" % channel.channel)

                # Si el canal esta en la lista de exclusiones lo saltamos
                else:
                    continue
        except:
            import traceback
            logger.info(channel.title + " | Detalle del error: %s" % traceback.format_exc())
            platformtools.dialog_notification("Error",
                                              "Se ha producido un error con el canal %s" %
                                              channel.title)
        return itemlist

    else:
        platformtools.dialog_notification("pelisalacarta", "Error!")
        platformtools.itemlist_update(Item(channel=CHANNELNAME, action="submenu_tools"))
Exemple #16
0
    def start(self,
              list_controls=None,
              dict_values=None,
              caption="",
              callback=None,
              item=None,
              custom_button=None,
              channelpath=None):
        log()

        # Media Path
        self.mediapath = os.path.join(config.get_runtime_path(), 'resources',
                                      'skins', 'Default', 'media')

        # Params
        self.list_controls = list_controls
        self.values = dict_values
        self.caption = caption
        self.callback = callback
        self.item = item

        if isinstance(custom_button, dict):
            self.custom_button = {}
            self.custom_button["label"] = custom_button.get("label", "")
            self.custom_button["function"] = custom_button.get("function", "")
            self.custom_button["visible"] = bool(
                custom_button.get("visible", True))
            self.custom_button["close"] = bool(
                custom_button.get("close", False))
        else:
            self.custom_button = None

        # Load Channel Settings
        if not channelpath:
            channelpath = inspect.currentframe(
            ).f_back.f_back.f_code.co_filename
        self.channel = os.path.basename(channelpath).replace(".py", "")
        self.ch_type = os.path.basename(os.path.dirname(channelpath))
        # If list_controls does not exist, it is removed from the channel json
        if not self.list_controls:

            # If the channel path is in the "channels" folder, we get the controls and values using chaneltools
            if os.path.join(
                    config.get_runtime_path(), "channels") or os.path.join(
                        config.get_runtime_path(), "specials") in channelpath:

                # The call is made from a channel
                self.list_controls, default_values = channeltools.get_channel_controls_settings(
                    self.channel)
                self.kwargs = {"channel": self.channel}
                self.channelName = channeltools.get_channel_json(
                    self.channel)['name']

            # If the channel path is in the "servers" folder, we get the controls and values through servertools
            elif os.path.join(config.get_runtime_path(),
                              "servers") in channelpath:

                # The call is made from a channel
                self.list_controls, default_values = servertools.get_server_controls_settings(
                    self.channel)
                self.kwargs = {"server": self.channel}
                self.channelName = servertools.get_server_json(
                    self.channel)['name']

            # Else Exit
            else:
                return None

        # If dict_values are not passed, create a blank dict
        if self.values is None:
            self.values = {}

        # Make title
        if self.caption == "":
            self.caption = str(
                config.get_localized_string(30100)) + ' - ' + self.channelName

        matches = match(self.caption, patron=r'@(\d+)').matches
        if matches:
            for m in matches:
                self.caption = self.caption.replace(
                    '@' + match, config.get_localized_string(int(m)))

        # Show Window
        self.return_value = None
        self.doModal()
        return self.return_value
def get_channel_setting(name, channel):
    """
    Retorna el valor de configuracion del parametro solicitado.

    Devuelve el valor del parametro 'name' en la configuracion propia del canal 'channel'.

    Si se especifica el nombre del canal busca en la ruta \addon_data\plugin.video.pelisalacarta\settings_channels el archivo channel_data.json
    y lee el valor del parametro 'name'. Si el archivo channel_data.json no existe busca en la carpeta channels el archivo
    channel.xml y crea un archivo channel_data.json antes de retornar el valor solicitado.

    Parametros:
    name -- nombre del parametro
    channel [ -- nombre del canal

    Retorna:
    value -- El valor del parametro 'name'

    """
    #Creamos la carpeta si no existe
    if not os.path.exists(
            os.path.join(config.get_data_path(), "settings_channels")):
        os.mkdir(os.path.join(config.get_data_path(), "settings_channels"))

    file_settings = os.path.join(config.get_data_path(), "settings_channels",
                                 channel + "_data.json")
    dict_settings = {}

    if os.path.exists(file_settings):
        # Obtenemos configuracion guardada de ../settings/channel_data.json
        try:
            dict_file = jsontools.load_json(open(file_settings, "r").read())
            if isinstance(dict_file, dict) and dict_file.has_key('settings'):
                dict_settings = dict_file['settings']
        except EnvironmentError:
            logger.info("ERROR al leer el archivo: {0}".format(file_settings))

    if len(dict_settings) == 0 or not dict_settings.has_key(name):
        # Obtenemos controles del archivo ../channels/channel.xml
        from core import channeltools
        try:
            list_controls, default_settings = channeltools.get_channel_controls_settings(
                channel)
        except:
            default_settings = {}
        if default_settings.has_key(
                name
        ):  # Si el parametro existe en el channel.xml creamos el channel_data.json
            default_settings.update(dict_settings)
            dict_settings = default_settings
            dict_file = {}
            dict_file['settings'] = dict_settings
            # Creamos el archivo ../settings/channel_data.json
            json_data = jsontools.dump_json(dict_file).encode("utf-8")
            try:
                open(file_settings, "w").write(json_data)
            except EnvironmentError:
                logger.info(
                    "[config.py] ERROR al salvar el archivo: {0}".format(
                        file_settings))

    # Devolvemos el valor del parametro local 'name' si existe
    if dict_settings.has_key(name):
        return dict_settings[name]
    else:
        return None
Exemple #18
0
    def show_channel_settings(self, list_controls=None, dict_values=None, caption="", callback=None, item=None, custom_button=None, channelpath=None):
      from core import config
      from core import channeltools
      import inspect
      if not os.path.isdir(os.path.join(config.get_data_path(), "settings_channels")):
         os.mkdir(os.path.join(config.get_data_path(), "settings_channels"))
         
                
      title = caption

      if type(custom_button) == dict:
        custom_button = {"label"    : custom_button.get("label", ""),
                         "function" : custom_button.get("function", ""),
                         "visible"  : bool(custom_button.get("visible", True)),
                         "close"    : bool(custom_button.get("close", False))} 

      else:
        custom_button = None
            
      #Obtenemos el canal desde donde se ha echo la llamada y cargamos los settings disponibles para ese canal
      if not channelpath:
        channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename
      channelname = os.path.basename(channelpath).replace(".py", "")

      #Si no tenemos list_controls, hay que sacarlos del xml del canal
      if not list_controls:      
      
        #Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
        if os.path.join(config.get_runtime_path(), "channels") in channelpath:
        
          # La llamada se hace desde un canal
          list_controls, default_values = channeltools.get_channel_controls_settings(channelname)

        #En caso contrario salimos
        else:
          return None


      #Si no se pasan dict_values, creamos un dict en blanco
      if  dict_values == None:
        dict_values = {}
      
      #Ponemos el titulo
      if caption =="": 
        caption = str(config.get_localized_string(30100)) + " -- " + channelname.capitalize()
      elif caption.startswith('@') and unicode(caption[1:]).isnumeric():
          caption = config.get_localized_string(int(caption[1:]))
      
      
    
      JsonData = {}
      JsonData["action"]="OpenConfig"   
      JsonData["data"]={}
      JsonData["data"]["title"]=caption
      JsonData["data"]["custom_button"]=custom_button
      JsonData["data"]["items"]=[]
      

      # Añadir controles
      for c in list_controls:
          if not "default" in c: c["default"] = ""
          if not "color" in c: c["color"] = "auto"
          if not "label" in c: continue
          
          #Obtenemos el valor
          if not c["id"] in dict_values:
            if not callback:
              c["value"]= config.get_setting(c["id"],channelname)
            else:
              c["value"] = c["default"]

            
          # Translation
          if c['label'].startswith('@') and unicode(c['label'][1:]).isnumeric():
              c['label'] = str(config.get_localized_string(c['label'][1:]))
          if c["label"].endswith (":"): c["label"] = c["label"][:-1]
          
          if c['type'] == 'list':
              lvalues=[]
              for li in c['lvalues']:
                  if li.startswith('@') and unicode(li[1:]).isnumeric():
                      lvalues.append(str(config.get_localized_string(li[1:])))
                  else:
                      lvalues.append(li)
              c['lvalues'] = lvalues

          JsonData["data"]["items"].append(c)
        
      ID = self.send_message(JsonData)
      close = False
      
      while True:
        data = self.get_data(ID)
        if type(data) == dict:
          JsonData["action"]="HideLoading"
          JsonData["data"] = {}
          self.send_message(JsonData)
        
          for v in data:
              if data[v] == "true": data[v] = True
              if data[v] == "false": data[v] = False
              if unicode(data[v]).isnumeric():  data[v] =  int(data[v])
            
          if not callback:
            for v in data:
              config.set_setting(v,data[v],channelname)
            return None
            
          else:
            exec "from channels import " + channelname + " as cb_channel"
            exec "return_value = cb_channel." + callback + "(item, data)"
            return return_value

        elif data == "custom_button":
          try:
              cb_channel = __import__('channels.%s' % channelname, None, None, ["channels.%s" % channelname])
          except ImportError:
              logger.error('Imposible importar %s' % channelname)
              
          else:
            return_value = getattr(cb_channel, custom_button['function'])(item)
            if custom_button["close"] == True:
              return return_value
        
        elif data == False:
          return None
Exemple #19
0
def show_channel_settings(list_controls=None,
                          dict_values=None,
                          caption="",
                          channelname="",
                          callback=None,
                          item=None):
    ''' Funcion que permite utilizar cuadros de configuracion personalizados.
    
    show_channel_settings(listado_controles, dict_values, caption, callback, item)
            Parametros:
                listado_controles: (list) Lista de controles a incluir en la ventana, segun el siguiente esquema:
                    (opcional)list_controls= [
                                {'id': "nameControl1",
                                  'type': "bool",                       # bool, text, list, label 
                                  'label': "Control 1: tipo RadioButton",
                                  'color': '0xFFee66CC',                # color del texto en formato ARGB hexadecimal
                                  'default': True,
                                  'enabled': True,
                                  'visible': True
                                },
                                {'id': "nameControl2",
                                  'type': "text",                       # bool, text, list, label 
                                  'label': "Control 2: tipo Cuadro de texto",
                                  'color': '0xFFee66CC',
                                  'default': "Valor por defecto",
                                  'hidden': False,                      # only for type = text Indica si hay que ocultar el texto (para passwords)
                                  'enabled': True,
                                  'visible': True
                                },
                                {'id': "nameControl3",
                                  'type': "list",                       # bool, text, list, label 
                                  'label': "Control 3: tipo Lista",
                                  'color': '0xFFee66CC',
                                  'default': 0,                         # Indice del valor por defecto en lvalues 
                                  'enabled': True,
                                  'visible': True,
                                  'lvalues':["item1", "item2", "item3", "item4"],  # only for type = list
                                },
                                {'id': "nameControl4",
                                  'type': "label",                       # bool, text, list, label 
                                  'label': "Control 4: tipo Etiqueta",
                                  'color': '0xFFee66CC',               
                                  'enabled': True,
                                  'visible': True
                                }]
                    Si no se incluye el listado_controles, se intenta obtener del xml del canal desde donde se hace la llamada. 
                    El formato de los controles en el xml es:
                        <?xml version="1.0" encoding="UTF-8" ?>
                        <channel>
                            ...
                            ...
                            <settings>
                                <id>nameControl1</id>
                                <type>bool</type>
                                <label>Control 1: tipo RadioButton</label>
                                <default>false</default>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            <settings>
                                <id>nameControl2</id>
                                <type>text</type>
                                <label>Control 2: tipo Cuadro de texto</label>
                                <default>Valor por defecto</default>
                                <hidden>true</hidden>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            <settings>
                                <id>nameControl3</id>
                                <type>list</type>
                                <label>Control 3: tipo Lista</label>
                                <default>0</default>
                                <enabled>true</enabled>
                                <color>0xFFee66CC</color>
                                <visible>true</visible>
                                <lvalues>item1</lvalues>
                                <lvalues>item2</lvalues>
                                <lvalues>item3</lvalues>
                                <lvalues>item4</lvalues>
                            </settings>
                            <settings>
                                <id>nameControl4</id>
                                <type>label</type>
                                <label>Control 4: tipo Etiqueta</label>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            ...
                        </channel>  
                    
                    
                    Los campos 'label', 'default' y 'lvalues' pueden ser un numero precedido de '@'. En cuyo caso se buscara el literal en el archivo string.xml del idioma seleccionado.
                    Los campos 'enabled' y 'visible' admiten los comparadores eq(), gt() e it() y su funcionamiento se describe en: http://kodi.wiki/view/Add-on_settings#Different_types
                    Por el momento en PLEX, tanto si quedan disabled, como no visible, los ocultamos (quitandolos del itemlist)
                    Los campos hidden y color no tienen utilidad en PLEX
                    
                (opcional)dict_values: (dict) Diccionario que representa el par (id: valor) de los controles de la lista.
                    Si algun control de la lista no esta incluido en este diccionario se le asignara el valor por defecto.
                        dict_values={"nameControl1": False,
                                     "nameControl2": "Esto es un ejemplo"}
                
                (opcional) caption: (str) Titulo de la ventana de configuracion. Se puede localizar mediante un numero precedido de '@'
                (opcional) callback (str) Nombre de la funcion, del canal desde el que se realiza la llamada, que sera invocada al pulsar 
                    el boton aceptar de la ventana. A esta funcion se le pasara como parametros el objeto 'item' y el dicionario 'dict_values'
            Retorno: Si se especifica 'callback' se devolvera lo que devuelva esta funcion. Si no devolvera None     
    
    Ejemplos de uso:
        platformtools.show_channel_settings(): Así tal cual, sin pasar ningún argumento, la ventana detecta de que canal se ha hecho la llamada, 
            y lee los ajustes del XML y carga los controles, cuando le das a Aceptar los vuelve a guardar.
        
        return platformtools.show_channel_settings(list_controls=list_controls, dict_values=dict_values, callback='cb', ítem=ítem):
            Así abre la ventana con los controles pasados y los valores de dict_values, si no se pasa dict_values, carga los valores por defecto de los controles, 
            cuando le das a aceptar, llama a la función 'cb' del canal desde donde se ha llamado, pasando como parámetros, el ítem y el dict_values    
    
    '''
    logger.info("[plex_config_menu] show_channel_settings")
    global params
    itemlist = []

    #Cuando venimos de hacer click en un control de la ventana, channelname ya se pasa como argumento, si no lo tenemos, detectamos de donde venimos
    if not channelname:
        channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename
        channelname = os.path.basename(channelpath).replace(".py", "")

    #Si no tenemos list_controls, hay que sacarlos del xml del canal
    if not list_controls:

        #Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
        if os.path.join(config.get_runtime_path(), "channels") in channelpath:

            # La llamada se hace desde un canal
            list_controls, default_values = channeltools.get_channel_controls_settings(
                channelname)

        #En caso contrario salimos
        else:
            return itemlist

    #Si no se pasan dict_values, creamos un dict en blanco
    if dict_values == None:
        dict_values = {}

    #Ponemos el titulo
    if caption == "":
        caption = str(config.get_localized_string(
            "30100")) + " -- " + channelname.capitalize()
    elif caption.startswith('@') and unicode(caption[1:]).isnumeric():
        caption = config.get_localized_string(int(caption[1:]))

    # Añadir controles
    for c in list_controls:

        #Obtenemos el valor
        if not c["id"] in dict_values:
            if not callback:
                dict_values[c["id"]] = config.get_setting(c["id"], channelname)
            else:
                if not 'default' in c: c["default"] = ''
                dict_values[c["id"]] = c["default"]

        # Translation
        if c['label'].startswith('@') and unicode(c['label'][1:]).isnumeric():
            c['label'] = str(config.get_localized_string(c['label'][1:]))
        if c["label"].endswith(":"): c["label"] = c["label"][:-1]

        if c['type'] == 'list':
            lvalues = []
            for li in c['lvalues']:
                if li.startswith('@') and unicode(li[1:]).isnumeric():
                    lvalues.append(str(config.get_localized_string(li[1:])))
                else:
                    lvalues.append(li)
            c['lvalues'] = lvalues

        #Tipos de controles
        if c['type'] == 'label':
            titulo = c["label"]
            itemlist.append(
                Item(channel=__channel__,
                     action="control_label_click",
                     title=titulo,
                     extra=list_controls.index(c)))

        if c['type'] == 'bool':
            titulo = c["label"] + ":" + (' ' * 5) + (
                "[X]" if dict_values[c["id"]] else "[  ]")
            itemlist.append(
                Item(channel=__channel__,
                     action="control_bool_click",
                     title=titulo,
                     extra=list_controls.index(c)))

        elif c['type'] == 'list':
            titulo = c["label"] + ":" + (' ' * 5) + str(
                c["lvalues"][dict_values[c["id"]]])
            itemlist.append(
                Item(channel=__channel__,
                     action="control_list_click",
                     title=titulo,
                     extra=list_controls.index(c)))

        elif c['type'] == 'text':
            titulo = c["label"] + ":" + (' ' * 5) + str(dict_values[c["id"]])
            item = Item(channel=__channel__,
                        action="control_text_click",
                        title=titulo,
                        extra=list_controls.index(c))
            item.type = "input"
            item.value = dict_values[c["id"]]
            itemlist.append(item)

    params = {
        "list_controls": list_controls,
        "dict_values": dict_values,
        "caption": caption,
        "channelname": channelname,
        "callback": callback,
        "item": item
    }
    if itemlist:

        #Creamos un itemlist nuevo añadiendo solo los items que han pasado la evaluacion
        evaluated = []
        for x in range(len(list_controls)):
            #por el momento en PLEX, tanto si quedan disabled, como no visible, los ocultamos (quitandolos del itemlist)
            visible = evaluate(x, list_controls[x]["enabled"]) and evaluate(
                x, list_controls[x]["visible"])
            if visible:
                evaluated.append(itemlist[x])

        # Añadir Titulo
        evaluated.insert(
            0,
            Item(channel=__channel__,
                 action="control_label_click",
                 title=caption))
        # Añadir item aceptar y cancelar
        evaluated.append(
            Item(channel=__channel__,
                 action="ok_Button_click",
                 title="Aceptar"))
        evaluated.append(
            Item(channel=channelname, action="mainlist", title="Cancelar"))
        evaluated.append(
            Item(channel=__channel__,
                 action="default_Button_click",
                 title="Por defecto"))

    return evaluated
def show_channel_settings(list_controls=None, dict_values=None, caption="", callback=None,item=None, custom_button= None, channelpath= None):
    ''' Funcion que permite utilizar cuadros de configuracion personalizados.
    
    show_channel_settings(listado_controles, dict_values, caption, callback, item)
            Parametros:
                listado_controles: (list) Lista de controles a incluir en la ventana, segun el siguiente esquema:
                    (opcional)list_controls= [
                                {'id': "nameControl1",
                                  'type': "bool",                       # bool, text, list, label 
                                  'label': "Control 1: tipo RadioButton",
                                  'color': '0xFFee66CC',                # color del texto en formato ARGB hexadecimal
                                  'default': True,
                                  'enabled': True,
                                  'visible': True
                                },
                                {'id': "nameControl2",
                                  'type': "text",                       # bool, text, list, label 
                                  'label': "Control 2: tipo Cuadro de texto",
                                  'color': '0xFFee66CC',
                                  'default': "Valor por defecto",
                                  'hidden': False,                      # only for type = text Indica si hay que ocultar el texto (para passwords)
                                  'enabled': True,
                                  'visible': True
                                },
                                {'id': "nameControl3",
                                  'type': "list",                       # bool, text, list, label 
                                  'label': "Control 3: tipo Lista",
                                  'color': '0xFFee66CC',
                                  'default': 0,                         # Indice del valor por defecto en lvalues 
                                  'enabled': True,
                                  'visible': True,
                                  'lvalues':["item1", "item2", "item3", "item4"],  # only for type = list
                                },
                                {'id': "nameControl4",
                                  'type': "label",                       # bool, text, list, label 
                                  'label': "Control 4: tipo Etiqueta",
                                  'color': '0xFFee66CC',               
                                  'enabled': True,
                                  'visible': True
                                }]
                    Si no se incluye el listado_controles, se intenta obtener del xml del canal desde donde se hace la llamada. 
                    El formato de los controles en el xml es:
                        <?xml version="1.0" encoding="UTF-8" ?>
                        <channel>
                            ...
                            ...
                            <settings>
                                <id>nameControl1</id>
                                <type>bool</type>
                                <label>Control 1: tipo RadioButton</label>
                                <default>false</default>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            <settings>
                                <id>nameControl2</id>
                                <type>text</type>
                                <label>Control 2: tipo Cuadro de texto</label>
                                <default>Valor por defecto</default>
                                <hidden>true</hidden>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            <settings>
                                <id>nameControl3</id>
                                <type>list</type>
                                <label>Control 3: tipo Lista</label>
                                <default>0</default>
                                <enabled>true</enabled>
                                <color>0xFFee66CC</color>
                                <visible>true</visible>
                                <lvalues>item1</lvalues>
                                <lvalues>item2</lvalues>
                                <lvalues>item3</lvalues>
                                <lvalues>item4</lvalues>
                            </settings>
                            <settings>
                                <id>nameControl4</id>
                                <type>label</type>
                                <label>Control 4: tipo Etiqueta</label>
                                <enabled>true</enabled>
                                <visible>true</visible>
                                <color>0xFFee66CC</color>
                            </settings>
                            ...
                        </channel>  
                    
                    
                    Los campos 'label', 'default' y 'lvalues' pueden ser un numero precedido de '@'. En cuyo caso se buscara el literal en el archivo string.xml del idioma seleccionado.
                    Los campos 'enabled' y 'visible' admiten los comparadores eq(), gt() e it() y su funcionamiento se describe en: http://kodi.wiki/view/Add-on_settings#Different_types
                    Por el momento en PLEX, tanto si quedan disabled, como no visible, los ocultamos (quitandolos del itemlist)
                    Los campos hidden y color no tienen utilidad en PLEX
                    
                (opcional)dict_values: (dict) Diccionario que representa el par (id: valor) de los controles de la lista.
                    Si algun control de la lista no esta incluido en este diccionario se le asignara el valor por defecto.
                        dict_values={"nameControl1": False,
                                     "nameControl2": "Esto es un ejemplo"}
                
                (opcional) caption: (str) Titulo de la ventana de configuracion. Se puede localizar mediante un numero precedido de '@'
                (opcional) callback (str) Nombre de la funcion, del canal desde el que se realiza la llamada, que sera invocada al pulsar 
                    el boton aceptar de la ventana. A esta funcion se le pasara como parametros el objeto 'item' y el dicionario 'dict_values'
            Retorno: Si se especifica 'callback' se devolvera lo que devuelva esta funcion. Si no devolvera None     
    
    Ejemplos de uso:
        platformtools.show_channel_settings(): Así tal cual, sin pasar ningún argumento, la ventana detecta de que canal se ha hecho la llamada, 
            y lee los ajustes del XML y carga los controles, cuando le das a Aceptar los vuelve a guardar.
        
        return platformtools.show_channel_settings(list_controls=list_controls, dict_values=dict_values, callback='cb', ítem=ítem):
            Así abre la ventana con los controles pasados y los valores de dict_values, si no se pasa dict_values, carga los valores por defecto de los controles, 
            cuando le das a aceptar, llama a la función 'cb' del canal desde donde se ha llamado, pasando como parámetros, el ítem y el dict_values    
    
    '''
    logger.info("[plex_config_menu] show_channel_settings")
    global params
    itemlist = []

    #Cuando venimos de hacer click en un control de la ventana, channelname ya se pasa como argumento, si no lo tenemos, detectamos de donde venimos
    if not channelpath:
        channelpath = inspect.currentframe().f_back.f_back.f_code.co_filename
    channelname = os.path.basename(channelpath).replace(".py", "")


    #Si no tenemos list_controls, hay que sacarlos del xml del canal
    if not list_controls:

        #Si la ruta del canal esta en la carpeta "channels", obtenemos los controles y valores mediante chaneltools
        if os.path.join(config.get_runtime_path(), "channels") in channelpath:

            # La llamada se hace desde un canal
            list_controls, default_values = channeltools.get_channel_controls_settings(channelname)

        #En caso contrario salimos
        else:
            return itemlist

    #Si no se pasan dict_values, creamos un dict en blanco
    if  dict_values == None:
        dict_values = {}

    if type(custom_button) == dict:
        custom_button = {"label"    : custom_button.get("label", ""),
                         "function" : custom_button.get("function", ""),
                         "visible"  : bool(custom_button.get("visible", True)),
                         "close"    : bool(custom_button.get("close", False))}

    else:
        custom_button = None

    #Ponemos el titulo
    if caption =="":
        caption = str(config.get_localized_string("30100")) + " -- " + channelname.capitalize()
    elif caption.startswith('@') and unicode(caption[1:]).isnumeric():
        caption = config.get_localized_string(int(caption[1:]))


    # Añadir controles
    for c in list_controls:

        #Obtenemos el valor
        if not c["id"] in dict_values:
            if not callback:
                dict_values[c["id"]]= config.get_setting(c["id"],channelname)
            else:
                if not 'default' in c: c["default"] = ''
                dict_values[c["id"]] = c["default"]


        # Translation
        if c['label'].startswith('@') and unicode(c['label'][1:]).isnumeric():
            c['label'] = str(config.get_localized_string(c['label'][1:]))
        if c["label"].endswith (":"): c["label"] = c["label"][:-1]

        if c['type'] == 'list':
            lvalues=[]
            for li in c['lvalues']:
                if li.startswith('@') and unicode(li[1:]).isnumeric():
                    lvalues.append(str(config.get_localized_string(li[1:])))
                else:
                    lvalues.append(li)
            c['lvalues'] = lvalues


        #Tipos de controles
        if c['type'] == 'label':
            titulo = c["label"]
            itemlist.append(Item(channel=__channel__, action="control_label_click", title=titulo, extra=list_controls.index(c)))

        if c['type'] == 'bool':
            titulo = c["label"] + ":" + (' ' * 5) + ("[X]" if dict_values[c["id"]] else "[  ]")
            itemlist.append(Item(channel=__channel__, action="control_bool_click", title=titulo, extra=list_controls.index(c)))

        elif c['type'] == 'list':
            titulo = c["label"] + ":" + (' ' * 5) + str(c["lvalues"][dict_values[c["id"]]])
            itemlist.append(Item(channel=__channel__, action="control_list_click", title=titulo, extra=list_controls.index(c)))

        elif c['type'] == 'text':
            titulo = c["label"] + ":" + (' ' * 5) + str(dict_values[c["id"]])
            item= Item(channel=__channel__, action="control_text_click", title=titulo, extra=list_controls.index(c))
            item.type = "input"
            item.value = dict_values[c["id"]]
            itemlist.append(item)



    params = {"list_controls":list_controls, "dict_values":dict_values, "caption":caption, "channelpath":channelpath, "callback":callback, "item":item, "custom_button": custom_button}
    if itemlist:

        #Creamos un itemlist nuevo añadiendo solo los items que han pasado la evaluacion
        evaluated = []
        for x in range(len(list_controls)):
            #por el momento en PLEX, tanto si quedan disabled, como no visible, los ocultamos (quitandolos del itemlist)
            visible = evaluate(x, list_controls[x]["enabled"]) and evaluate(x, list_controls[x]["visible"])
            if visible:
                evaluated.append(itemlist[x])

        # Añadir Titulo
        evaluated.insert(0,Item(channel=__channel__, action="control_label_click", title=caption))
        # Añadir item aceptar y cancelar
        evaluated.append(Item(channel=__channel__, action="ok_Button_click", title="Aceptar"))
        evaluated.append(Item(channel=channelname, action="mainlist", title="Cancelar"))

        if custom_button is None:
            evaluated.append(Item(channel=__channel__, action="default_Button_click", title="Por defecto"))
        else:
            if custom_button['visible'] == True:
                evaluated.append(Item(channel=__channel__, action="default_Button_click", title=custom_button["label"]))


    return evaluated