def backups(item): from platformcode import platformtools logger.info("pelisalacarta.channel.configuracion backups") ruta = filetools.join(config.get_data_path(), "backups") ruta_split = "" if "ruta" in item.title: heading = "Ruta de copias de seguridad" if not filetools.exists(ruta): folders = "Carpeta no creada" else: folders = str(len(filetools.listdir(ruta))) + " copia/s de seguridad guardadas" if len(ruta) > 55: ruta_split = ruta[55:] ruta = ruta[:55] platformtools.dialog_ok(heading, ruta, ruta_split, folders) else: if not filetools.exists(ruta): platformtools.dialog_ok("La carpeta no existe", "No hay copias de seguridad guardadas") else: dyesno = platformtools.dialog_yesno("Las copias de seguridad se eliminarán", "¿Está seguro?") if dyesno: import shutil shutil.rmtree(ruta, ignore_errors=True)
def create_tvshows_from_xml(): logger.info("fusionse.platformcode.library_service create_tvshows_from_xml") fname = filetools.join(config.get_data_path(), library.TVSHOW_FILE_OLD) if filetools.exists(fname): platformtools.dialog_ok("Libreria: Si aggiornerà al nuovo formato", "Selezionare il nome corretto di ogni serie, se non siete sicuri potete 'Annulla'.", "Ci sono nuove opzioni per la 'Libreria' in 'configurazione'.") filetools.rename(library.TVSHOWS_PATH, "SERIES_OLD") if not filetools.exists(library.TVSHOWS_PATH): filetools.mkdir(library.TVSHOWS_PATH) if filetools.exists(library.TVSHOWS_PATH): try: data = filetools.read(fname) for line in data.splitlines(): aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item(contentSerieName=tvshow, url=url, channel=channel, action="episodios", title=tvshow, active=True) patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(serie.contentSerieName) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow library.save_library_tvshow(serie, list()) filetools.rename(fname, "series.xml.old") # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen library.clean() except EnvironmentError: logger.info("ERROR al leer el archivo: {0}".format(fname)) 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") return True return False
def verify_directories_created(): from core import logger from core import filetools from platformcode import xbmc_library config_paths = [["librarypath", "library"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) # Biblioteca if path == "librarypath": set_setting("library_version", "v4") if not saved_path: saved_path = xbmc_library.search_library_path() if saved_path: set_setting(path, saved_path) if not saved_path: saved_path = "special://profile/addon_data/plugin.video." + PLUGIN_NAME + "/" + default set_setting(path, saved_path) if get_setting("library_set_content")== "true" and path in ["librarypath","downloadpath"]: xbmc_library.add_sources(saved_path) saved_path = xbmc.translatePath(saved_path) if not filetools.exists(saved_path): logger.debug("Creating %s: %s" % (path, saved_path)) filetools.mkdir(saved_path) config_paths = [["folder_movies", "CINE"], ["folder_tvshows", "SERIES"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = default set_setting(path, saved_path) content_path = filetools.join(get_library_path(), saved_path) if not filetools.exists(content_path): logger.debug("Creating %s: %s" % (path, content_path)) if filetools.mkdir(content_path) and get_setting("library_set_content")== "true": xbmc_library.set_content(default) elif get_setting("library_ask_set_content") == "active": xbmc_library.set_content(default)
def create_tvshows_from_xml(): logger.info("pelisalacarta.platformcode.library_service create_tvshows_from_xml") fname = filetools.join(config.get_data_path(), library.TVSHOW_FILE_OLD) if filetools.exists(fname): 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.") filetools.rename(library.TVSHOWS_PATH, "SERIES_OLD") if not filetools.exists(library.TVSHOWS_PATH): filetools.mkdir(library.TVSHOWS_PATH) if filetools.exists(library.TVSHOWS_PATH): try: data = filetools.read(fname) for line in data.splitlines(): aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item(contentSerieName=tvshow, url=url, channel=channel, action="episodios", title=tvshow, active=True) patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(serie.contentSerieName) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow library.save_library_tvshow(serie, list()) filetools.rename(fname, "series.xml.old") # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen library.clean() except EnvironmentError: logger.info("ERROR al leer el archivo: {0}".format(fname)) 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") return True return False
def download_thumb(filename, url): from core import downloadtools lock = threading.Lock() lock.acquire() folder = filetools.join(config.get_data_path(), 'thumbs_copiapop') if not filetools.exists(folder): filetools.mkdir(folder) lock.release() if not filetools.exists(filename): downloadtools.downloadfile(url, filename, silent=True) return filename
def play(item): logger.info() itemlist = [] try: from core import filetools ficherosubtitulo = filetools.join( config.get_data_path(), 'subtitulo_areadocu.srt' ) if filetools.exists(ficherosubtitulo): try: filetools.remove(ficherosubtitulo) except IOError: logger.info("Error al eliminar el archivo "+ficherosubtitulo) raise data = httptools.downloadpage(item.subtitle, headers={'Referer': item.extra}).data filetools.write(ficherosubtitulo, data) subtitle = ficherosubtitulo except: subtitle = "" logger.info("Error al descargar el subtítulo") extension = item.url.rsplit("|", 1)[0][-4:] itemlist.append(['%s %s [directo]' % (extension, item.calidad), item.url, 0, subtitle]) #itemlist.append(item.clone(subtitle=subtitle)) return itemlist
def mark_content_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_content_as_watched") # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): url_scraper = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == "movie": name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == "episode": name_file = item.contentSeason + "x" + item.contentEpisodeNumber else: name_file = item.contentTitle if not hasattr(it, "library_playcounts"): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != "movie": it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, url_scraper + it.tojson()): item.infoLabels["playcount"] = item.playcount if item.contentType == "tvshow": # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def create_tvshows_from_json(_actualizado): logger.info("pelisalacarta.platformcode.library_service create_tvshows_from_json") fname = filetools.join(config.get_data_path(), library.TVSHOW_FILE) if filetools.exists(fname): if not _actualizado: platformtools.dialog_ok("Biblioteca: Actualizando formato", "Espere por favor mientras se completa el proceso") try: data = jsontools.loads(filetools.read(fname)) for tvshow in data: for channel in data[tvshow]["channels"]: serie = Item(contentSerieName=data[tvshow]["channels"][channel]["tvshow"], url=data[tvshow]["channels"][channel]["url"], channel=channel, action="episodios", title=data[tvshow]["name"], active=True) if not tvshow.startswith("t_"): serie.infoLabels["tmdb_id"] = tvshow library.save_library_tvshow(serie, list()) filetools.rename(fname, "series.json.old") except EnvironmentError: logger.info("ERROR al leer el archivo: {0}".format(fname))
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def peliculas(item): logger.info() itemlist = [] for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): for f in ficheros: if f.endswith(".nfo"): nfo_path = filetools.join(raiz, f) head_nfo, new_item = library.read_nfo(nfo_path) new_item.nfo = nfo_path new_item.path = raiz new_item.thumbnail = new_item.contentThumbnail new_item.text_color = "blue" if not filetools.exists(filetools.join(new_item.path, filetools.basename(new_item.strm_path))): # Si se ha eliminado el strm desde la bilbioteca de kodi, no mostrarlo continue # Menu contextual: Marcar como visto/no visto visto = new_item.library_playcounts.get(os.path.splitext(f)[0], 0) new_item.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Segna film come non visto" contador = 0 else: texto_visto = "Segna film come visto" contador = 1 # Menu contextual: Eliminar serie/canal num_canales = len(new_item.library_urls) if "descargas" in new_item.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Elimina film/canale" multicanal = True else: texto_eliminar = "Elimina questo film" multicanal = False new_item.context = [{"title": texto_visto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": contador}, {"title": texto_eliminar, "action": "eliminar", "channel": "biblioteca", "multicanal": multicanal}] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "biblioteca"}] #logger.debug("new_item: " + new_item.tostring('\n')) itemlist.append(new_item) return sorted(itemlist, key=lambda it: it.title.lower())
def read_favourites(): favourites_list = [] if filetools.exists(FAVOURITES_PATH): data = filetools.read(FAVOURITES_PATH) matches = scrapertools.find_multiple_matches(data, "<favourite([^<]*)</favourite>") for match in matches: name = scrapertools.find_single_match(match, 'name="([^"]*)') thumb = scrapertools.find_single_match(match, 'thumb="([^"]*)') data = scrapertools.find_single_match(match, '[^>]*>([^<]*)') favourites_list.append((name,thumb,data)) return favourites_list
def backups(item): logger.info() ruta = filetools.join(config.get_data_path(), 'backups') ruta_split = "" if "ruta" in item.title: heading = "Ruta de copias de seguridad" if not filetools.exists(ruta): folders = "Carpeta no creada" else: folders = str(len(filetools.listdir(ruta))) + " copia/s de seguridad guardadas" if len(ruta) > 55: ruta_split = ruta[55:] ruta = ruta[:55] platformtools.dialog_ok(heading, ruta, ruta_split, folders) else: if not filetools.exists(ruta): platformtools.dialog_ok("La carpeta no existe", "No hay copias de seguridad guardadas") else: dyesno = platformtools.dialog_yesno("Las copias de seguridad se eliminarán", "¿Está seguro?") if dyesno: import shutil shutil.rmtree(ruta, ignore_errors=True)
def clean_watched_new_version(): try: info_file = dict() watched_file = dict() if filetools.exists(info_file_path): info_file = jsontools.load(filetools.read(info_file_path)) if filetools.exists(data_path): watched_file = jsontools.load(filetools.read(data_path)) for msg, values in list(info_file.items()): if values.get('version', False) and watched_file.get(msg): del watched_file[msg] watched_file_atl = watched_file.copy() for msg in watched_file_atl: if not info_file.get(msg): del watched_file[msg] filetools.write(data_path, jsontools.dump(watched_file)) except: logger.error(traceback.format_exc())
def read_favourites(): favourites_list = [] if filetools.exists(FAVOURITES_PATH): data = filetools.read(FAVOURITES_PATH) matches = scrapertools.find_multiple_matches( data, "<favourite([^<]*)</favourite>") for match in matches: name = scrapertools.find_single_match(match, 'name="([^"]*)') thumb = scrapertools.find_single_match(match, 'thumb="([^"]*)') data = scrapertools.find_single_match(match, '[^>]*>([^<]*)') favourites_list.append((name, thumb, data)) return favourites_list
def save_library_tvshow(item, episodelist): """ guarda en la libreria de series la serie con todos los capitulos incluidos en la lista episodelist @type item: item @param item: item que representa la serie a guardar @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos o -1 si ha fallado toda la serie """ logger.info("streamondemand.platformcode.library save_library_tvshow") # Itentamos obtener el titulo correcto: # 1. contentSerieName: Este deveria ser el sitio correcto # 2. show titulo = item.contentSerieName if not titulo: titulo = item.show # Colocamos el titulo en su sitio para que tmdb lo localize item.contentSerieName = titulo # establecemos "active" para que se actualice cuando se llame a library_service item.active = True # Si llegados a este punto no tenemos titulo, salimos if not item.contentSerieName or not item.channel: return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llame a uno u otro tmdb.find_and_set_infoLabels_tmdb( item, config.get_setting("scrap_ask_name") == "true") path = filetools.join( TVSHOWS_PATH, "{0} [{1}]".format(item.contentSerieName.strip().lower(), item.channel).lower()) if not filetools.exists(path): logger.info( "streamondemand.platformcode.library save_library_tvshow Creando directorio serie:" + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
def get_video_url(page_url, premium=False, user="", password="", video_password=""): import xbmc from xbmcaddon import Addon logger.debug("(page_url='%s')" % page_url) video_urls = [] video_id = scrapertools.find_single_match(page_url, '(?:v=|embed/)([A-z0-9_-]{11})') inputstream = platformtools.install_inputstream() try: __settings__ = Addon(name) if inputstream: __settings__.setSetting('kodion.video.quality.mpd', 'true') else: __settings__.setSetting('kodion.video.quality.mpd', 'false') # video_urls = [['con YouTube', 'plugin://plugin.video.youtube/play/?video_id=' + video_id ]] except: path = xbmc.translatePath('special://home/addons/' + name) if filetools.exists(path): if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70818)): xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "' + name + '", "enabled": true }}') else: return [['', '']] else: xbmc.executebuiltin('InstallAddon(' + name + ')', wait=True) try: Addon(name) except: return [['', '']] my_addon = xbmcaddon.Addon('plugin.video.youtube') addon_dir = xbmc.translatePath(my_addon.getAddonInfo('path')) sys.path.append(filetools.join(addon_dir, 'resources', 'lib')) from youtube_resolver import resolve for stream in resolve(page_url): # title = scrapertools.find_single_match(stream['title'], '(\d+p)') if scrapertools.find_single_match(stream['title'], r'(\d+p)'): video_urls.append( [re.sub(r'(\[[^\]]+\])', '', stream['title']), stream['url']]) video_urls.sort(key=lambda it: int(it[0].split("p", 1)[0])) return video_urls
def backups(item): from platformcode import platformtools logger.info() ruta = filetools.join(config.get_data_path(), 'backups') ruta_split = "" if "ruta" in item.title: heading = "Percorso di backup" if not filetools.exists(ruta): folders = "Directory non creata" else: folders = str(len(filetools.listdir(ruta))) + " copia/e di backup" if len(ruta) > 55: ruta_split = ruta[55:] ruta = ruta[:55] platformtools.dialog_ok(heading, ruta, ruta_split, folders) else: if not filetools.exists(ruta): platformtools.dialog_ok("La cartella non esiste", "Nessun backup salvato") else: dyesno = platformtools.dialog_yesno("I backup vengono cancellati", "Sei sicuro?") if dyesno: import shutil shutil.rmtree(ruta, ignore_errors=True)
def update_external_addon(addon_name): logger.info(addon_name) #Verificamos que el addon está instalado if xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % addon_name): #Path de actuali<aciones de Alfa alfa_addon_updates = filetools.join(config.get_runtime_path(), filetools.join("lib", addon_name)) #Path de destino en addon externo __settings__ = xbmcaddon.Addon(id="plugin.video." + addon_name) if addon_name.lower() in ['quasar', 'elementum']: addon_path = filetools.join(xbmc.translatePath(__settings__.getAddonInfo('Path')), \ filetools.join("resources", filetools.join("site-packages", addon_name))) else: addon_path = '' #Hay modificaciones en Alfa? Las copiamos al addon if filetools.exists(alfa_addon_updates) and filetools.exists(addon_path): for root, folders, files in filetools.walk(alfa_addon_updates): for file in files: input_file = filetools.join(root, file) output_file = input_file.replace(alfa_addon_updates, addon_path) if not filetools.copy(input_file, output_file, silent=True): logger.error('Error en la copia: Input: %s o Output: %s' % (input_file, output_file)) return False return True else: logger.error('Alguna carpeta no existe: Alfa: %s o %s: %s' % (alfa_addon_updates, addon_name, addon_path)) # Se ha desinstalado Quasar, reseteamos la opción else: config.set_setting('addon_quasar_update', False) if filetools.exists(filetools.join(config.get_data_path(), "%s.json" % addon_name)): filetools.remove(filetools.join(config.get_data_path(), "%s.json" % addon_name)) return True return False
def verify_directories_created(): from platformcode import logger from core import filetools config_paths = [["videolibrarypath", "library"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["bookmarkpath", "favorites"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = filetools.join(get_data_path(), *default.split("/")) set_setting(path, saved_path) if not filetools.exists(saved_path): logger.debug("Creating %s: %s" % (path, saved_path)) filetools.mkdir(saved_path) config_paths = [["folder_movies", "CINE"], ["folder_tvshows", "SERIES"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = default set_setting(path, saved_path) content_path = filetools.join(get_videolibrary_path(), saved_path) if not filetools.exists(content_path): logger.debug("Creating %s: %s" % (path, content_path)) # si se crea el directorio filetools.mkdir(content_path)
def download(item=None): if filetools.exists(quasar_path): xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "plugin.video.quasar", "enabled": false }}' ) sleep(1) filetools.rmdirtree(quasar_path) if filetools.exists(filename): filetools.remove(filename) return download() else: platform = get_platform() support.log('OS:', platform) support.log('Extract IN:', quasar_path) url = support.match( quasar_url, patronBlock= r'<div class="release-entry">(.*?)<!-- /.release-body -->', patron=r'<a href="([a-zA-Z0-9/\.-]+%s.zip)' % platform).match support.log('URL:', url) if url: downloadtools.downloadfile(host + url, filename) extract()
def showOnce(): if not config.get_all_settings_addon(): logger.error('corrupted settings.xml!!') settings_xml = filetools.join(config.get_data_path(), 'settings.xml') settings_bak = filetools.join(config.get_data_path(), 'settings.bak') if filetools.exists(settings_bak): filetools.copy(settings_bak, settings_xml, True) logger.info('restored settings.xml from backup') else: filetools.write( settings_xml, '<settings version="2">\n</settings>') # resetted settings else: from platformcode import xbmc_videolibrary xbmc_videolibrary.ask_set_content(silent=False) config.set_setting('show_once', True)
def get_video_url(page_url, premium=False, user="", password="", video_password=""): import xbmc from xbmcaddon import Addon logger.info("(page_url='%s')" % page_url) video_urls = [] if not page_url.startswith("http"): page_url = "http://www.youtube.com/watch?v=%s" % page_url logger.info(" page_url->'%s'" % page_url) video_id = scrapertools.find_single_match(page_url, '(?:v=|embed/)([A-z0-9_-]{11})') inputstream = platformtools.install_inputstream() # from core.support import dbg;dbg() try: __settings__ = Addon(name) if inputstream: __settings__.setSetting('kodion.video.quality.mpd', 'true') else: __settings__.setSetting('kodion.video.quality.mpd', 'false') video_urls = [[ 'con YouTube', 'plugin://plugin.video.youtube/play/?video_id=' + video_id ]] except: if filetools.exists( xbmc.translatePath('special://profile/addon_data/' + name)): if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70818)): xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "' + name + '", "enabled": true }}') else: return [['', '']] else: xbmc.executebuiltin('InstallAddon(' + name + ')', wait=True) try: Addon(name) except: return [['', '']] return get_video_url(page_url) return video_urls
def android_workaround(self, new_dest_path): ### Alfa (entera) import subprocess for libname in get_libname(self.platform): libpath=os.path.join(self.dest_path, libname) size=str(os.path.getsize(libpath)) new_libpath=os.path.join(new_dest_path, libname) if filetools.exists(new_libpath): new_size=str(os.path.getsize(new_libpath)) if size != new_size: filetools.remove(new_libpath) if filetools.exists(new_libpath): try: command = ['su', '-c', 'rm', '%s' % new_libpath] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output_cmd, error_cmd = p.communicate() log('Comando ROOT: %s' % str(command)) except: log('Sin PERMISOS ROOT: %s' % str(command)) if not filetools.exists(new_libpath): log('Deleted: (%s) %s -> (%s) %s' %(size, libpath, new_size, new_libpath)) if not filetools.exists(new_libpath): filetools.copy(libpath, new_libpath, silent=True) ### ALFA log('Copying... %s -> %s' %(libpath, new_libpath)) if not filetools.exists(new_libpath): try: command = ['su', '-c', 'cp', '%s' % libpath, '%s' % new_libpath] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output_cmd, error_cmd = p.communicate() log('Comando ROOT: %s' % str(command)) command = ['su', '-c', 'chmod', '777', '%s' % new_libpath] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output_cmd, error_cmd = p.communicate() log('Comando ROOT: %s' % str(command)) except: log('Sin PERMISOS ROOT: %s' % str(command)) if not filetools.exists(new_libpath): log('ROOT Copy Failed!') else: command = ['chmod', '777', '%s' % new_libpath] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output_cmd, error_cmd = p.communicate() log('Comando: %s' % str(command)) else: log('Module exists. Not copied... %s' % new_libpath) ### ALFA return new_dest_path
def eliminar_lista(item): logger.info() fullfilename = filetools.join(trackingtools.get_tracking_path(), item.lista) if not filetools.exists(fullfilename): platformtools.dialog_ok(config.__addon_name, 'Error, no se encuentra la lista!', item.lista) return False if item.lista.replace('.sqlite', '') == trackingtools.get_current_dbname(): platformtools.dialog_ok(config.__addon_name, 'La lista activa no se puede eliminar!', item.lista) return False if not platformtools.dialog_yesno('Eliminar lista', '¿Estás seguro de querer borrar la lista %s ?' % item.lista): return False filetools.remove(fullfilename) platformtools.itemlist_refresh() return True
def check_db(): if filetools.exists(db_path): conn = sqlite3.connect(db_path) c = conn.cursor() c.execute('UPDATE availables SET info="", new=0, release="" WHERE new=1 AND wish=0') conn.commit() conn.execute("VACUUM") conn.close() return False else: conn = sqlite3.connect(db_path) c = conn.cursor() c.execute('CREATE TABLE IF NOT EXISTS availables (tmdb_id, info, new, release, wish)') conn.commit() conn.close() return True
def mainlist(item): itemlist = list() status = config.get_setting("autoscan", item.channel) if not status: from platformcode import platformtools opt = platformtools.dialog_yesno("Alfa - Lista de deseos", "Para agregar elementos a esta sección necesitas activar la busqueda de estrenos y sugerencias." " Deseas activarla ahora?") if opt: config.set_setting("autoscan", True, item.channel) Thread(target=autoscan).start() if not filetools.exists(db_path): return itemlist itemlist.append(Item(channel=item.channel, title="Configuración", thumbnail=get_thumb("setting_0.png"), action="show_settings")) conn = sqlite3.connect(db_path) c = conn.cursor() c.execute("SELECT * FROM availables WHERE wish=1") results = c.fetchall() c.close() for x in results: infolabels = jsontools.load(x[1]) infolabels["quality"] = "" infolabels["language"] = "" context = [{"title": "Quitar de la lista", "action": "set_checked", "channel": item.channel, "contextual": True, "value": 0} ] itemlist.append(Item(channel="search", action='from_context', title="", text=infolabels["title"], contentType="movie", context=context, infoLabels=infolabels)) tmdb.set_infoLabels_itemlist(itemlist[1:], seekTmdb=True) return itemlist
def extract(): import zipfile support.log('Estraggo Quasar in:', quasar_path) with zipfile.ZipFile(filename, 'r') as zip_ref: zip_ref.extractall(xbmc.translatePath("special://home/addons/")) xbmc.executebuiltin('UpdateLocalAddons') if platformtools.dialog_ok('Quasar', config.get_localized_string(70783)): if filetools.exists(filename): filetools.remove(filename) xbmc.executeJSONRPC( '{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "plugin.video.quasar", "enabled": true }}' ) updater.refreshLang() xbmcaddon.Addon(id="plugin.video.quasar").setSetting( 'download_path', config.get_setting('downloadpath')) xbmc.executebuiltin('UpdateLocalAddons') sleep(2)
def search_for_unrar_in_error(download_paths, init=False): logger.info(download_paths) for torrent_client, path in download_paths: list_dir = filetools.listdir(path) for folder_w in list_dir: folder = filetools.join(path, folder_w) if filetools.isdir(folder): if not filetools.exists(filetools.join(folder, '_rar_control.json')): continue else: if not '_rar_control.json' in folder: continue rar_control = jsontools.load(filetools.read(filetools.join(folder, '_rar_control.json'))) rar_control['status'] += ': Recovery' if ('UnRARing' in rar_control['status'] or 'RECOVERY' in rar_control['status']) and not init: continue if 'UnRARing' in rar_control['status'] or 'ERROR' in rar_control['status']: rar_control['status'] = 'RECOVERY: ' + rar_control['status'] rar_control['download_path'] = folder rar_control['torr_client'] = torrent_client if 'ERROR' in rar_control['status'] or 'UnRARing' in rar_control['status'] \ or 'RECOVERY' in rar_control['status']: rar_control['error'] += 1 ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), jsontools.dump(rar_control)) logger.debug('%s, %s, %s, %s, %s, %s' % (rar_control['download_path'], \ rar_control['rar_names'][0], rar_control['password'], \ str(rar_control['error']), rar_control['error_msg'], rar_control['status'])) if ('ERROR' in rar_control['status'] and rar_control['error'] > 2) \ or ('UnRARing' in rar_control['status'] and rar_control['error'] > 3) \ or ('RECOVERY' in rar_control['status'] and rar_control['error'] > 3) \ or 'DONE' in rar_control['status']: continue if ret: try: threading.Thread(target=call_unrar, args=(rar_control,)).start() # Creamos un Thread independiente por UnRAR time.sleep(1) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, pasamos al siguiente logger.error(traceback.format_exc()) if not init: sys.exit(0)
def save_library_tvshow(item, episodelist): """ guarda en la libreria de series la serie con todos los capitulos incluidos en la lista episodelist @type item: item @param item: item que representa la serie a guardar @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos o -1 si ha fallado toda la serie """ logger.info("streamondemand.platformcode.library save_library_tvshow") # Itentamos obtener el titulo correcto: # 1. contentSerieName: Este deveria ser el sitio correcto # 2. show titulo = item.contentSerieName if not titulo: titulo = item.show # Colocamos el titulo en su sitio para que tmdb lo localize item.contentSerieName = titulo # establecemos "active" para que se actualice cuando se llame a library_service item.active = True # Si llegados a este punto no tenemos titulo, salimos if not item.contentSerieName or not item.channel: return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llame a uno u otro tmdb.find_and_set_infoLabels_tmdb(item, config.get_setting("scrap_ask_name") == "true") path = filetools.join(TVSHOWS_PATH, "{0} [{1}]".format(item.contentSerieName.strip().lower(), item.channel).lower()) if not filetools.exists(path): logger.info("streamondemand.platformcode.library save_library_tvshow Creando directorio serie:" + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
def read_nfo(path_nfo, item=None): """ Metodo para leer archivos nfo. Los arcivos nfo tienen la siguiente extructura: url_scraper | xml + item_json [url_scraper] y [xml] son opcionales, pero solo uno de ellos ha de existir siempre. @param path_nfo: ruta absoluta al archivo nfo @type path_nfo: str @param item: Si se pasa este parametro el item devuelto sera una copia de este con los valores de 'infoLabels', 'library_playcounts' y 'path' leidos del nfo @type: Item @return: Una tupla formada por la cabecera (head_nfo ='url_scraper'|'xml') y el objeto 'item_json' @rtype: tuple (str, Item) """ head_nfo = "" it = None if filetools.exists(path_nfo): head_nfo = filetools.read(path_nfo, 0, 1) data = filetools.read(path_nfo, 1) if not head_nfo.startswith('http'): # url_scraper no valida, xml presente head_nfo = '' # TODO devolver el xml en head_nfo import re data = re.sub(r"\n|\r|\t|\s{2}| ", "", data) data = re.sub("(<tvshow>|<movie>)(.*?)(</tvshow>|</movie>)", "", data) it_nfo = Item().fromjson(data) if item: it = item.clone() it.infoLabels = it_nfo.infoLabels if 'library_playcounts' in it_nfo: it.library_playcounts = it_nfo.library_playcounts if it_nfo.path: it.path = it_nfo.path else: it = it_nfo if 'fanart' in it.infoLabels: it.fanart = it.infoLabels['fanart'] return head_nfo, it
def copy_file(item): logger.info() from core import filetools MIS_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'Mis_Torrents') MIS_TORRENT_BTDIGG_FOLDER = filetools.join(MIS_TORRENT_FOLDER, 'BTDigg - resultados') if not filetools.exists(MIS_TORRENT_BTDIGG_FOLDER): filetools.mkdir(MIS_TORRENT_BTDIGG_FOLDER) path = filetools.join(MIS_TORRENT_BTDIGG_FOLDER, filetools.validate_path(item.copytitle) + '.magnet') filetools.write(path, item.url, silent=True) platformtools.dialog_notification( 'Copiando MAGNET', filetools.validate_path(item.copytitle) + '.magnet')
def get_server_json(server_name): # logger.info("server_name=" + server_name) try: server_path = filetools.join(config.get_runtime_path(), "servers", server_name + ".json") if not filetools.exists(server_path): server_path = filetools.join(config.get_runtime_path(), "servers", "debriders", server_name + ".json") # logger.info("server_path=" + server_path) server_json = jsontools.load(filetools.read(server_path)) # logger.info("server_json= %s" % server_json) except Exception as ex: template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(" %s" % message) server_json = None return server_json
def read_nfo(path_nfo, item=None): url_scraper = "" it = None if filetools.exists(path_nfo): url_scraper = filetools.read(path_nfo, 0, 1) if item: it = item.clone() it_nfo = Item().fromjson(filetools.read(path_nfo, 1)) it.infoLabels = it_nfo.infoLabels if "library_playcounts" in it_nfo: it.library_playcounts = it_nfo.library_playcounts if it_nfo.path: it.path = it_nfo.path else: it = Item().fromjson(filetools.read(path_nfo, 1)) if "fanart" in it.infoLabels: it.fanart = it.infoLabels["fanart"] return url_scraper, it
def search_library_path(): logger.info() cine = config.get_setting('folder_movies', default='CINE') series = config.get_setting('folder_tvshows', default='SERIES') cine_win = '\\%s\\' % cine cine_res = '/%s/' % cine series_win = '\\%s\\' % series series_res = '/%s/' % series sql = 'SELECT strPath FROM path WHERE (idParentPath IS NULL AND strContent IS NOT NULL AND (' + \ 'strPath LIKE "%library' + cine_win + '" or strPath LIKE "%library' + cine_res + \ '" or strPath LIKE "%library' + series_win + '" or strPath LIKE "%library' + series_res + '"))' nun_records, records = execute_sql_kodi(sql) if nun_records >= 1: logger.debug(records) resp = filetools.join(filetools.dirname(records[0][0][:-1]), ' ').rstrip() if filetools.exists(resp): return resp return None
def read_nfo(path_nfo, item=None): url_scraper = "" it = None if filetools.exists(path_nfo): url_scraper = filetools.read(path_nfo, 0, 1) if item: it = item.clone() it_nfo = Item().fromjson(filetools.read(path_nfo, 1)) it.infoLabels = it_nfo.infoLabels if 'library_playcounts' in it_nfo: it.library_playcounts = it_nfo.library_playcounts if it_nfo.path: it.path = it_nfo.path else: it = Item().fromjson(filetools.read(path_nfo, 1)) if 'fanart' in it.infoLabels: it.fanart = it.infoLabels['fanart'] return url_scraper, it
def copiar_lista(item): logger.info() import xbmcgui origen = xbmcgui.Dialog().browseSingle(1, 'Selecciona el fichero .sqlite a copiar', 'files', '.sqlite', False, False, '') # 1:ShowAndGetFile if origen is None or origen == '': return False lista_origen = filetools.basename(origen) destino = filetools.join(trackingtools.get_tracking_path(), lista_origen) if filetools.exists(destino): lista_origen = lista_origen.replace('.sqlite', '') + '-' + datetime.now().strftime('%Y%m%d-%H%M%S') + '.sqlite' destino = filetools.join(trackingtools.get_tracking_path(), lista_origen) platformtools.dialog_ok(config.__addon_name, 'Ya existe una lista con este nombre, se le añade un sufijo para diferenciarla.', lista_origen) if not filetools.copy(origen, destino, silent=False): platformtools.dialog_ok(config.__addon_name, 'Error, no se ha podido copiar la lista!', origen, destino) return False platformtools.itemlist_refresh() return True
def verify_directories_created(): from core import logger from core import filetools config_paths = [["librarypath", "library"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["bookmarkpath", "favorites"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = filetools.join(get_data_path(), *default.split("/")) set_setting(path, saved_path) if not filetools.exists(saved_path): logger.debug("Creating %s: %s" % (path, saved_path)) filetools.mkdir(saved_path) #Biblioteca if path == "librarypath": set_setting("library_version", "v4")
def crear_lista(item): logger.info() titulo = platformtools.dialog_input(default='', heading='Nombre de la lista') if titulo is None or titulo == '': return False titulo = config.text_clean(titulo, blank_char='_') filename = titulo.replace('.sqlite', '') + '.sqlite' fullfilename = filetools.join(trackingtools.get_tracking_path(), filename) # Comprobar que el fichero no exista ya if filetools.exists(fullfilename): platformtools.dialog_ok(config.__addon_name, 'Error, ya existe una lista con este nombre!', filename) return False # Provocar que se guarde db = trackingtools.TrackingData(filename) db.close(commit=True) platformtools.itemlist_refresh() return True
def verify_directories_created(): from core import logger from core import filetools config_paths = [["librarypath", "library"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = "special://profile/plugin_data/video/pelisalacarta/" + default set_setting(path, saved_path) saved_path = xbmc.translatePath(saved_path) if not filetools.exists(saved_path): logger.debug("Creating %s: %s" % (path, saved_path)) filetools.mkdir(saved_path) # Biblioteca if path == "librarypath": set_setting("library_version", "v4")
def reactivate_unrar(init=False, mute=True): logger.info() from servers import torrent torrent_paths = torrent.torrent_dirs() download_paths = [] for torr_client, save_path_videos in list(torrent_paths.items()): if 'BT' not in torr_client and 'MCT' not in torr_client: torr_client = torr_client.lower() if '_' not in torr_client and '_web' not in torr_client and save_path_videos \ and save_path_videos not in str(download_paths): download_paths.append((torr_client, save_path_videos)) # Agregamos el path para este Cliente # Borramos archivos de control "zombies" rar_control = {} if filetools.exists(filetools.join(save_path_videos, '_rar_control.json')): rar_control = jsontools.load(filetools.read(filetools.join(save_path_videos, '_rar_control.json'))) if rar_control and len(rar_control['rar_files']) == 1: ret = filetools.remove(filetools.join(save_path_videos, '_rar_control.json'), silent=True) search_for_unrar_in_error(download_paths, init=init)
def export_videolibrary(item): logger.info() zip_file_folder = platformtools.dialog_browse( 3, config.get_localized_string(80002)) if zip_file_folder == "": return zip_file = u'' + xbmc.translatePath(zip_file_folder + "KoD_video_library-" + str(datetime.date.today()) + ".zip") p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), config.get_localized_string(80003)) p_dialog.update(0) if filetools.exists(temp_path): filetools.rmdirtree(temp_path) filetools.mkdir(temp_path) p_dialog.update(25) filetools.mkdir(movies_path) copy_tree(videolibrary_movies_path, movies_path) p_dialog.update(50) filetools.mkdir(tvshows_path) copy_tree(videolibrary_tvshows_path, tvshows_path) p_dialog.update(75) zipper = ziptools.ziptools() zipper.zip(temp_path, zip_file) filetools.rmdirtree(temp_path) p_dialog.update(100) xbmc.sleep(1000) p_dialog.close() platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80004), time=5000, sound=False)
def submenu_tools(item): import os from core import filetools logger.info() itemlist = list() #Herramientas de testeo masivo test_path = os.path.join(config.get_runtime_path(), "channels/test.py") if filetools.exists(test_path): itemlist.append(Item(channel=CHANNELNAME, title="Herramientas de Testeo masivo", action="", folder=False, thumbnail=get_thumb("channels.png"))) itemlist.append(Item(title='- Testear canales ...', channel="test", action="channel_test_selected")) itemlist.append(Item(title='- Testear servidores ...', channel="test", action="server_test_selected")) itemlist.append(Item(title='- Testear novedades!', channel="test", action="news_test_all")) itemlist.append(Item(title='- Upload tests to web!', channel="test", action="web_update_tests")) itemlist.append( Item(channel=CHANNELNAME, action="", title="", folder=False, thumbnail=get_thumb("setting_0.png"))) itemlist.append(Item(channel=CHANNELNAME, title="Herramientas de canales", action="", folder=False, thumbnail=get_thumb("channels.png"))) itemlist.append(Item(channel=CHANNELNAME, title=" Comprobar archivos *_data.json", action="conf_tools", folder=True, extra="lib_check_datajson", thumbnail=get_thumb("channels.png"))) if config.get_videolibrary_support(): itemlist.append(Item(channel=CHANNELNAME, action="", title="", folder=False, thumbnail=get_thumb("setting_0.png"))) itemlist.append(Item(channel=CHANNELNAME, title="Herramientas de videoteca", action="", folder=False, thumbnail=get_thumb("videolibrary.png"))) itemlist.append(Item(channel=CHANNELNAME, action="overwrite_tools", folder=False, thumbnail=get_thumb("videolibrary.png"), title=" Sobreescribir toda la videoteca (strm, nfo y json)")) itemlist.append(Item(channel="videolibrary", action="update_videolibrary", folder=False, thumbnail=get_thumb("videolibrary.png"), title=" Buscar nuevos episodios y actualizar videoteca")) return itemlist
def download(item=None): if filetools.exists(elementum_path): if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70783)): addon_file = filetools.file_open( filetools.join(elementum_path, 'addon.xml')).read() required = support.match(addon_file, patron=r'addon="([^"]+)').matches for r in required: xbmc.executebuiltin('InstallAddon(' + r + ')', wait=True) setting() platformtools.dialog_ok('Elementum', config.get_localized_string(70783)) else: if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70782)): pform = get_platform() url = support.match( elementum_url, patronBlock= r'<div class="release-entry">(.*?)<!-- /.release-body -->', patron=r'<a href="([a-zA-Z0-9/\.-]+%s.zip)' % pform).match support.info('OS:', pform) support.info('Extract IN:', elementum_path) support.info('URL:', url) if url: downloadtools.downloadfile(host + url, filename) extract() xbmc.sleep(1000) addon_file = filetools.file_open( filetools.join(elementum_path, 'addon.xml')).read() required = support.match(addon_file, patron=r'addon="([^"]+)').matches for r in required: xbmc.executebuiltin('InstallAddon(' + r + ')', wait=True) setting()
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc() and item.contentType == 'episode': from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi( item, item.playcount) platformtools.itemlist_refresh()
def getEpg(): now = datetime.now() fileName = support.config.get_temp_file('guidatv-') + now.strftime( '%Y %m %d') archiveName = fileName + '.gz' xmlName = fileName + '.xml' if not filetools.exists(xmlName): support.info('downloading epg') # cancello quelli vecchi for f in glob.glob(support.config.get_temp_file('guidatv-') + '*'): filetools.remove(f, silent=True) # inmemory = io.BytesIO(httptools.downloadpage(host).data) downloadtools.downloadfile(host, archiveName) support.info('opening gzip and writing xml') with gzip.GzipFile(fileobj=filetools.file_open( archiveName, mode='rb', vfs=False)) as f: guide = f.read().decode('utf-8') guide = guide.replace('\n', ' ').replace('><', '>\n<') with open(xmlName, 'w') as f: f.write(guide) # else: guide = filetools.file_open(xmlName, vfs=False) return guide
def verify_directories_created(): from core import logger from core import filetools config_paths = [["librarypath", "library"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["bookmarkpath", "favorites"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) if not saved_path: saved_path = filetools.join(get_data_path() , *default.split("/")) set_setting(path, saved_path) if not filetools.exists(saved_path): logger.debug("Creating %s: %s" % (path, saved_path)) filetools.mkdir(saved_path) #Biblioteca if path == "librarypath": set_setting("library_version", "v4")
def convert_old_to_v4(): logger.info() path_series_xml = filetools.join(config.get_data_path(), "series.xml") path_series_json = filetools.join(config.get_data_path(), "series.json") series_insertadas = 0 series_fallidas = 0 version = 'v?' # Renombrar carpeta Series y crear una vacia import time new_name = str(time.time()) path_series_old = filetools.join(library.LIBRARY_PATH, "SERIES_OLD_" + new_name) if filetools.rename(library.TVSHOWS_PATH, "SERIES_OLD_" + new_name): if not filetools.mkdir(library.TVSHOWS_PATH): logger.error("ERROR, no se ha podido crear la nueva carpeta de SERIES") return False else: logger.error("ERROR, no se ha podido renombrar la antigua carpeta de SERIES") return False path_cine_old = filetools.join(library.LIBRARY_PATH, "CINE_OLD_" + new_name) if filetools.rename(library.MOVIES_PATH, "CINE_OLD_" + new_name): if not filetools.mkdir(library.MOVIES_PATH): logger.error("ERROR, no se ha podido crear la nueva carpeta de CINE") return False else: logger.error("ERROR, no se ha podido renombrar la antigua carpeta de CINE") return False # Convertir libreria de v1(xml) a v4 if filetools.exists(path_series_xml): try: data = filetools.read(path_series_xml) for line in data.splitlines(): try: aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item(contentSerieName=tvshow, url=url, channel=channel, action="episodios", title=tvshow, active=True) patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(serie.contentSerieName) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_xml, "series.xml.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_xml) return False # Convertir libreria de v2(json) a v4 if filetools.exists(path_series_json): try: data = jsontools.load_json(filetools.read(path_series_json)) for tvshow in data: for channel in data[tvshow]["channels"]: try: serie = Item(contentSerieName=data[tvshow]["channels"][channel]["tvshow"], url=data[tvshow]["channels"][channel]["url"], channel=channel, action="episodios", title=data[tvshow]["name"], active=True) if not tvshow.startswith("t_"): serie.infoLabels["tmdb_id"] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_json, "series.json.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_json) return False # Convertir libreria de v3 a v4 if version != 'v4': # Obtenemos todos los tvshow.json de la biblioteca de SERIES_OLD recursivamente for raiz, subcarpetas, ficheros in filetools.walk(path_series_old): for f in ficheros: if f == "tvshow.json": try: serie = Item().fromjson(filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 movies_insertadas = 0 movies_fallidas = 0 for raiz, subcarpetas, ficheros in filetools.walk(path_cine_old): for f in ficheros: if f.endswith(".strm.json"): try: movie = Item().fromjson(filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_movie(movie) if fallidos == 0: movies_insertadas += 1 platformtools.dialog_notification("Película actualizada", movie.infoLabels['title']) else: movies_fallidas += 1 except: movies_fallidas += 1 config.set_setting("library_version", 'v4') platformtools.dialog_notification("Biblioteca actualizada al nuevo formato", "%s series convertidas y %s series descartadas.\n" "%s peliculas convertidas y %s peliculas descartadas." "A continuación se va a obtener la información de todos los episodios" % (series_insertadas, series_fallidas, movies_insertadas, movies_fallidas), time=12000) # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.clean() return True
def verify_directories_created(): import logger from core import filetools # Force download path if empty download_path = get_setting("downloadpath") if download_path == "": if is_xbmc(): download_path = "special://profile/addon_data/plugin.video." + PLUGIN_NAME + "/downloads" else: download_path = filetools.join(get_data_path(), "downloads") set_setting("downloadpath", download_path) # Force download list path if empty download_list_path = get_setting("downloadlistpath") if download_list_path == "": if is_xbmc(): download_list_path = "special://profile/addon_data/plugin.video." + PLUGIN_NAME + "/downloads/list" else: download_list_path = filetools.join(get_data_path(), "downloads", "list") set_setting("downloadlistpath", download_list_path) # Force bookmark path if empty bookmark_path = get_setting("bookmarkpath") if bookmark_path == "": if is_xbmc(): bookmark_path = "special://profile/addon_data/plugin.video." + PLUGIN_NAME + "/downloads/list" else: bookmark_path = filetools.join(get_data_path(), "bookmarks") set_setting("bookmarkpath", bookmark_path) # Create data_path if not exists if not os.path.exists(get_data_path()): logger.debug("Creating data_path " + get_data_path()) filetools.mkdir(get_data_path()) if is_xbmc(): # xbmc.log("Es una plataforma XBMC") if download_path.startswith("special://"): # Translate from special and create download_path if not exists download_path = xbmc.translatePath(download_path) texto = "(from special)" else: texto = "" # TODO si tiene smb se debería poder dejar que cree? filetools permite crear carpetas para SMB if not download_path.lower().startswith("smb") and not filetools.exists(download_path): logger.debug("Creating download_path" + texto + ": " + download_path) filetools.mkdir(download_path) if download_list_path.startswith("special://"): # Create download_list_path if not exists download_list_path = xbmc.translatePath(download_list_path) texto = "(from special)" else: texto = "" # TODO si tiene smb se debería poder dejar que cree? filetools permite crear carpetas para SMB if not download_list_path.lower().startswith("smb") and not filetools.exists(download_list_path): logger.debug("Creating download_list_path" + texto + ": " + download_list_path) filetools.mkdir(download_list_path) if bookmark_path.startswith("special://"): # Create bookmark_path if not exists bookmark_path = xbmc.translatePath(bookmark_path) texto = "(from special)" else: texto = "" # TODO si tiene smb se debería poder dejar que cree? filetools permite crear carpetas para SMB if not bookmark_path.lower().startswith("smb") and not filetools.exists(bookmark_path): logger.debug("Creating bookmark_path" + texto + ": " + bookmark_path) filetools.mkdir(bookmark_path) # Create library_path if not exists # TODO si tiene smb se debería poder dejar que cree? filetools permite crear carpetas para SMB if not get_library_path().lower().startswith("smb") and not os.path.exists(get_library_path()): librarypath = get_library_path() logger.debug("Creating library_path " + librarypath) if filetools.mkdir(librarypath): set_setting("library_version", "v4") # Create settings_path is not exists settings_path = filetools.join(get_data_path(), "settings_channels") if not filetools.exists(settings_path): logger.debug("Creating settings_path " + settings_path) filetools.mkdir(settings_path) # Checks that a directory "xbmc" is not present on platformcode old_xbmc_directory = os.path.join(get_runtime_path(), "platformcode", "xbmc") if os.path.exists(old_xbmc_directory): logger.debug("Removing old platformcode.xbmc directory") filetools.rmdirtree(old_xbmc_directory)
def save_library_episodes(path, episodelist, serie, silent=False, overwrite=True): """ guarda en la ruta indicada todos los capitulos incluidos en la lista episodelist @type path: str @param path: ruta donde guardar los episodios @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @type serie: item @param serie: serie de la que se van a guardar los episodios @type silent: bool @param silent: establece si se muestra la notificación @param overwrite: permite sobreescribir los ficheros existentes @type overwrite: bool @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos """ logger.info("pelisalacarta.platformcode.library save_library_episodes") # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("pelisalacarta.platformcode.library save_library_episodes No hay lista de episodios, " "salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo episodios...') p_dialog.update(0, 'Añadiendo episodio...') # fix float porque la division se hace mal en python 2.x t = float(100) / len(episodelist) for i, e in enumerate(episodelist): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Añadiendo episodio...', e.title) # Añade todos menos el que dice "Añadir esta serie..." o "Descargar esta serie..." if e.action == "add_serie_to_library" or e.action == "download_all_episodes": continue try: if e.channel == "descargas": season_episode = scrapertools.get_season_and_episode(e.contentTitle.lower()) else: season_episode = scrapertools.get_season_and_episode(e.title.lower()) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2)) except: continue strm_path = filetools.join(path, "%s.strm" % season_episode) if not filetools.exists(strm_path): # Si no existe season_episode.strm añadirlo item_strm = e.clone(action='play_from_library', channel='biblioteca', strm_path=strm_path.replace(TVSHOWS_PATH, ""), infoLabels={}) item_strm.contentSeason = e.contentSeason item_strm.contentEpisodeNumber = e.contentEpisodeNumber item_strm.contentType = e.contentType item_strm.contentTitle = season_episode # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente, if item_strm.list_idiomas: # si viene de library_service se obtiene del fichero tvshow.nfo, propiedad "library_filter_show" if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show.get(serie.channel, "") # si se ha agregado la serie lo obtenemos del titulo. else: item_strm.library_filter_show = serie.title if item_strm.library_filter_show == "": logger.error("Se ha producido un error al obtener el nombre de la serie a filtrar") # logger.debug("item_strm" + item_strm.tostring('\n')) # logger.debug("serie " + serie.tostring('\n')) filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) nfo_path = filetools.join(path, "%s.nfo" % season_episode) item_nfo = None if not filetools.exists(nfo_path) and e.infoLabels.get("tmdb_id"): # Si no existe season_episode.nfo añadirlo tmdb.find_and_set_infoLabels_tmdb(e) item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) url_scraper = "https://www.themoviedb.org/tv/%s/season/%s/episode/%s\n" % (item_nfo.infoLabels['tmdb_id'], item_nfo.contentSeason, item_nfo.contentEpisodeNumber) filetools.write(nfo_path, url_scraper + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) if filetools.exists(nfo_path) and filetools.exists(strm_path): nuevo = not filetools.exists(json_path) if nuevo or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: item_nfo = Item().fromjson(filetools.read(nfo_path, 1)) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if nuevo: logger.info("pelisalacarta.platformcode.library savelibrary Insertado: %s" % json_path) insertados += 1 # Marcamos episodio como no visto news_in_playcounts[season_episode] = 0 # Marcamos la temporada como no vista news_in_playcounts["season %s" % e.contentSeason] = 0 # Marcamos la serie como no vista # logger.debug("serie " + serie.tostring('\n')) news_in_playcounts[serie.contentTitle] = 0 else: logger.info("pelisalacarta.platformcode.library savelibrary Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("pelisalacarta.platformcode.library savelibrary Fallido: %s" % json_path) fallidos += 1 else: logger.info("pelisalacarta.platformcode.library savelibrary Fallido: %s" % json_path) fallidos += 1 if not silent and p_dialog.iscanceled(): break if not silent: p_dialog.close() if news_in_playcounts: # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ... tvshow_path = filetools.join(path, "tvshow.nfo") try: url_scraper = filetools.read(tvshow_path, 0, 1) tvshow_item = Item().fromjson(filetools.read(tvshow_path, 1)) tvshow_item.library_playcounts.update(news_in_playcounts) filetools.write(tvshow_path, url_scraper + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") fallidos = -1 # ... y actualizamos la biblioteca de Kodi if config.is_xbmc(): update(FOLDER_TVSHOWS, filetools.basename(path) + "/") if fallidos == len(episodelist): fallidos = -1 logger.debug("%s [%s]: insertados= %s, sobreescritos= %s, fallidos= %s" % (serie.contentSerieName, serie.channel, insertados, sobreescritos, fallidos)) return insertados, sobreescritos, fallidos
def download_from_url(url, item): logger.info("pelisalacarta.channels.descargas download_from_url - Intentando descargar: %s" % (url)) if url.lower().endswith(".m3u8") or url.lower().startswith("rtmp"): save_server_statistics(item.server, 0, False) return {"downloadStatus": STATUS_CODES.error} # Obtenemos la ruta de descarga y el nombre del archivo download_path = filetools.dirname(filetools.join(config.get_setting("downloadpath"), item.downloadFilename)) file_name = filetools.basename(filetools.join(config.get_setting("downloadpath"), item.downloadFilename)) # Creamos la carpeta si no existe if not filetools.exists(download_path): filetools.mkdir(download_path) # Mostramos el progreso progreso = platformtools.dialog_progress("Descargas", "Iniciando descarga...") # Lanzamos la descarga d = Downloader(url, filetools.encode(download_path), filetools.encode(file_name)) d.start() # Monitorizamos la descarga hasta que se termine o se cancele while d.state == d.states.downloading and not progreso.iscanceled(): time.sleep(0.1) line1 = "%s" % (filetools.decode(d.filename)) line2 = "%.2f%% - %.2f %s de %.2f %s a %.2f %s/s (%d/%d)" % ( d.progress, d.downloaded[1], d.downloaded[2], d.size[1], d.size[2], d.speed[1], d.speed[2], d.connections[0], d.connections[1]) line3 = "Tiempo restante: %s" % (d.remaining_time) progreso.update(int(d.progress), line1, line2, line3) # Descarga detenida. Obtenemos el estado: # Se ha producido un error en la descarga if d.state == d.states.error: logger.info("pelisalacarta.channels.descargas download_video - Error al intentar descargar %s" % (url)) d.stop() progreso.close() status = STATUS_CODES.error # Aun está descargando (se ha hecho click en cancelar) elif d.state == d.states.downloading: logger.info("pelisalacarta.channels.descargas download_video - Descarga detenida") d.stop() progreso.close() status = STATUS_CODES.canceled # La descarga ha finalizado elif d.state == d.states.completed: logger.info("pelisalacarta.channels.descargas download_video - Descargado correctamente") progreso.close() status = STATUS_CODES.completed if item.downloadSize and item.downloadSize != d.size[0]: status = STATUS_CODES.error save_server_statistics(item.server, d.speed[0], d.state != d.states.error) if progreso.iscanceled(): status = STATUS_CODES.canceled dir = os.path.dirname(item.downloadFilename) file = filetools.join(dir, filetools.decode(d.filename)) if status == STATUS_CODES.completed: move_to_libray(item.clone(downloadFilename = file)) return {"downloadUrl": d.download_url, "downloadStatus": status, "downloadSize": d.size[0], "downloadProgress": d.progress, "downloadCompleted": d.downloaded[0], "downloadFilename": file}
def execute_sql_kodi(sql): """ Ejecuta la consulta sql contra la base de datos de kodi @param sql: Consulta sql valida @type sql: str @return: Numero de registros modificados o devueltos por la consulta @rtype nun_records: int @return: lista con el resultado de la consulta @rtype records: list of tuples """ logger.info("pelisalacarta.platformcode.library execute_sql_kodi") file_db = "" nun_records = 0 records = None # Buscamos el nombre de la BBDD de videos segun la version de kodi code_db = {'10': 'MyVideos37.db', '11': 'MyVideos60.db', '12': 'MyVideos75.db', '13': 'MyVideos78.db', '14': 'MyVideos90.db', '15': 'MyVideos93.db', '16': 'MyVideos99.db', '17': 'MyVideos107.db'} video_db = code_db.get(xbmc.getInfoLabel("System.BuildVersion").split(".", 1)[0], '') if video_db: file_db = filetools.join(xbmc.translatePath("special://userdata/Database"), video_db) # metodo alternativo para localizar la BBDD if not file_db or not filetools.exists(file_db): file_db = "" for f in filetools.listdir(xbmc.translatePath("special://userdata/Database")): path_f = filetools.join(xbmc.translatePath("special://userdata/Database"), f) if filetools.isfile(path_f) and f.lower().startswith('myvideos') and f.lower().endswith('.db'): file_db = path_f break if file_db: logger.info("Archivo de BD: %s" % file_db) conn = None try: import sqlite3 conn = sqlite3.connect(file_db) cursor = conn.cursor() logger.info("Ejecutando sql: %s" % sql) cursor.execute(sql) conn.commit() records = cursor.fetchall() if sql.lower().startswith("select"): nun_records = len(records) if nun_records == 1 and records[0][0] is None: nun_records = 0 records = [] else: nun_records = conn.total_changes conn.close() logger.info("Consulta ejecutada. Registros: %s" % nun_records) except: logger.error("Error al ejecutar la consulta sql") if conn: conn.close() else: logger.debug("Base de datos no encontrada") return nun_records, records
def findvideos(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] list_canales = {} item_local = None if not item.contentTitle or not item.strm_path: logger.debug("No se pueden buscar videos por falta de parametros") return [] content_title = filter(lambda c: c not in ":*?<>|\/", item.contentTitle).strip().lower() if item.contentType == 'movie': item.strm_path = filetools.join(library.MOVIES_PATH, item.strm_path.strip('\/')) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, os.path.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(library.TVSHOWS_PATH, item.strm_path.strip('\/')) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, 'tvshow.nfo') for fd in filetools.listdir(path_dir): if fd.endswith('.json'): contenido, nom_canal = fd[:-6].split('[') if (content_title in contenido.strip() or item.contentType == 'movie') and nom_canal not in \ list_canales.keys(): list_canales[nom_canal] = filetools.join(path_dir, fd) num_canales = len(list_canales) if 'descargas' in list_canales: json_path = list_canales['descargas'] item_json = Item().fromjson(filetools.read(json_path)) del list_canales['descargas'] # Comprobar q el video no haya sido borrado if filetools.exists(item_json.url): item_local = item_json.clone(action='play') itemlist.append(item_local) else: num_canales -= 1 filtro_canal = '' if num_canales > 1 and config.get_setting("ask_channel", "biblioteca") == True: opciones = ["Mostrar solo los enlaces de %s" % k.capitalize() for k in list_canales.keys()] opciones.insert(0, "Mostrar todos los enlaces") if item_local: opciones.append(item_local.title) from platformcode import platformtools index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index < 0: return [] elif item_local and index == len(opciones) - 1: filtro_canal = 'descargas' platformtools.play_video(item_local) elif index > 0: filtro_canal = opciones[index].replace("Mostrar solo los enlaces de ", "") itemlist = [] for nom_canal, json_path in list_canales.items(): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue # Importamos el canal de la parte seleccionada try: channel = __import__('channels.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) except ImportError: exec "import channels." + nom_canal + " as channel" item_json = Item().fromjson(filetools.read(json_path)) list_servers = [] try: # FILTERTOOLS # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente. if "list_idiomas" in item_json: # si se viene desde la biblioteca de pelisalacarta if "library_filter_show" in item: item_json.show = item.library_filter_show.get(nom_canal, "") # Ejecutamos find_videos, del canal o común if hasattr(channel, 'findvideos'): list_servers = getattr(channel, 'findvideos')(item_json) else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception as ex: logger.error("Ha fallado la funcion findvideos para el canal %s" % nom_canal) template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.error(message) # Cambiarle el titulo a los servers añadiendoles el nombre del canal delante y # las infoLabels y las imagenes del item si el server no tiene for server in list_servers: if not server.action: # Ignorar las etiquetas continue server.contentChannel = server.channel server.channel = "biblioteca" server.nfo = item.nfo server.strm_path = item.strm_path server.title = "%s: %s" % (nom_canal.capitalize(), server.title) server.infoLabels = item_json.infoLabels if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server) # return sorted(itemlist, key=lambda it: it.title.lower()) return itemlist
def set_content(content_type, silent=False): """ Procedimiento para auto-configurar la biblioteca de kodi con los valores por defecto @type content_type: str ('CINE' o 'SERIES') @param content_type: tipo de contenido para configurar, series o peliculas """ if config.is_xbmc(): continuar = True msg_text = "" librarypath = config.get_setting("librarypath") if content_type == 'CINE': if not xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)'): if not silent: # Preguntar si queremos instalar metadata.themoviedb.org install = platformtools.dialog_yesno("The Movie Database", "TheMovieDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.themoviedb.org xbmc.executebuiltin('xbmc.installaddon(metadata.themoviedb.org)', True) logger.info("Instalado el Scraper de películas de TheMovieDB") except: pass continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)')) if not continuar: msg_text = "The Movie Database no instalado." else: # SERIES # Instalar The TVDB if not xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'): if not silent: # Preguntar si queremos instalar metadata.tvdb.com install = platformtools.dialog_yesno("The TVDB", "The TVDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.tvdb.com xbmc.executebuiltin('xbmc.installaddon(metadata.tvdb.com)', True) logger.info("Instalado el Scraper de series de The TVDB") except: pass continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)')) if not continuar: msg_text = "The TVDB no instalado." # Instalar TheMovieDB if continuar and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): continuar = False if not silent: # Preguntar si queremos instalar metadata.tvshows.themoviedb.org install = platformtools.dialog_yesno("The Movie Database", "TheMovieDB non presente.", "Installare ora?") else: install = True if install: try: # Instalar metadata.tvshows.themoviedb.org # 1º Probar desde el repositorio ... xbmc.executebuiltin('xbmc.installaddon(metadata.tvshows.themoviedb.org)', True) if not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): # ...si no funciona descargar e instalar desde la web url = "http://mirrors.kodi.tv/addons/jarvis/metadata.tvshows.themoviedb.org/metadata.tvshows.themoviedb.org-1.3.1.zip" path_down = xbmc.translatePath( "special://home/addons/packages/metadata.tvshows.themoviedb.org-1.3.1.zip") path_unzip = xbmc.translatePath("special://home/addons/") header = ("User-Agent", "Kodi/15.2 (Windows NT 10.0; WOW64) App_Bitness/32 Version/15.2-Git:20151019-02e7013") from core import downloadtools from core import ziptools downloadtools.downloadfile(url, path_down, continuar=True, headers=[header]) unzipper = ziptools.ziptools() unzipper.extract(path_down, path_unzip) xbmc.executebuiltin('UpdateLocalAddons') strSettings = '<settings>\n' \ ' <setting id="fanart" value="true" />\n' \ ' <setting id="keeporiginaltitle" value="false" />\n' \ ' <setting id="language" value="it" />\n' \ '</settings>' path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml") tv_themoviedb_addon_path = filetools.dirname(path_settings) if not filetools.exists(tv_themoviedb_addon_path): filetools.mkdir(tv_themoviedb_addon_path) if filetools.write(path_settings,strSettings): continuar = True except: pass continuar = (install and continuar) if not continuar: msg_text = "The Movie Database non installato." idPath = 0 idParentPath = 0 strPath = "" if continuar: continuar = False # Buscamos el idPath sql = 'SELECT MAX(idPath) FROM path' nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idPath = records[0][0] + 1 sql_librarypath = librarypath if sql_librarypath.startswith("special://"): sql_librarypath = sql_librarypath.replace('/profile/', '/%/').replace('/home/userdata/', '/%/') sep = '/' elif sql_librarypath.startswith("smb://"): sep = '/' else: sep = os.sep if not sql_librarypath.endswith(sep): sql_librarypath += sep # Buscamos el idParentPath sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_librarypath nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idParentPath = records[0][0] librarypath = records[0][1][:-1] continuar = True else: # No existe librarypath en la BD: la insertamos sql_librarypath = librarypath if not sql_librarypath.endswith(sep): sql_librarypath += sep sql = 'INSERT INTO path (idPath, strPath, scanRecursive, useFolderNames, noUpdate, exclude) VALUES ' \ '(%s, "%s", 0, 0, 0, 0)' % (idPath, sql_librarypath) nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True idParentPath = idPath idPath += 1 else: msg_text = "Omesso di impostare LibraryPath in BD" if continuar: continuar = False # Fijamos strContent, strScraper, scanRecursive y strSettings if content_type == 'CINE': strContent = 'movies' strScraper = 'metadata.themoviedb.org' scanRecursive = 2147483647 strSettings = "<settings><setting id='RatingS' value='TMDb' /><setting id='certprefix' value='Rated ' />" \ "<setting id='fanart' value='true' /><setting id='keeporiginaltitle' value='false' />" \ "<setting id='language' value='it' /><setting id='tmdbcertcountry' value='us' />" \ "<setting id='trailer' value='true' /></settings>" strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per i film ?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting("folder_movies") + sep else: strContent = 'tvshows' strScraper = 'metadata.tvdb.com' scanRecursive = 0 strSettings = "<settings><setting id='RatingS' value='TheTVDB' />" \ "<setting id='absolutenumber' value='false' />" \ "<setting id='dvdorder' value='false' />" \ "<setting id='fallback' value='true' />" \ "<setting id='fanart' value='true' />" \ "<setting id='language' value='it' /></settings>" strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per le serie ?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting("folder_tvshows") + sep logger.info("%s: %s" % (content_type, strPath)) # Comprobamos si ya existe strPath en la BD para evitar duplicados sql = 'SELECT idPath FROM path where strPath="%s"' % strPath nun_records, records = execute_sql_kodi(sql) sql = "" if nun_records == 0: # Insertamos el scraper sql = 'INSERT INTO path (idPath, strPath, strContent, strScraper, scanRecursive, useFolderNames, ' \ 'strSettings, noUpdate, exclude, idParentPath) VALUES (%s, "%s", "%s", "%s", %s, 0, ' \ '"%s", 0, 0, %s)' % ( idPath, strPath, strContent, strScraper, scanRecursive, strSettings, idParentPath) else: if not silent: # Preguntar si queremos configurar themoviedb.org como opcion por defecto actualizar = platformtools.dialog_yesno("The TVDB", strActualizar) else: actualizar = True if actualizar: # Actualizamos el scraper idPath = records[0][0] sql = 'UPDATE path SET strContent="%s", strScraper="%s", scanRecursive=%s, strSettings="%s" ' \ 'WHERE idPath=%s' % (strContent, strScraper, scanRecursive, strSettings, idPath) if sql: nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True if not continuar: msg_text = "Omesso impostare LibraryPath in BD" if not continuar: heading = "Biblioteca %s no configurada" % content_type elif content_type == 'SERIES' and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'): heading = "Biblioteca %s configurata" % content_type msg_text = "Riavviare Kodi per attuare le modifiche." else: heading = "Biblioteca %s configurata" % content_type msg_text = "Libreria di Kodi configurata correttamente." platformtools.dialog_notification(heading, msg_text, icon=1, time=10000) logger.info("%s: %s" % (heading,msg_text))
modo_cliente = int(config.get_setting("library_mode")) # Host name where XBMC is running, leave as localhost if on this PC # Make sure "Allow control of XBMC via HTTP" is set to ON in Settings -> # Services -> Webserver xbmc_host = config.get_setting("xbmc_host") # Configured in Settings -> Services -> Webserver -> Port xbmc_port = int(config.get_setting("xbmc_port")) # Base URL of the json RPC calls. For GET calls we append a "request" URI # parameter. For POSTs, we add the payload as JSON the the HTTP request body xbmc_json_rpc_url = "http://" + xbmc_host + ":" + str(xbmc_port) + "/jsonrpc" LIBRARY_PATH = config.get_library_path() if not filetools.exists(LIBRARY_PATH): logger.info("pelisalacarta.platformcode.library Library path doesn't exist:" + LIBRARY_PATH) config.verify_directories_created() # TODO permitir cambiar las rutas y nombres en settings para 'cine' y 'series' FOLDER_MOVIES = "CINE" # config.get_localized_string(30072) MOVIES_PATH = filetools.join(LIBRARY_PATH, FOLDER_MOVIES) FOLDER_TVSHOWS = "SERIES" # config.get_localized_string(30073) TVSHOWS_PATH = filetools.join(LIBRARY_PATH, FOLDER_TVSHOWS) def save_library_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item
def execute_sql_kodi(sql): """ Ejecuta la consulta sql contra la base de datos de kodi @param sql: Consulta sql valida @type sql: str @return: Numero de registros modificados o devueltos por la consulta @rtype nun_records: int @return: lista con el resultado de la consulta @rtype records: list of tuples """ logger.info() file_db = "" nun_records = 0 records = None # Buscamos el archivo de la BBDD de videos segun la version de kodi video_db = config.get_platform(True)['video_db'] if video_db: file_db = filetools.join(xbmc.translatePath("special://userdata/Database"), video_db) # metodo alternativo para localizar la BBDD if not file_db or not filetools.exists(file_db): file_db = "" for f in filetools.listdir(xbmc.translatePath("special://userdata/Database")): path_f = filetools.join(xbmc.translatePath("special://userdata/Database"), f) if filetools.isfile(path_f) and f.lower().startswith('myvideos') and f.lower().endswith('.db'): file_db = path_f break if file_db: logger.info("Archivo de BD: %s" % file_db) conn = None try: import sqlite3 conn = sqlite3.connect(file_db) cursor = conn.cursor() logger.info("Ejecutando sql: %s" % sql) cursor.execute(sql) conn.commit() records = cursor.fetchall() if sql.lower().startswith("select"): nun_records = len(records) if nun_records == 1 and records[0][0] is None: nun_records = 0 records = [] else: nun_records = conn.total_changes conn.close() logger.info("Consulta ejecutada. Registros: %s" % nun_records) except: logger.error("Error al ejecutar la consulta sql") if conn: conn.close() else: logger.debug("Base de datos no encontrada") return nun_records, records
def set_infolabels_from_library(itemlist, tipo): """ guarda los datos (thumbnail, fanart, plot, actores, etc) a mostrar de la library de Kodi. @type itemlist: list @param itemlist: item @type tipo: str @param tipo: @rtype: infoLabels @return: result of saving. """ logger.info("streamondemand.platformcode.library set_infoLabels_from_library") # Metodo 1: De la bilioteca de pelisalacarta if tipo == 'Movies': for item in itemlist: if item.path.endswith(".strm"): data_file = item.path if filetools.exists(data_file): infolabels = Item().fromurl(filetools.read(data_file)).infoLabels item.infoLabels = infolabels else: data_file = os.path.splitext(item.path)[0] + ".json" if filetools.exists(data_file): infolabels = Item().fromjson(filetools.read(data_file)).infoLabels item.infoLabels = infolabels item.title = item.contentTitle item.plot = item.contentPlot item.thumbnail = item.contentThumbnail elif tipo == 'TVShows': for item in itemlist: data_file = filetools.join(item.path, "tvshow.json") if filetools.exists(data_file): infolabels = Item().fromjson(filetools.read(data_file)).infoLabels item.infoLabels = infolabels item.title = item.contentSerieName item.thumbnail = item.contentThumbnail item.plot = item.contentPlot elif tipo == 'Episodes': for item in itemlist: if item.path.endswith(".strm"): data_file = item.path if filetools.exists(data_file): infolabels = Item().fromurl(filetools.read(data_file)).infoLabels item.infoLabels = infolabels # TODO debería existir el else? else: data_file = os.path.splitext(item.path)[0] + ".json" if filetools.exists(data_file): infolabels = Item().fromjson(filetools.read(data_file)).infoLabels item.infoLabels = infolabels item.plot = item.contentPlot item.thumbnail = item.contentThumbnail if item.contentTitle: if len(str(item.contentEpisodeNumber)) == 1: item.title = "{0}x0{1}".format(item.contentSeason, item.contentEpisodeNumber) else: item.title = "{0}x{1}".format(item.contentSeason, item.contentEpisodeNumber) item.title = "{0} - {1}".format(item.title, item.contentTitle.strip()) else: if "fulltitle" in item: item.title = item.fulltitle else: if len(str(item.contentEpisodeNumber)) == 1: item.title = "{0}x0{1}".format(item.contentSeason, item.contentEpisodeNumber) else: item.title = "{0}x{1}".format(item.contentSeason, item.contentEpisodeNumber) item.title = "{0} - {1}".format(item.title, "Episodio {0}".format(item.contentEpisodeNumber)) if config.get_setting("get_metadata_from_kodi") == "true": # Metodo2: De la bilioteca de kodi payload = dict() result = list() if tipo == 'Movies': payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "year", "rating", "trailer", "tagline", "plot", "plotoutline", "originaltitle", "lastplayed", "playcount", "writer", "mpaa", "cast", "imdbnumber", "runtime", "set", "top250", "votes", "fanart", "tag", "thumbnail", "file", "director", "country", "studio", "genre", "sorttitle", "setid", "dateadded" ]}, "id": "libMovies"} elif tipo == 'TVShows': payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "genre", "year", "rating", "plot", "studio", "mpaa", "cast", "playcount", "episode", "imdbnumber", "premiered", "votes", "lastplayed", "fanart", "thumbnail", "file", "originaltitle", "sorttitle", "episodeguide", "season", "watchedepisodes", "dateadded", "tag"]}, "id": "libTvShows"} elif tipo == 'Episodes' and 'tvshowid' in itemlist[0].infoLabels and itemlist[0].infoLabels['tvshowid']: tvshowid = itemlist[0].infoLabels['tvshowid'] payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": tvshowid, "properties": ["title", "plot", "votes", "rating", "writer", "firstaired", "playcount", "runtime", "director", "productioncode", "season", "episode", "originaltitle", "showtitle", "cast", "lastplayed", "fanart", "thumbnail", "file", "dateadded", "tvshowid"]}, "id": 1} data = get_data(payload) logger.debug("JSON-RPC: {0}".format(data)) if 'error' in data: logger.error("JSON-RPC: {0}".format(data)) elif 'movies' in data['result']: result = data['result']['movies'] elif 'tvshows' in data['result']: result = data['result']['tvshows'] elif 'episodes' in data['result']: result = data['result']['episodes'] if result: for i in itemlist: for r in result: if r['file'].endswith(os.sep) or r['file'].endswith('/'): r_filename_aux = r['file'][:-1] else: r_filename_aux = r['file'] # r_filename_aux = r['file'][:-1] if r['file'].endswith(os.sep) or r['file'].endswith('/') else r['file'] r_filename = os.path.basename(r_filename_aux) # logger.debug(os.path.basename(i.path) + '\n' + r_filename) i_filename = os.path.basename(i.path) if i_filename == r_filename: infolabels = r # Obtener imagenes y asignarlas al item if 'thumbnail' in infolabels: infolabels['thumbnail'] = urllib.unquote_plus(infolabels['thumbnail']).replace('image://', '') if infolabels['thumbnail'].endswith('/'): i.thumbnail = infolabels['thumbnail'][:-1] else: i.thumbnail = infolabels['thumbnail'] # i.thumbnail = infolabels['thumbnail'][:-1] if infolabels['thumbnail'].endswith('/') else infolabels['thumbnail'] if 'fanart' in infolabels: infolabels['fanart'] = urllib.unquote_plus(infolabels['fanart']).replace('image://', '') if infolabels['fanart'].endswith('/'): i.fanart = infolabels['fanart'][:-1] else: i.fanart = infolabels['fanart'] # i.fanart = infolabels['fanart'][:-1] if infolabels['fanart'].endswith('/') else infolabels['fanart'] # Adaptar algunos campos al formato infoLables if 'cast' in infolabels: l_castandrole = list() for c in sorted(infolabels['cast'], key=lambda _c: _c["order"]): l_castandrole.append((c['name'], c['role'])) infolabels.pop('cast') infolabels['castandrole'] = l_castandrole if 'genre' in infolabels: infolabels['genre'] = ', '.join(infolabels['genre']) if 'writer' in infolabels: infolabels['writer'] = ', '.join(infolabels['writer']) if 'director' in infolabels: infolabels['director'] = ', '.join(infolabels['director']) if 'country' in infolabels: infolabels['country'] = ', '.join(infolabels['country']) if 'studio' in infolabels: infolabels['studio'] = ', '.join(infolabels['studio']) if 'runtime' in infolabels: infolabels['duration'] = infolabels.pop('runtime') # Fijar el titulo si existe y añadir infoLabels al item if 'label' in infolabels: i.title = infolabels['label'] i.infoLabels = infolabels result.remove(r) break
def addchannel(item): from platformcode import platformtools import time, os logger.info("pelisalacarta.channels.configuracion addchannel") tecleado = platformtools.dialog_input("", "Introduzca la URL") if not tecleado: return logger.info("pelisalacarta.channels.configuracion url=%s" % tecleado) local_folder = config.get_runtime_path() if "canal" in item.title: local_folder = filetools.join(local_folder, "channels") folder_to_extract = "channels" info_accion = "canal" else: local_folder = filetools.join(local_folder, "servers") folder_to_extract = "servers" info_accion = "conector" # Detecta si es un enlace a un .py o .xml (pensado sobre todo para enlaces de github) try: extension = tecleado.rsplit(".", 1)[1] except: extension = "" files = [] zip = False if extension == "py" or extension == "xml": filename = tecleado.rsplit("/", 1)[1] localfilename = filetools.join(local_folder, filename) files.append([tecleado, localfilename, filename]) else: import re from core import scrapertools # Comprueba si la url apunta a una carpeta completa (channels o servers) de github if re.search(r"https://github.com/[^\s]+/" + folder_to_extract, tecleado): try: data = scrapertools.downloadpage(tecleado) matches = scrapertools.find_multiple_matches( data, '<td class="content">.*?href="([^"]+)".*?title="([^"]+)"' ) for url, filename in matches: url = "https://raw.githubusercontent.com" + url.replace("/blob/", "/") localfilename = filetools.join(local_folder, filename) files.append([url, localfilename, filename]) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) platformtools.dialog_ok("Error", "La url no es correcta o no está disponible") return else: filename = "new%s.zip" % info_accion localfilename = filetools.join(config.get_data_path(), filename) files.append([tecleado, localfilename, filename]) zip = True logger.info("pelisalacarta.channels.configuracion localfilename=%s" % localfilename) logger.info("pelisalacarta.channels.configuracion descarga fichero...") try: if len(files) > 1: lista_opciones = ["No", "Sí", "Sí (Sobrescribir todos)"] overwrite_all = False from core import downloadtools for url, localfilename, filename in files: result = downloadtools.downloadfile(url, localfilename, continuar=False) if result == -3: if len(files) == 1: dyesno = platformtools.dialog_yesno( "El archivo ya existe", "Ya existe el %s %s." " ¿Desea sobrescribirlo?" % (info_accion, filename), ) else: if not overwrite_all: dyesno = platformtools.dialog_select( "El archivo %s ya existe, ¿desea sobrescribirlo?" % filename, lista_opciones ) else: dyesno = 1 # Diálogo cancelado if dyesno == -1: return # Caso de carpeta github, opción sobrescribir todos elif dyesno == 2: overwrite_all = True elif dyesno: hora_folder = "Copia seguridad [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), "backups", hora_folder, folder_to_extract) if not filetools.exists(backup): os.makedirs(backup) import shutil shutil.copy2(localfilename, filetools.join(backup, filename)) result = downloadtools.downloadfile(url, localfilename, continuar=True) else: if len(files) == 1: return else: continue except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) return if zip: try: # Lo descomprime logger.info("pelisalacarta.channels.configuracion descomprime fichero...") from core import ziptools unzipper = ziptools.ziptools() logger.info("pelisalacarta.channels.configuracion destpathname=%s" % local_folder) unzipper.extract(localfilename, local_folder, folder_to_extract, True, True) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) # Borra el zip descargado filetools.remove(localfilename) platformtools.dialog_ok("Error", "Se ha producido un error extrayendo el archivo") return # Borra el zip descargado logger.info("pelisalacarta.channels.configuracion borra fichero...") filetools.remove(localfilename) logger.info("pelisalacarta.channels.configuracion ...fichero borrado") platformtools.dialog_ok("Éxito", "Actualización/Instalación realizada correctamente")
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 addchannel(item): from platformcode import platformtools import os import time logger.info() tecleado = platformtools.dialog_input("", "Inserire l'URL") if not tecleado: return logger.info("url=%s" % tecleado) local_folder = config.get_runtime_path() if "canal" in item.title: local_folder = filetools.join(local_folder, 'channels') folder_to_extract = "channels" info_accion = "canal" else: local_folder = filetools.join(local_folder, 'servers') folder_to_extract = "servers" info_accion = "conector" # Detecta si es un enlace a un .py o .xml (pensado sobre todo para enlaces de github) try: extension = tecleado.rsplit(".", 1)[1] except: extension = "" files = [] zip = False if extension == "py" or extension == "xml": filename = tecleado.rsplit("/", 1)[1] localfilename = filetools.join(local_folder, filename) files.append([tecleado, localfilename, filename]) else: import re from core import scrapertools # Comprueba si la url apunta a una carpeta completa (channels o servers) de github if re.search(r'https://github.com/[^\s]+/'+folder_to_extract, tecleado): try: data = scrapertools.downloadpage(tecleado) matches = scrapertools.find_multiple_matches(data, '<td class="content">.*?href="([^"]+)".*?title="([^"]+)"') for url, filename in matches: url = "https://raw.githubusercontent.com" + url.replace("/blob/", "/") localfilename = filetools.join(local_folder, filename) files.append([url, localfilename, filename]) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) platformtools.dialog_ok("Errore", "L'URL non è corretto o non disponibile") return else: filename = 'new%s.zip' % info_accion localfilename = filetools.join(config.get_data_path(), filename) files.append([tecleado, localfilename, filename]) zip = True logger.info("localfilename=%s" % localfilename) logger.info("descarga fichero...") try: if len(files) > 1: lista_opciones = ["No", "Si", "Si (Sovrascrivere tutto)"] overwrite_all = False from core import downloadtools for url, localfilename, filename in files: result = downloadtools.downloadfile(url, localfilename, continuar=False) if result == -3: if len(files) == 1: dyesno = platformtools.dialog_yesno("Il file esiste già", "%s %s esiste già. " "Vuoi sovrascrivere?" % (info_accion, filename)) else: if not overwrite_all: dyesno = platformtools.dialog_select("Il file %s esiste già, vuoi sovrascrivere?" % filename, lista_opciones) else: dyesno = 1 # Diálogo cancelado if dyesno == -1: return # Caso de carpeta github, opción sobrescribir todos elif dyesno == 2: overwrite_all = True elif dyesno: hora_folder = "Backup [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), 'backups', hora_folder, folder_to_extract) if not filetools.exists(backup): os.makedirs(backup) import shutil shutil.copy2(localfilename, filetools.join(backup, filename)) downloadtools.downloadfile(url, localfilename, continuar=True) else: if len(files) == 1: return else: continue except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) return if zip: try: # Lo descomprime logger.info("descomprime fichero...") from core import ziptools unzipper = ziptools.ziptools() logger.info("destpathname=%s" % local_folder) unzipper.extract(localfilename, local_folder, folder_to_extract, True, True) except: import traceback logger.error("Detalle del error: %s" % traceback.format_exc()) # Borra el zip descargado filetools.remove(localfilename) platformtools.dialog_ok("Errore", "C'è stato un errore nell'estrazione del file") return # Borra el zip descargado logger.info("borra fichero...") filetools.remove(localfilename) logger.info("...fichero borrado") platformtools.dialog_ok("Successo", "Aggiornamento/installazione eseguita correttamente")