def tojson(self, path=""): ''' Crea un JSON a partir del item, para guardar archivos de favoritos, lista de descargas, etc... Si se especifica un path, te lo guarda en la ruta especificada, si no, devuelve la cadena json Usos: item.tojson(path="ruta\archivo\json.json") file.write(item.tojson()) ''' if path: open(path, "wb").write(json.dump_json(self.__dict__)) else: return json.dump_json(self.__dict__)
def save_server_stats(stats, type="find_videos"): if not config.get_setting("server_stats"): return stats_file = os.path.join(config.get_data_path(), "server_stats.json") today = datetime.datetime.now().strftime("%Y%m%d") #Leemos el archivo try: server_stats = jsontools.load_json(open(stats_file, "rb").read()) except: server_stats = {"created": time.time(), "data": {}} #Actualizamos los datos for server in stats: if not server in server_stats["data"]: server_stats["data"][server] = {} if not today in server_stats["data"][server]: server_stats["data"][server][today] = { "find_videos": { "found": 0 }, "resolve": { "sucess": 0, "error": 0 } } server_stats["data"][server][today][type][stats[server]] += 1 #Guardamos el archivo open(stats_file, "wb").write(jsontools.dump_json(server_stats)) #Enviamos al servidor return if time.time() - server_stats["created"] > 86400: #86400: #1 Dia from core import httptools if httptools.downloadpage( "url servidor", headers={ 'Content-Type': 'application/json' }, post=jsontools.dump_json(server_stats)).sucess: os.remove(stats_file) logger.info("Datos enviados correctamente") else: logger.info("No se han podido enviar los datos")
def get_data(url_orig, cookie): try: response = httptools.downloadpage(url_orig, headers=cookie) if not response.data or "urlopen error [Errno 1]" in str( response.code): raise Exception return response.data except: import urllib post = {"address": url_orig} if cookie: post["options"] = [{ "man": "--cookie", "attribute": cookie.get("Cookie", "") }] from core import jsontools data = httptools.downloadpage("http://onlinecurl.com/").data token = scrapertools.find_single_match( data, '<meta name="csrf-token" content="([^"]+)"') headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': token, 'Referer': 'http://onlinecurl.com/' } post = "curl_request=" + urllib.quote( jsontools.dump_json(post)) + "&email=" response = httptools.downloadpage("http://onlinecurl.com/onlinecurl", post=post, headers=headers).data data = jsontools.load_json(response).get("body", "") return data
def update_json_data(dict_node, filename, node): """ actualiza el json_data de un fichero con el diccionario pasado @param dict_node: diccionario con el nodo @type dict_node: dict @param filename: nombre del fichero para guardar @type filename: str @param node: nodo a actualizar @return: fname, json_data @rtype: str, dict """ logger.info() from core import config from core import jsontools fname = join(config.get_data_path(), "settings_channels", filename + "_data.json") data = read(fname) dict_data = jsontools.load_json(data) # es un dict if dict_data: if node in dict_data: logger.debug(" existe el key %s" % node) dict_data[node] = dict_node else: logger.debug(" NO existe el key %s" % node) new_dict = {node: dict_node} dict_data.update(new_dict) else: logger.debug(" NO es un dict") dict_data = {node: dict_node} json_data = jsontools.dump_json(dict_data) return fname, json_data
def get_data(payload): """ obtiene la información de la llamada JSON-RPC con la información pasada en payload @type payload: dict @param payload: data :return: """ logger.info("pelisalacarta.platformcode.library get_data: payload %s" % payload) # Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type headers = {'content-type': 'application/json'} if modo_cliente: try: req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump_json(payload), headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("pelisalacarta.platformcode.library get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("pelisalacarta.platformcode.library get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"]
def get_data(url_orig, req_post=""): try: if not excption: response = httptools.downloadpage(url_orig, req_post) if not response.data or "urlopen error [Errno 1]" in str(response.code): global excption excption = True raise Exception return response.data else: raise Exception except: import urllib post = {"address": url_orig.replace(".me", ".org")} if req_post: post["options"] = [{"man": "--data", "attribute": req_post}] else: post["options"] = [] from core import jsontools global token if not token: data = httptools.downloadpage("http://onlinecurl.com/").data token = scrapertools.find_single_match(data, '<meta name="csrf-token" content="([^"]+)"') headers = {'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': token, 'Referer': 'http://onlinecurl.com/'} post = "curl_request=" + urllib.quote(jsontools.dump_json(post)) + "&email=" response = httptools.downloadpage("http://onlinecurl.com/onlinecurl", post=post, headers=headers).data data = jsontools.load_json(response).get("body", "") return data
def clean_up_file(item): """ borra los elementos del fichero "series" que no existen como carpetas en la libreria de "SERIES" @type item: item @param item: elemento @rtype: list @return: vacío para navegue. """ logger.info("pelisalacarta.platformcode.library clean_up_file") path = TVSHOWS_PATH dict_data = item.dict_fichero # Obtenemos las carpetas de las series raiz, carpetas_series, files = os.walk(path).next() for tvshow_id in dict_data.keys(): for channel in dict_data[tvshow_id]["channels"].keys(): carpeta = "{0} [{1}]".format(title_to_filename(dict_data[tvshow_id]["channels"][channel]["tvshow"].lower()), channel) if carpeta not in carpetas_series: dict_data[tvshow_id]["channels"].pop(channel, None) if not dict_data[tvshow_id]["channels"]: dict_data.pop(tvshow_id, None) json_data = jsontools.dump_json(dict_data) save_file(json_data, join_path(config.get_data_path(), TVSHOW_FILE)) return []
def save_server_stats(stats, type="find_videos"): if not config.get_setting("server_stats"): return stats_file = os.path.join(config.get_data_path(), "server_stats.json") today = datetime.datetime.now().strftime("%Y%m%d") # Leemos el archivo try: server_stats = jsontools.load_json(open(stats_file, "rb").read()) except: server_stats = {"created": time.time(), "data": {}} # Actualizamos los datos for server in stats: if not server in server_stats["data"]: server_stats["data"][server] = {} if not today in server_stats["data"][server]: server_stats["data"][server][today] = {"find_videos": {"found": 0}, "resolve": {"sucess": 0, "error": 0}} server_stats["data"][server][today][type][stats[server]] += 1 # Guardamos el archivo open(stats_file, "wb").write(jsontools.dump_json(server_stats)) # Enviamos al servidor return
def extract_safe(item): logger.info("pelisalacarta.channels.puyasubs extract_safe") if item.infoLabels["tmdb_id"] and not item.infoLabels["plot"]: from core import tmdb tmdb.set_infoLabels_item(item, True, idioma_busqueda="en") itemlist = list() hash = item.url.rsplit("/", 1)[1] headers = [['Content-Type', 'application/json;charset=utf-8']] post = jsontools.dump_json({"hash": hash}) data = scrapertools.downloadpage("http://safelinking.net/v1/protected", post, headers) data = jsontools.load_json(data) for link in data.get("links"): enlace = link["url"] domain = link["domain"] title = "Ver por %s" % domain action = "play" if "mega" in domain: server = "mega" if "/#F!" in enlace: action = "carpeta" elif "1fichier" in domain: server = "onefichier" if "/dir/" in enlace: action = "carpeta" itemlist.append(item.clone(title=title, action=action, url=enlace, server=server)) return itemlist
def get_data(payload): """ obtiene la información de la llamada JSON-RPC con la información pasada en payload @type payload: dict @param payload: data :return: """ logger.info("payload %s" % payload) # Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type headers = {'content-type': 'application/json'} if modo_cliente: try: req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump_json(payload), headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"]
def get_data(payload): """ obtiene la información de la llamada JSON-RPC con la información pasada en payload @type payload: dict @param payload: data :return: """ logger.info("payload: %s" % payload) # Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type headers = {'content-type': 'application/json'} if config.get_setting("library_mode", "biblioteca"): try: try: xbmc_port = int(config.get_setting("xbmc_puerto", "biblioteca")) except: xbmc_port = 0 xbmc_json_rpc_url = "http://" + config.get_setting("xbmc_host", "biblioteca") + ":" + str( xbmc_port) + "/jsonrpc" req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump_json(payload), headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"]
def get_bing_images(self, q, mode="single", tipo="m"): thumb = "" f1file = filetools.join(config.get_data_path(), 'matchcenter', 'matchcenter_moto.json') data_bing = filetools.read(f1file) if data_bing: data_bing = jsontools.load_json(data_bing) thumb = data_bing.get(q, "") else: data_bing = {} if not thumb: data_img = httptools.downloadpage( "http://www.bing.com/images/search?q=%s" % q.replace(" ", "+")).data if mode == "single": thumb = scrapertools.find_single_match( data_img, tipo + 'url":"(.*?)"') else: thumb = scrapertools.find_multiple_matches( data_img, tipo + 'url":"(.*?)"') data_bing[q] = thumb filetools.write(f1file, jsontools.dump_json(data_bing)) return thumb
def extract_safe(item): logger.info("pelisalacarta.channels.puyasubs extract_safe") if item.infoLabels["tmdb_id"] and not item.infoLabels["plot"]: from core import tmdb tmdb.set_infoLabels_item(item, True, idioma_busqueda="en") itemlist = list() hash = item.url.rsplit("/", 1)[1] headers = [['Content-Type', 'application/json;charset=utf-8']] post = jsontools.dump_json({"hash": hash}) data = scrapertools.downloadpage("http://safelinking.net/v1/protected", post, headers) data = jsontools.load_json(data) for link in data.get("links"): enlace = link["url"] domain = link["domain"] title = "Ver por %s" % domain action = "play" if "mega" in domain: server = "mega" if "/#F!" in enlace: action = "carpeta" elif "1fichier" in domain: server = "onefichier" if "/dir/" in enlace: action = "carpeta" itemlist.append( item.clone(title=title, action=action, url=enlace, server=server)) return itemlist
def set_server_setting(name, value, server): # Creamos la carpeta si no existe if not os.path.exists(os.path.join(config.get_data_path(), "settings_servers")): os.mkdir(os.path.join(config.get_data_path(), "settings_servers")) file_settings = os.path.join(config.get_data_path(), "settings_servers", server + "_data.json") dict_settings = {} dict_file = None 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()) dict_settings = dict_file.get('settings', {}) except EnvironmentError: logger.info("ERRORE durante la lettura del file: %s" % file_settings) dict_settings[name] = value # comprobamos si existe dict_file y es un diccionario, sino lo creamos if dict_file is None or not dict_file: dict_file = {} dict_file['settings'] = dict_settings # Creamos el archivo ../settings/channel_data.json try: json_data = jsontools.dump_json(dict_file) open(file_settings, "w").write(json_data) except EnvironmentError: logger.info("ERRORE al salvataggio del file: %s" % file_settings) return None return value
def update_json_data(dict_series, filename): """ actualiza el json_data de un fichero con el diccionario pasado :param dict_series: diccionario con las series :type dict_series: dict :param filename: nombre del fichero para guardar :type filename: str :return: fname, json_data :rtype: str, dict """ logger.info("[filtertools.py] update_json_data") 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")) fname = os.path.join(config.get_data_path(), "settings_channels", filename + "_data.json") data = filetools.read(fname) dict_data = jsontools.load_json(data) # es un dict if dict_data: if TAG_TVSHOW_FILTER in dict_data: logger.info(" existe el key SERIES") dict_data[TAG_TVSHOW_FILTER] = dict_series else: logger.info(" NO existe el key SERIES") new_dict = {TAG_TVSHOW_FILTER: dict_series} dict_data.update(new_dict) else: logger.info(" NO es un dict") dict_data = {TAG_TVSHOW_FILTER: dict_series} json_data = jsontools.dump_json(dict_data) return fname, json_data
def update_json_data(dict_series, filename): """ actualiza el json_data de un fichero con el diccionario pasado :param dict_series: diccionario con las series :type dict_series: dict :param filename: nombre del fichero para guardar :type filename: str :return: fname, json_data :rtype: str, dict """ logger.info("[filtertools.py] update_json_data") 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")) fname = os.path.join(config.get_data_path(), "settings_channels", filename + "_data.json") data = filetools.read(fname) dict_data = jsontools.load_json(data) # es un dict if dict_data: if TAG_TVSHOW_FILTER in dict_data: logger.info(" existe el key SERIES") dict_data[TAG_TVSHOW_FILTER] = dict_series else: logger.info(" NO existe el key SERIES") new_dict = {TAG_TVSHOW_FILTER: dict_series} dict_data.update(new_dict) else: logger.info(" NO es un dict") dict_data = {TAG_TVSHOW_FILTER: dict_series} json_data = jsontools.dump_json(dict_data) return fname, json_data
def get_data(payload): """ obtiene la información de la llamada JSON-RPC con la información pasada en payload @type payload: dict @param payload: data :return: """ logger.info("payload: %s" % payload) # Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type headers = {'content-type': 'application/json'} if config.get_setting("library_mode", "biblioteca"): try: try: xbmc_port = int(config.get_setting("xbmc_puerto", "biblioteca")) except: xbmc_port = 0 xbmc_json_rpc_url = "http://" + config.get_setting( "xbmc_host", "biblioteca") + ":" + str(xbmc_port) + "/jsonrpc" req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump_json(payload), headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"]
def tourl(self): """ Genera una cadena de texto con los datos del item para crear una url, para volver generar el Item usar item.fromurl(). Uso: url = item.tourl() """ dump = json.dump_json(self.__dict__) # if empty dict if not dump: # set a str to avoid b64encode fails dump = "" return urllib.quote(base64.b64encode(dump))
def savecurrenthash(_hash, file): if " OR " in _hash: _hash = _hash.split(" OR ", 1)[0] _hash = unicode(_hash, "utf-8", errors="replace").encode("utf-8") media_dict = {"hash": _hash} if not filetools.exists(file): if not filetools.exists( filetools.join(config.get_data_path(), 'matchcenter')): filetools.mkdir( filetools.join(config.get_data_path(), 'matchcenter')) filetools.write(file, jsontools.dump_json(media_dict)) return
def __login(): # logger.info() global TOKEN apikey = "106B699FDC04301C" url = HOST + "/login" params = {"apikey": apikey} try: req = urllib2.Request(url, data=jsontools.dump_json(params), headers=DEFAULT_HEADERS) response = urllib2.urlopen(req) html = response.read() response.close() except Exception, ex: message = "An exception of type %s occured. Arguments:\n%s" % (type(ex).__name__, repr(ex.args)) logger.error("error en: %s" % message)
def save_server_statistics(server, speed, success): from core import jsontools if os.path.isfile(STATS_FILE): servers = jsontools.load_json(open(STATS_FILE, "rb").read()) else: servers = {} if not server in servers: servers[server] = {"success": [], "count": 0, "speeds": [], "last": 0} servers[server]["count"] += 1 servers[server]["success"].append(bool(success)) servers[server]["success"] = servers[server]["success"][-5:] servers[server]["last"] = time.time() if success: servers[server]["speeds"].append(speed) servers[server]["speeds"] = servers[server]["speeds"][-5:] open(STATS_FILE, "wb").write(jsontools.dump_json(servers)) return
def get_server_setting(name, server): # Creamos la carpeta si no existe if not os.path.exists( os.path.join(config.get_data_path(), "settings_servers")): os.mkdir(os.path.join(config.get_data_path(), "settings_servers")) file_settings = os.path.join(config.get_data_path(), "settings_servers", server + "_data.json") dict_settings = {} dict_file = {} if os.path.exists(file_settings): # 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) if len(dict_settings) == 0 or name not in dict_settings: # Obtenemos controles del archivo ../channels/channel.xml try: list_controls, default_settings = get_server_controls_settings( server) except: default_settings = {} if name in default_settings: # Si el parametro existe en el channel.xml 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) except EnvironmentError: logger.info("ERROR al salvar el archivo: %s" % file_settings) # Devolvemos el valor del parametro local 'name' si existe if name in dict_settings: return dict_settings[name] else: return None
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"))
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"))
def get_server_setting(name, server, default=None): """ Retorna el valor de configuracion del parametro solicitado. Devuelve el valor del parametro 'name' en la configuracion propia del servidor 'server'. Busca en la ruta \addon_data\plugin.video.dss\settings_servers el archivo server_data.json y lee el valor del parametro 'name'. Si el archivo server_data.json no existe busca en la carpeta servers el archivo server.xml y crea un archivo server_data.json antes de retornar el valor solicitado. Si el parametro 'name' tampoco existe en el el archivo server.xml se devuelve el parametro default. @param name: nombre del parametro @type name: str @param server: nombre del servidor @type server: str @param default: valor devuelto en caso de que no exista el parametro name @type default: cualquiera @return: El valor del parametro 'name' @rtype: El tipo del valor del parametro """ # Creamos la carpeta si no existe if not os.path.exists( os.path.join(config.get_data_path(), "settings_servers")): os.mkdir(os.path.join(config.get_data_path(), "settings_servers")) file_settings = os.path.join(config.get_data_path(), "settings_servers", server + "_data.json") dict_settings = {} dict_file = {} if os.path.exists(file_settings): # 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) if not dict_settings or name not in dict_settings: # Obtenemos controles del archivo ../channels/channel.xml try: list_controls, default_settings = get_server_controls_settings( server) except: default_settings = {} if name in default_settings: # Si el parametro existe en el channel.xml 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) except EnvironmentError: logger.info("ERROR al salvar el archivo: %s" % file_settings) # Devolvemos el valor del parametro local 'name' si existe, si no se devuelve default return dict_settings.get(name, default)
def findvideos(item): logger.info("pelisalacarta.channels.puyasubs findvideos") if item.infoLabels["tmdb_id"] and not item.infoLabels["plot"]: from core import tmdb tmdb.set_infoLabels_item(item, True, idioma_busqueda="en") itemlist = list() data = scrapertools.downloadpage(item.url) idiomas = scrapertools.find_single_match(data, 'Subtitulo:\s*(.*?)<br />') calidades = ['720p', '1080p'] torrents = scrapertools.find_multiple_matches( data, '<a href="(https://www.frozen-layer.com/descargas[^"]+)"') if not torrents: torrents = scrapertools.find_multiple_matches( data, '<a href="(https://www.nyaa.se/\?page=view[^"]+)"') if torrents: for i, enlace in enumerate(torrents): title = "Ver por Torrent %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append( item.clone(title=title, action="play", url=enlace, server="torrent")) onefichier = scrapertools.find_multiple_matches( data, '<a href="(https://1fichier.com/[^"]+)"') if onefichier: for i, enlace in enumerate(onefichier): title = "Ver por 1fichier %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append( item.clone(title=title, action="play", url=enlace, server="onefichier")) safelink = scrapertools.find_multiple_matches( data, '<a href="(http(?:s|)://safelinking.net/[^"]+)"') if safelink: for i, safe in enumerate(safelink): headers = [['Content-Type', 'application/json;charset=utf-8']] hash = safe.rsplit("/", 1)[1] post = jsontools.dump_json({"hash": hash}) data_sf = scrapertools.downloadpage( "http://safelinking.net/v1/protected", post, headers) data_sf = jsontools.load_json(data_sf) for link in data_sf.get("links"): enlace = link["url"] domain = link["domain"] title = "Ver por %s" % domain action = "play" if "mega" in domain: server = "mega" if "/#F!" in enlace: action = "carpeta" elif "1fichier" in domain: server = "onefichier" if "/dir/" in enlace: action = "carpeta" title += " %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append( item.clone(title=title, action=action, url=enlace, server=server)) return itemlist
def save_tvshow_in_file(serie): """ Guarda los datos de la serie dentro del fichero 'series.json' @type serie: item @param serie: elemento """ logger.info("pelisalacarta.platformcode.library save_tvshow_in_file") fname = join_path(config.get_data_path(), TVSHOW_FILE) fname2 = join_path(config.get_data_path(), TVSHOW_FILE_OLD) # TODO soporte samba if not os.path.isfile(fname) and os.path.isfile(fname2): convert_xml_to_json() if 'infoLabels' not in serie: serie.infoLabels = {} patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(serie.show) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] if 'title' not in serie.infoLabels: serie.infoLabels['title'] = serie.show # Abrir ventana de seleccion de serie serie = get_video_id_from_scraper(serie, config.get_setting("scrap_ask_name") == "true") create_nfo = False if 'id_Tmdb' in serie.infoLabels: tvshow_id = serie.infoLabels['id_Tmdb'] create_nfo = True else: tvshow_id = "t_{0}_[{1}]".format(serie.show.strip().replace(" ", "_"), serie.channel) # Cargar el registro series.json fname = join_path(config.get_data_path(), TVSHOW_FILE) dict_series = jsontools.load_json(read_file(fname)) if not dict_series: dict_series = {} path = join_path(TVSHOWS_PATH, "{0} [{1}]".format(title_to_filename(serie.show.strip().lower()), serie.channel).lower()) if path_exists(path): if create_nfo: create_nfo_file(tvshow_id, path, "serie") # Si la serie no existe en el registro ... if tvshow_id not in dict_series: # ... añadir la serie al registro dict_series[tvshow_id] = {"name": serie.infoLabels['title'], "channels": {}} # Si no hay datos del canal en el registro para esta serie... if serie.channel not in dict_series[tvshow_id]["channels"]: # ... añadir canal al registro de la serie dict_channel = {"tvshow": serie.show.strip(), "url": serie.url, "path": path} dict_series[tvshow_id]["channels"][serie.channel] = dict_channel logger.info("dict_series {0}".format(dict_series)) json_data = jsontools.dump_json(dict_series) save_file(json_data, fname)
xbmc_port) + "/jsonrpc" req = urllib2.Request(xbmc_json_rpc_url, data=jsontools.dump_json(payload), headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"] else: try: data = jsontools.load_json(xbmc.executeJSONRPC(jsontools.dump_json(payload))) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data:: error en xbmc.executeJSONRPC: {0}". format(message)) data = ["error"] logger.info("data: %s" % data) return data def update(folder_content=FOLDER_TVSHOWS, folder=""): """ Actualiza la libreria dependiendo del tipo de contenido y la ruta que se le pase.
headers=headers) f = urllib2.urlopen(req) response = f.read() f.close() logger.info("get_data: response %s" % response) data = jsontools.load_json(response) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info("get_data: error en xbmc_json_rpc_url: %s" % message) data = ["error"] else: try: data = jsontools.load_json( xbmc.executeJSONRPC(jsontools.dump_json(payload))) except Exception, ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info( "get_data:: error en xbmc.executeJSONRPC: {0}".format(message)) data = ["error"] logger.info("get_data: data %s" % data) return data def update(content_type=FOLDER_TVSHOWS, folder=""): """ Actualiza la libreria dependiendo del tipo de contenido y la ruta que se le pase.
def findvideos(item): logger.info("pelisalacarta.channels.puyasubs findvideos") if item.infoLabels["tmdb_id"] and not item.infoLabels["plot"]: from core import tmdb tmdb.set_infoLabels_item(item, True, idioma_busqueda="en") itemlist = list() data = scrapertools.downloadpage(item.url) idiomas = scrapertools.find_single_match(data, 'Subtitulo:\s*(.*?)<br />') calidades = ['720p', '1080p'] torrents = scrapertools.find_multiple_matches(data, '<a href="(https://www.frozen-layer.com/descargas[^"]+)"') if not torrents: torrents = scrapertools.find_multiple_matches(data, '<a href="(https://www.nyaa.se/\?page=view[^"]+)"') if torrents: for i, enlace in enumerate(torrents): title = "Ver por Torrent %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append(item.clone(title=title, action="play", url=enlace, server="torrent")) onefichier = scrapertools.find_multiple_matches(data, '<a href="(https://1fichier.com/[^"]+)"') if onefichier: for i, enlace in enumerate(onefichier): title = "Ver por 1fichier %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append(item.clone(title=title, action="play", url=enlace, server="onefichier")) safelink = scrapertools.find_multiple_matches(data, '<a href="(http(?:s|)://safelinking.net/[^"]+)"') if safelink: for i, safe in enumerate(safelink): headers = [['Content-Type', 'application/json;charset=utf-8']] hash = safe.rsplit("/", 1)[1] post = jsontools.dump_json({"hash": hash}) data_sf = scrapertools.downloadpage("http://safelinking.net/v1/protected", post, headers) data_sf = jsontools.load_json(data_sf) for link in data_sf.get("links"): enlace = link["url"] domain = link["domain"] title = "Ver por %s" % domain action = "play" if "mega" in domain: server = "mega" if "/#F!" in enlace: action = "carpeta" elif "1fichier" in domain: server = "onefichier" if "/dir/" in enlace: action = "carpeta" title += " %s" % idiomas if ">720p" in data and ">1080p" in data: try: title = "[%s] %s" % (calidades[i], title) except: pass itemlist.append(item.clone(title=title, action=action, url=enlace, server=server)) return itemlist
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
def convert_xml_to_json(): logger.info("pelisalacarta.platformcode.library convert_xml_to_json") ruta_seriesold = os.path.join(config.get_library_path(), "SERIES_OLD") # Si ocurre un error durante la conversion y se crean las carpetas "SERIES" # y "SERIES_OLD", al reiniciar kodi os.rename dara un error, probablemente # sera "OSError: (66, 'Directory not empty')" if path_exists(ruta_seriesold): platformtools.dialog_notification("Actualizar biblioteca", "Actualizando desde XML") import shutil shutil.rmtree(ruta_seriesold) if not path_exists(ruta_seriesold): logger.info("pelisalacarta.platformcode.library eliminado: " + ruta_seriesold) else: logger.info("ERROR. No se ha podido eliminar: " + ruta_seriesold) platformtools.dialog_notification("ERROR", "No se actualizara la biblioteca") return False else: platformtools.dialog_ok("Biblioteca: Se va a actualizar al nuevo formato", "Seleccione el nombre correcto de cada serie, si no está seguro pulse 'Cancelar'.", "Hay nuevas opciones en 'Biblioteca' y en la 'configuración' del addon.") # TODO soporte samba os.rename(TVSHOWS_PATH, os.path.join(config.get_library_path(), "SERIES_OLD")) if not path_exists(TVSHOWS_PATH): make_dir(TVSHOWS_PATH) if path_exists(TVSHOWS_PATH): fname = join_path(config.get_data_path(), TVSHOW_FILE_OLD) dict_data = {} # TODO compatible con samba if path_exists(fname): try: with open(fname, "r") as f: for line in f: aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item() serie.infoLabels = {} patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(tvshow) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow create_nfo = False # Abrir ventana de seleccion para identificar la serie serie = get_video_id_from_scraper(serie, True) if 'id_Tmdb' in serie.infoLabels: tvshow_id = serie.infoLabels['id_Tmdb'] create_nfo = True else: tvshow_id = "t_{0}_[{1}]".format(tvshow.strip().replace(" ", "_"), channel) path = join_path(TVSHOWS_PATH, title_to_filename("{0} [{1}]".format( tvshow.strip().lower(), channel))) logger.info("pelisalacarta.platformcode.library savelibrary Creando directorio serie:" + path) try: make_dir(path) if create_nfo: create_nfo_file(tvshow_id, path, "serie") except OSError as exception: if exception.errno != errno.EEXIST: raise # Si la serie no existe en el registro ... if tvshow_id not in dict_data: # ... añadir la serie al registro dict_data[tvshow_id] = {"name": serie.infoLabels['title'], "channels": {}} # Si no hay datos del canal en el registro para esta serie... if channel not in dict_data[tvshow_id]["channels"]: # ... añadir canal al registro de la serie dict_channel = {"tvshow": tvshow.strip(), "url": url, "path": path} dict_data[tvshow_id]["channels"][channel] = dict_channel except EnvironmentError: logger.info("ERROR al leer el archivo: {0}".format(fname)) else: # todo soporte samba os.rename(join_path(config.get_data_path(), TVSHOW_FILE_OLD), join_path(config.get_data_path(), "series_old.xml")) json_data = jsontools.dump_json(dict_data) save_file(json_data, join_path(config.get_data_path(), TVSHOW_FILE)) else: logger.info("ERROR, no se ha podido crear la nueva carpeta de SERIES") else: logger.info("ERROR, no se ha podido renombrar la antigua carpeta de SERIES") # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen xbmc.executebuiltin("CleanLibrary(video)")