def get_temporadas(item): logger.info("streamondemand.channels.biblioteca get_temporadas") itemlist = [] dict_temp = {} raiz, carpetas_series, ficheros = filetools.walk(item.path).next() if config.get_setting("no_pile_on_seasons") == "Siempre": return get_episodios(item) for i in ficheros: if "tvshow" not in i: season = i.split('x')[0] dict_temp[season] = "Stagione " + str(season) if config.get_setting("no_pile_on_seasons") == "Solo se presente una stagione" and len(dict_temp) == 1: return get_episodios(item) else: # Creamos un item por cada temporada for season, title in dict_temp.items(): # fix para que se filtren bien los contenido, ya que sino se hereda el campo item.infoLabels['season'] = "" new_item = item.clone(action="get_episodios", title=title, contentTitle=title, contentSeason=season, contentEpisodeNumber="", filtrar_season=True, text_color="") itemlist.append(new_item) # logger.debug(new_item.tostring()) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: int(it.contentSeason)) if config.get_setting("show_all_seasons") == "true": new_item = item.clone(action="get_episodios", title="*Tutte le stagioni", text_color="") itemlist.insert(0, new_item) return itemlist
def update_biblio(item): logger.info() # Actualizar las series activas sobreescribiendo import library_service if item.extra == "overwrite_everything": if config.is_xbmc(): seleccion = platformtools.dialog_yesno(config.PLUGIN_NAME, "Avviso: devi attendere.", "Vuoi continuare ?") if seleccion == 1: library_service.check_for_update(overwrite="everything") else: library_service.check_for_update(overwrite="everything") else: library_service.check_for_update(overwrite=True) # Eliminar las carpetas de peliculas que no contengan archivo strm for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): strm = False for f in ficheros: if f.endswith(".strm"): strm = True break if ficheros and not strm: logger.debug("Borrando carpeta de pelicula eliminada: %s" % raiz) filetools.rmdirtree(raiz)
def get_episodios(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Menu contextual: Releer tvshow.nfo head_nfo, item_nfo = library.read_nfo(item.nfo) # Crear un item en la lista para cada strm encontrado for i in ficheros: if i.endswith('.strm'): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") # Si hay q filtrar por temporada, ignoramos los capitulos de otras temporadas if item.filtrar_season and int(season) != int(item.contentSeason): continue # Obtener los datos del season_episode.nfo nfo_path = filetools.join(raiz, i).replace('.strm', '.nfo') head_nfo, epi = library.read_nfo(nfo_path) # Fijar el titulo del capitulo si es posible if epi.contentTitle: title_episodie = epi.contentTitle.strip() else: title_episodie = "Stagione %s Episodio %s" % \ (epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2)) epi.contentTitle = "%sx%s" % (epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2)) epi.title = "%sx%s - %s" % (epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2), title_episodie) if item_nfo.library_filter_show: epi.library_filter_show = item_nfo.library_filter_show # Menu contextual: Marcar episodio como visto o no visto = item_nfo.library_playcounts.get(season_episode, 0) epi.infoLabels["playcount"] = visto if visto > 0: texto = "Segna episodio come non visto" value = 0 else: texto = "Segna episodio come visto" value = 1 epi.context = [{"title": texto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": value, "nfo": item.nfo}] # logger.debug("epi:\n" + epi.tostring('\n')) itemlist.append(epi) return sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
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() # logger.debug(item.tostring('\n')) path = "" # Si llegados a este punto no tenemos titulo o tmdb_id, salimos if not (item.contentSerieName or item.infoLabels['tmdb_id']) or not item.channel: logger.debug("NO ENCONTRADO contentSerieName NI tmdb_id") return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llame a uno u otro scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la serie # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE IMDB_ID") return 0, 0, -1 _id = item.infoLabels['code'] if config.get_setting("original_title_folder", "biblioteca") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] elif item.infoLabels['title']: base_name = item.infoLabels['title'] else: base_name = item.contentSerieName base_name = filetools.validate_path(base_name.replace('/', '-')).lower() for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH): for c in subcarpetas: if c.endswith("[%s]" % _id): path = filetools.join(raiz, c) break if not path: path = filetools.join(TVSHOWS_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio serie: " + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
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 get_temporadas(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] dict_temp = {} raiz, carpetas_series, ficheros = filetools.walk(item.path).next() if config.get_setting("no_pile_on_seasons", "biblioteca") == 2: # Siempre return get_episodios(item) for f in ficheros: if f.endswith('.json'): season = f.split('x')[0] dict_temp[season] = "Temporada %s" % season if config.get_setting("no_pile_on_seasons", "biblioteca") == 1 and len(dict_temp) == 1: # Sólo si hay una temporada return get_episodios(item) else: # Creamos un item por cada temporada for season, title in dict_temp.items(): new_item = item.clone(action="get_episodios", title=title, contentSeason=season, filtrar_season=True) # Menu contextual: Releer tvshow.nfo head_nfo, item_nfo = library.read_nfo(item.nfo) # Menu contextual: Marcar la temporada como vista o no visto = item_nfo.library_playcounts.get("season %s" % season, 0) new_item.infoLabels["playcount"] = visto if visto > 0: texto = "Marcar temporada como no vista" value = 0 else: texto = "Marcar temporada como vista" value = 1 new_item.context = [{"title": texto, "action": "mark_season_as_watched", "channel": "biblioteca", "playcount": value}] # logger.debug("new_item:\n" + new_item.tostring('\n')) itemlist.append(new_item) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: int(it.contentSeason)) if config.get_setting("show_all_seasons", "biblioteca") == True: new_item = item.clone(action="get_episodios", title="*Todas las temporadas") new_item.infoLabels["playcount"] = 0 itemlist.insert(0, new_item) return itemlist
def get_episodios(item): logger.info("pelisalacarta.channels.biblioteca get_episodios") itemlist = [] # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Crear un item en la lista para cada strm encontrado for i in ficheros: # strm if i.endswith(".strm"): season, episode = scrapertools.get_season_and_episode(i).split("x") # Si hay q filtrar por temporada, ignoramos los capitulos de otras temporadas if item.filtrar_season and int(season) != int(item.contentSeason): continue epi = Item().fromurl(filetools.read(filetools.join(raiz, i))) epi.contentChannel = item.contentChannel epi.path = filetools.join(raiz, i) epi.title = i epi.channel = "biblioteca" epi.action = "findvideos" epi.contentEpisodeNumber = episode epi.contentSeason = season # fix sobreescribe el color del texto si viene pasado en el strm epi.text_color = "" # fix para que no se ejecute el método de play para la biblioteca de Kodi epi.strm = False itemlist.append(epi) # videos elif not i.endswith(".nfo") and not i.endswith(".json") and not i.endswith(".srt"): season, episode = scrapertools.get_season_and_episode(i).split("x") # Si hay q filtrar por temporada, ignoramos los capitulos de otras temporadas if item.filtrar_season and int(season) != int(item.contentSeason): continue epi = Item() epi.contentChannel = "local" epi.path = filetools.join(raiz, i) epi.title = i epi.channel = "biblioteca" epi.action = "play" epi.contentEpisodeNumber = episode epi.contentSeason = season itemlist.append(epi) library.set_infolabels_from_library(itemlist, tipo="Episodes") return sorted(itemlist, key=get_sort_temp_epi)
def mark_season_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_season_as_watched") # logger.debug("item:\n" + item.tostring('\n')) # Obtener el diccionario de episodios marcados f = filetools.join(item.path, "tvshow.nfo") url_scraper = filetools.read(f, 0, 1) it = Item().fromjson(filetools.read(f, 1)) if not hasattr(it, "library_playcounts"): it.library_playcounts = {} # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Marcamos cada uno de los episodios encontrados de esta temporada episodios_marcados = 0 for i in ficheros: if i.endswith(".strm"): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason): name_file = os.path.splitext(os.path.basename(i))[0] it.library_playcounts[name_file] = item.playcount episodios_marcados += 1 if episodios_marcados: if int(item.contentSeason) == -1: # Añadimos todas las temporadas al diccionario item.library_playcounts for k in it.library_playcounts.keys(): if k.startswith("season"): it.library_playcounts[k] = item.playcount else: # Añadimos la temporada al diccionario item.library_playcounts it.library_playcounts["season %s" % item.contentSeason] = item.playcount # se comprueba que si todas las temporadas están vistas, se marque la serie como vista it = check_tvshow_playcount(it, item.contentSeason) # Guardamos los cambios en tvshow.nfo filetools.write(f, url_scraper + it.tojson()) item.infoLabels["playcount"] = item.playcount if config.is_xbmc(): # Actualizamos la BBDD de Kodi library.mark_season_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def update_biblio(item): logger.info() # Actualizar las series activas sobreescribiendo import library_service library_service.check_for_update(overwrite=True) # Eliminar las carpetas de peliculas que no contengan archivo strm for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): strm = False for f in ficheros: if f.endswith(".strm"): strm = True break if ficheros and not strm: logger.debug("Borrando carpeta de pelicula eliminada: %s" % raiz) filetools.rmdirtree(raiz)
def updatebiblio(item): logger.info("pelisalacarta.channels.ayuda updatebiblio") # Actualizar las series activas sobreescribiendo import library_service library_service.main() # Eliminar las carpetas de peliculas que no contengan archivo strm from platformcode import library for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): strm = False for f in ficheros: if f.endswith(".strm"): strm = True break if ficheros and not strm: logger.debug("Borrando carpeta de pelicula eliminada: %s" % raiz) filetools.rmdirtree(raiz)
def findvideos(item): from core import servertools if item.infoLabels["tmdb_id"]: tmdb.set_infoLabels_item(item, __modo_grafico__) itemlist = servertools.find_video_items(item) library_path = config.get_library_path() if config.get_library_support(): title = "Añadir película a la biblioteca" if item.infoLabels["imdb_id"] and not library_path.lower().startswith("smb://"): try: from core import filetools movie_path = filetools.join(config.get_library_path(), 'CINE') files = filetools.walk(movie_path) for dirpath, dirname, filename in files: for f in filename: if item.infoLabels["imdb_id"] in f and f.endswith(".nfo"): from core import library head_nfo, it = library.read_nfo(filetools.join(dirpath, dirname, f)) canales = it.library_urls.keys() canales.sort() if "clasicofilm" in canales: canales.pop(canales.index("clasicofilm")) canales.insert(0, "[COLOR red]clasicofilm[/COLOR]") title = "Película ya en tu biblioteca. [%s] ¿Añadir?" % ",".join(canales) break except: import traceback logger.info(traceback.format_exc()) pass itemlist.append(item.clone(action="add_pelicula_to_library", title=title)) token_auth = config.get_setting("token_trakt", "tvmoviedb") if token_auth and item.infoLabels["tmdb_id"]: itemlist.append(item.clone(channel="tvmoviedb", title="[Trakt] Gestionar con tu cuenta", action="menu_trakt", extra="movie")) return itemlist
def overwrite_tools(item): import library_service from core import library seleccion = platformtools.dialog_yesno("Sobrescribir toda la biblioteca", "Esto puede llevar algun tiempo.", "¿Desea continuar?") if seleccion == 1: heading = 'Sobrescribiendo biblioteca....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) if not serie.active: # si la serie no esta activa descartar continue # Eliminamos la carpeta con la serie ... filetools.rmdirtree(path) # ... y la volvemos a añadir library_service.update(path, p_dialog, i, t, serie, 3) p_dialog.close()
def update_external_addon(addon_name): logger.info(addon_name) try: #Verificamos que el addon está instalado if xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % addon_name): #Path de actualizaciones de Alfa alfa_addon_updates_mig = filetools.join(config.get_runtime_path(), "lib") alfa_addon_updates = filetools.join(alfa_addon_updates_mig, addon_name) #Está el addon activo? try: __settings__ = xbmcaddon.Addon(id="plugin.video." + addon_name) except: logger.error('Addon %s desactivado' % (addon_name.upper())) return True #Path de destino en addon externo if addon_name.lower() in ['quasar', 'elementum']: addon_path_root = filetools.translatePath( __settings__.getAddonInfo('Path')) addon_path_mig = filetools.join( addon_path_root, filetools.join("resources", "site-packages")) addon_path = filetools.join(addon_path_mig, addon_name) else: addon_path_root = '' addon_path_mig = '' addon_path = '' #Hay modificaciones en Alfa? Las copiamos al addon, incuidas las carpetas de migración a PY3 if filetools.exists(alfa_addon_updates) and filetools.exists( addon_path): for root, folders, files in filetools.walk( alfa_addon_updates_mig): if ('future' in root or 'past' in root) and not 'concurrent' in root: for file in files: alfa_addon_updates_mig_folder = root.replace( alfa_addon_updates_mig, addon_path_mig) if not filetools.exists( alfa_addon_updates_mig_folder): filetools.mkdir(alfa_addon_updates_mig_folder) if file.endswith('.pyo') or file.endswith('.pyd'): continue input_file = filetools.join(root, file) output_file = input_file.replace( alfa_addon_updates_mig, addon_path_mig) if not filetools.copy( input_file, output_file, silent=True): logger.error( 'Error en la copia de MIGRACIÓN: Input: %s o Output: %s' % (input_file, output_file)) return False 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_mig) if file in ['addon.xml']: filetools.copy(input_file, filetools.join( addon_path_root, file), silent=True) continue 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_mig)) # 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 except: logger.error(traceback.format_exc()) return False
def get_seasons(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] dict_temp = {} raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Menu contextual: Releer tvshow.nfo head_nfo, item_nfo = videolibrarytools.read_nfo(item.nfo) if config.get_setting("no_pile_on_seasons", "videolibrary") == 2: # Siempre return get_episodes(item) for f in ficheros: if f.endswith('.json'): season = f.split('x')[0] dict_temp[season] = config.get_localized_string(60027) % season if config.get_setting("no_pile_on_seasons", "videolibrary") == 1 and len( dict_temp) == 1: # Sólo si hay una temporada return get_episodes(item) else: # TODO mostrar los episodios de la unica temporada "no vista", en vez de mostrar el Item "temporada X" previo # si está marcado "ocultar los vistos" en el skin, se ejecutaria esto # se comprueba cada temporada en dict_temp si está visto. # si hay una sola temporada y no_pile_on_seasons == 1, se devuelve get(episodios) # si está todo visto, hacemos como actualmente <-- el else no se hace nada.. CREO # if config.get_setting("no_pile_on_seasons", "videolibrary") == 1 and len(dict_temp_Visible) == 1: # Sólo si hay una temporada # Creamos un item por cada temporada for season, title in dict_temp.items(): new_item = item.clone(action="get_episodes", title=title, contentSeason=season, filtrar_season=True) # Menu contextual: Marcar la temporada como vista o no visto = item_nfo.library_playcounts.get("season %s" % season, 0) new_item.infoLabels["playcount"] = visto if visto > 0: texto = config.get_localized_string(60028) value = 0 else: texto = config.get_localized_string(60029) value = 1 new_item.context = [{ "title": texto, "action": "mark_season_as_watched", "channel": "videolibrary", "playcount": value }] # logger.debug("new_item:\n" + new_item.tostring('\n')) itemlist.append(new_item) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: int(it.contentSeason)) if config.get_setting("show_all_seasons", "videolibrary"): new_item = item.clone(action="get_episodes", title=config.get_localized_string(60030)) new_item.infoLabels["playcount"] = 0 itemlist.insert(0, new_item) return itemlist
def episodios(item): logger.info() itemlist = [] # Descarga la página data = httptools.downloadpage(item.url).data data = re.sub(r"\n|\r|\t|\s{2}| |<br>", "", data) if not item.infoLabels["tmdb_id"]: item.infoLabels["tmdb_id"] = scrapertools.find_single_match(data, '<a href="https://www.themoviedb.org/[^/]+/(\d+)') item.infoLabels["year"] = scrapertools.find_single_match(data, 'class="e_new">(\d{4})') if not item.infoLabels["genre"]: item.infoLabels["genre"] = ", ".join(scrapertools.find_multiple_matches(data, '<a itemprop="genre"[^>]+>([^<]+)</a>')) if not item.infoLabels["plot"]: item.infoLabels["plot"] = scrapertools.find_single_match(data, 'itemprop="description">([^<]+)</div>') dc = scrapertools.find_single_match(data, "var dc_ic = '\?dc=([^']+)'") patron = '<div class="f_cl_l_c f_cl_l_c_id[^"]+" c_id="([^"]+)" .*?c_num="([^"]+)" c_name="([^"]+)"' \ '.*?load_f_links\(\d+\s*,\s*(\d+).*?<div class="([^"]+)" onclick="marcar_capitulo' matches = scrapertools.find_multiple_matches(data, patron) lista_epis = [] for c_id, episodio, title, ficha, status in matches: episodio = episodio.replace("X", "x") if episodio in lista_epis: continue lista_epis.append(episodio) url = "https://playmax.mx/c_enlaces_n.php?ficha=%s&c_id=%s&dc=%s" % (ficha, c_id, dc) title = "%s - %s" % (episodio, title) if "_mc a" in status: title = "[COLOR %s]%s[/COLOR] %s" % (color5, u"\u0474".encode('utf-8'), title) new_item = Item(channel=item.channel, action="findvideos", title=title, url=url, thumbnail=item.thumbnail, fanart=item.fanart, show=item.show, infoLabels=item.infoLabels, text_color=color2, referer=item.url, contentType="episode") try: new_item.infoLabels["season"], new_item.infoLabels["episode"] = episodio.split('x', 1) except: pass itemlist.append(new_item) itemlist.sort(key=lambda it: (it.infoLabels["season"], it.infoLabels["episode"]), reverse=True) if __modo_grafico__: tmdb.set_infoLabels_itemlist(itemlist, __modo_grafico__) library_path = config.get_videolibrary_path() if config.get_videolibrary_support() and not item.extra: title = "Añadir serie a la videoteca" if item.infoLabels["imdb_id"] and not library_path.lower().startswith("smb://"): try: from core import filetools path = filetools.join(library_path, "SERIES") files = filetools.walk(path) for dirpath, dirname, filename in files: if item.infoLabels["imdb_id"] in dirpath: for f in filename: if f != "tvshow.nfo": continue from core import videolibrarytools head_nfo, it = videolibrarytools.read_nfo(filetools.join(dirpath, dirname, f)) canales = it.library_urls.keys() canales.sort() if "playmax" in canales: canales.pop(canales.index("playmax")) canales.insert(0, "[COLOR red]playmax[/COLOR]") title = "Serie ya en tu videoteca. [%s] ¿Añadir?" % ",".join(canales) break except: import traceback logger.error(traceback.format_exc()) pass itemlist.append(item.clone(action="add_serie_to_library", title=title, text_color=color5, extra="episodios###library")) if itemlist and not __menu_info__: ficha = scrapertools.find_single_match(item.url, '-f(\d+)-') itemlist.extend(acciones_fichas(item, sid, ficha)) return itemlist
def get_environment(): """ Devuelve las variables de entorno del OS, de Kodi y de Alfa más habituales, necesarias para el diagnóstico de fallos """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = str(platform.python_version()) environment['os_release'] = str(platform.release()) if xbmc.getCondVisibility("system.platform.Windows"): try: if platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) except: pass environment['prod_model'] = '' if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split('\n'): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( int(memoryStatus.dwTotalPhys) / (1024**2)) environment['mem_free'] = str( int(memoryStatus.dwAvailPhys) / (1024**2)) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]) / 1024) environment['mem_free'] = str( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]) / 1024) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( int( scrapertools.find_single_match( label_a, '>(\d+)<\/')) / 1024**2) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, '>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, '>(.*?)<\/')) except: pass environment['userdata_path'] = str( xbmc.translatePath(config.get_data_path())) try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str( xbmc.translatePath(config.get_videolibrary_path())) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): environment['videolab_series'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))): environment['videolab_pelis'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))))) except: pass try: video_updates = ['No', 'Inicio', 'Una vez', 'Inicio+Una vez'] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' environment['torrentcli_option'] = '' environment['torrentcli_name'] = '' environment['torrentcli_dload_path'] = '' environment['torrentcli_buffer'] = '' environment['torrentcli_dload_estrgy'] = '' environment['torrentcli_mem_size'] = '' environment['torrentcli_free'] = '' torrent_id = config.get_setting("torrent_client", server="torrent", default=0) environment['torrentcli_option'] = str(torrent_id) if torrent_id > 0: torrent_id = torrent_id - 3 if torrent_id < 0: logger.error('torrent_id: ' + str(torrent_id) + ' / torrent_options: ' + str(platformtools.torrent_client_installed())) torrent_options = platformtools.torrent_client_installed() if torrent_options and torrent_id >= 0: environment['torrentcli_name'] = torrent_options[ torrent_id].replace('Plugin externo: ', '') if xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % environment['torrentcli_name']): __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % environment['torrentcli_name']) environment['torrentcli_name'] = environment[ 'torrentcli_name'].capitalize() if environment['torrentcli_name'] == 'Torrenter': environment['torrentcli_dload_path'] = str( xbmc.translatePath(__settings__.getSetting('storage'))) if not environment['torrentcli_dload_path']: environment['torrentcli_dload_path'] = str( filetools.join( xbmc.translatePath("special://home/"), "cache", "xbmcup", "plugin.video.torrenter", "Torrenter")) environment['torrentcli_buffer'] = str( __settings__.getSetting('pre_buffer_bytes')) else: environment['torrentcli_dload_path'] = str( xbmc.translatePath( __settings__.getSetting('download_path'))) environment['torrentcli_buffer'] = str( __settings__.getSetting('buffer_size')) environment['torrentcli_dload_estrgy'] = str( __settings__.getSetting('download_storage')) environment['torrentcli_mem_size'] = str( __settings__.getSetting('memory_size')) if environment['torrentcli_dload_path']: try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['torrentcli_dload_path']), None, None, ctypes.pointer(free_bytes)) environment['torrentcli_free'] = str(round(float(free_bytes.value) / \ (1024**3), 3)) else: disk_space = os.statvfs( environment['torrentcli_dload_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['torrentcli_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['torrentcli_free'] = '?' environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in proxy_channel_bloqued.items(): if proxy_active == 'ON': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk( xbmc.translatePath("special://logpath/")): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment['log_path']: environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024*1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = str(config.get_addon_version()) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['torrentcli_mem_size'] = '' environment['torrentcli_dload_path'] = '' environment['torrentcli_dload_estrgy'] = '' environment['machine'] = '' environment['platform'] = '' environment['torrentcli_buffer'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['torrentcli_free'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['torrentcli_name'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrentcli_option'] = '' return environment
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False hoy = datetime.date.today() try: if config.get_setting("updatelibrary", "biblioteca") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "biblioteca") if config.get_setting("updatelibrary", "biblioteca") == 1 and not overwrite: # "Actualizar al inicio" y No venimos del canal configuracion updatelibrary_wait = [0, 10000, 20000, 30000, 60000] wait = updatelibrary_wait[int( config.get_setting("updatelibrary_wait", "biblioteca"))] if wait > 0: import xbmc xbmc.sleep(wait) heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg( 'pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([ filetools.join(path, f) for f in files if f == "tvshow.nfo" ]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar continue # obtenemos las fecha de auctualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "biblioteca") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta( days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime( '%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "biblioteca" serie.action = "get_temporadas" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: # Actualizamos la biblioteca de Kodi xbmc_library.update(folder=filetools.basename(path)) p_dialog.close() else: logger.info( "No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta" ) except Exception as ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
def get_environment(): """ Devuelve las variables de entorno del OS, de Kodi y de Alfa más habituales, necesarias para el diagnóstico de fallos """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = '%s (%s, %s)' % (str(platform.python_version()), \ str(sys.api_version), str(platform.python_implementation())) environment['os_release'] = str(platform.release()) environment['prod_model'] = '' try: import multiprocessing environment['proc_num'] = ' (%sx)' % str( multiprocessing.cpu_count()) except: environment['proc_num'] = '' if xbmc.getCondVisibility("system.platform.Windows"): try: if platform.platform(): environment['os_release'] = str( platform.platform()).replace('Windows-', '') elif platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) command = ["wmic", "cpu", "get", "name"] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=0x08000000) output_cmd, error_cmd = p.communicate() if PY3 and isinstance(output_cmd, bytes): output_cmd = output_cmd.decode() output_cmd = re.sub(r'\n|\r|\s{2}', '', output_cmd) environment['prod_model'] = str(scrapertools.find_single_match(output_cmd, \ '\w+.*?(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) except: pass if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass environment['prod_model'] += ' (%s)' % config.is_rooted( silent=True) elif xbmc.getCondVisibility("system.platform.Linux"): environment['os_name'] = 'Linux' try: for label_a in subprocess.check_output('hostnamectl').split( FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'Operating' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, 'Operating\s*S\w+:\s*(.*?)\s*$')) break for label_a in subprocess.check_output( ['cat', '/proc/cpuinfo']).split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'model name' in label_a: environment['prod_model'] = str(scrapertools.find_single_match(label_a, \ 'model.*?:\s*(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) break except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) if not environment['os_release']: environment['os_release'] = str(platform.release()) if environment['proc_num'] and environment['prod_model']: environment['prod_model'] += environment['proc_num'] environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( old_div(int(memoryStatus.dwTotalPhys), (1024**2))) environment['mem_free'] = str( old_div(int(memoryStatus.dwAvailPhys), (1024**2))) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( old_div( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]), 1024)) environment['mem_free'] = str( old_div( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]), 1024)) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join("special://userdata", "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join("special://userdata", "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( old_div( int( scrapertools.find_single_match( label_a, '>(\d+)<\/')), 1024**2)) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, '>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, '>(.*?)<\/')) except: pass environment['userdata_path'] = str(config.get_data_path()) environment['userdata_path_perm'] = filetools.file_info( environment['userdata_path']) if not environment['userdata_path_perm']: del environment['userdata_path_perm'] try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' if environment.get('userdata_path_perm', ''): environment['userdata_path'] = environment['userdata_path_perm'] del environment['userdata_path_perm'] environment['torrent_lang'] = '%s/%s' % (config.get_setting("channel_language", default="").upper(), \ config.get_setting("second_language", default="").upper()) try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str(config.get_videolibrary_path()) environment['videolab_path_perm'] = filetools.file_info( environment['videolab_path']) if not environment['videolab_path_perm']: environment['videolab_path_perm'] = environment[ 'videolab_path'] if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): environment['videolab_series'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))): environment['videolab_pelis'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))))) except: pass try: video_updates = [ 'No', 'Inicio', 'Una vez', 'Inicio+Una vez', 'Dos veces al día' ] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' environment['torrent_list'] = [] environment['torrentcli_option'] = '' environment['torrent_error'] = '' environment['torrentcli_rar'] = config.get_setting("mct_rar_unpack", server="torrent", default=True) environment['torrentcli_backgr'] = config.get_setting( "mct_background_download", server="torrent", default=True) environment['torrentcli_lib_path'] = config.get_setting( "libtorrent_path", server="torrent", default="") if environment['torrentcli_lib_path']: lib_path = 'Activo' else: lib_path = 'Inactivo' if config.get_setting("libtorrent_version", server="torrent", default=""): lib_path += '-%s' % config.get_setting( "libtorrent_version", server="torrent", default="") environment['torrentcli_unrar'] = config.get_setting("unrar_path", server="torrent", default="") if environment['torrentcli_unrar']: if xbmc.getCondVisibility("system.platform.Android"): unrar = 'Android' else: unrar = filetools.dirname(environment['torrentcli_unrar']) unrar = filetools.basename(unrar).capitalize() else: unrar = 'Inactivo' torrent_id = config.get_setting("torrent_client", server="torrent", default=0) environment['torrentcli_option'] = str(torrent_id) torrent_options = platformtools.torrent_client_installed() if lib_path != 'Inactivo': torrent_options = ['MCT'] + torrent_options torrent_options = ['BT'] + torrent_options environment['torrent_list'].append({'Torrent_opt': str(torrent_id), 'Libtorrent': lib_path, \ 'RAR_Auto': str(environment['torrentcli_rar']), \ 'RAR_backgr': str(environment['torrentcli_backgr']), \ 'UnRAR': unrar}) environment['torrent_error'] = config.get_setting("libtorrent_error", server="torrent", default="") if environment['torrent_error']: environment['torrent_list'].append( {'Libtorrent_error': environment['torrent_error']}) for torrent_option in torrent_options: cliente = dict() cliente['D_load_Path'] = '' cliente['Libre'] = '?' cliente['Plug_in'] = torrent_option.replace('Plugin externo: ', '') if cliente['Plug_in'] == 'BT': cliente['D_load_Path'] = str( config.get_setting("bt_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'BT-torrents') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("bt_buffer", server="torrent", default=50)) elif cliente['Plug_in'] == 'MCT': cliente['D_load_Path'] = str( config.get_setting("mct_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'MCT-torrent-videos') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("mct_buffer", server="torrent", default=50)) elif xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % cliente['Plug_in']): try: __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % cliente['Plug_in']) except: continue cliente['Plug_in'] = cliente['Plug_in'].capitalize() if cliente['Plug_in'] == 'Torrenter': cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('storage'))) if not cliente['D_load_Path']: cliente['D_load_Path'] = str(filetools.join("special://home/", \ "cache", "xbmcup", "plugin.video.torrenter", "Torrenter")) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('pre_buffer_bytes')) elif cliente['Plug_in'] == 'Torrest': cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('s:download_path'))) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( int( int(__settings__.getSetting('s:buffer_size')) / (1024 * 1024))) else: cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('download_path'))) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('buffer_size')) if __settings__.getSetting( 'download_storage' ) == '1' and __settings__.getSetting('memory_size'): cliente['Memoria'] = str( __settings__.getSetting('memory_size')) if cliente.get('D_load_Path', ''): try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(cliente['D_load_Path']), None, None, ctypes.pointer(free_bytes)) cliente['Libre'] = str(round(float(free_bytes.value) / \ (1024**3), 3)).replace('.', ',') else: disk_space = os.statvfs(cliente['D_load_Path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize cliente['Libre'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)).replace('.', ',') except: pass if cliente.get('D_load_Path_perm', ''): cliente['D_load_Path'] = cliente['D_load_Path_perm'] del cliente['D_load_Path_perm'] environment['torrent_list'].append(cliente) environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in list( proxy_channel_bloqued.items()): if proxy_active != 'OFF': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk("special://logpath/"): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment.get('log_path', ''): environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024*1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = '%s (Upd: %s h.)' % (str(config.get_addon_version()), \ str(config.get_setting("addon_update_timer", default=12)).replace('0', 'No')) environment['assistant_version'] = str(None) if filetools.exists( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')): environment['assistant_version'] = filetools.read( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')) environment['assistant_cf_ua'] = str( config.get_setting('cf_assistant_ua', None)) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['machine'] = '' environment['platform'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['videolab_path_perm'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrent_list'] = [] environment['torrent_lang'] = '' environment['torrentcli_option'] = '' environment['torrentcli_rar'] = '' environment['torrentcli_lib_path'] = '' environment['torrentcli_unrar'] = '' environment['torrent_error'] = '' environment['assistant_version'] = '' environment['assistant_cf_ua'] = '' return environment
def save_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info() # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la videoteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la peli # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code") return 0, 0, -1 _id = item.infoLabels['code'][0] # progress dialog p_dialog = platformtools.dialog_progress( config.get_localized_string(20000), config.get_localized_string(60062)) if config.get_setting( "original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] else: base_name = item.contentTitle base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8") if config.get_setting("lowerize_title", "videolibrary") == 0: base_name = base_name.lower() for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio pelicula:" + path) if not filetools.mkdir(path): logger.debug("No se ha podido crear el directorio") return 0, 0, -1 nfo_path = filetools.join(path, "%s [%s].nfo" % (base_name, _id)) strm_path = filetools.join(path, "%s.strm" % base_name) json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel.lower()))) nfo_exists = filetools.exists(nfo_path) strm_exists = filetools.exists(strm_path) json_exists = filetools.exists(json_path) if not nfo_exists: # Creamos .nfo si no existe logger.info("Creando .nfo: " + nfo_path) head_nfo = scraper.get_nfo(item) item_nfo = Item(title=item.contentTitle, channel="videolibrary", action='findvideos', library_playcounts={"%s [%s]" % (base_name, _id): 0}, infoLabels=item.infoLabels, library_urls={}) else: # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # Crear base_name.strm si no existe item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie', contentTitle=item.contentTitle) strm_exists = filetools.write( strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "") # Solo si existen item_nfo y .strm continuamos if item_nfo and strm_exists: if json_exists: logger.info("El fichero existe. Se sobreescribe") sobreescritos += 1 else: insertados += 1 # Si se ha marcado la opción de url de emergencia, se añade ésta a la película después de haber ejecutado Findvideos del canal try: channel = generictools.verify_channel(item.channel) if config.get_setting("emergency_urls", channel) in [1, 3]: item = emergency_urls(item) if item_nfo.emergency_urls and not isinstance( item_nfo.emergency_urls, dict): del item_nfo.emergency_urls if not item_nfo.emergency_urls: item_nfo.emergency_urls = dict() item_nfo.emergency_urls.update({item.channel: True}) except: logger.error( "No se ha podido guardar las urls de emergencia de %s en la videoteca" % item.contentTitle) if filetools.write(json_path, item.tojson()): p_dialog.update(100, 'Añadiendo película...', item.contentTitle) item_nfo.library_urls[item.channel] = item.url if filetools.write(nfo_path, head_nfo + item_nfo.tojson()): # actualizamos la videoteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(FOLDER_MOVIES, filetools.basename(path) + "/") p_dialog.close() return insertados, sobreescritos, fallidos # Si llegamos a este punto es por q algo ha fallado logger.error("No se ha podido guardar %s en la videoteca" % item.contentTitle) p_dialog.update(100, config.get_localized_string(60063), item.contentTitle) p_dialog.close() return 0, 0, -1
def series(item): logger.info() itemlist = [] # Obtenemos todos los tvshow.nfo de la biblioteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk(library.TVSHOWS_PATH): for f in ficheros: if f == "tvshow.nfo": tvshow_path = filetools.join(raiz, f) # logger.debug(tvshow_path) head_nfo, item_tvshow = library.read_nfo(tvshow_path) item_tvshow.title = item_tvshow.contentTitle item_tvshow.path = raiz item_tvshow.nfo = tvshow_path # Menu contextual: Marcar como visto/no visto visto = item_tvshow.library_playcounts.get(item_tvshow.contentTitle, 0) item_tvshow.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Marcar serie como no vista" contador = 0 else: texto_visto = "Marcar serie como vista" contador = 1 # Menu contextual: Buscar automáticamente nuevos episodios o no if item_tvshow.active and int(item_tvshow.active) > 0: texto_update = "Buscar automáticamente nuevos episodios: Desactivar" value = 0 item_tvshow.text_color = "green" else: texto_update = "Buscar automáticamente nuevos episodios: Activar" value = 1 item_tvshow.text_color = "0xFFDF7401" # Menu contextual: Eliminar serie/canal num_canales = len(item_tvshow.library_urls) if "descargas" in item_tvshow.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Eliminar serie/canal" multicanal = True else: texto_eliminar = "Eliminar esta serie" multicanal = False item_tvshow.context = [{"title": texto_visto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": contador}, {"title": texto_update, "action": "mark_tvshow_as_updatable", "channel": "biblioteca", "active": value}, {"title": texto_eliminar, "action": "eliminar", "channel": "biblioteca", "multicanal": multicanal}, {"title": "Buscar nuevos episodios ahora", "action": "update_serie", "channel":"biblioteca"}] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "biblioteca"}] # logger.debug("item_tvshow:\n" + item_tvshow.tostring('\n')) itemlist.append(item_tvshow) if itemlist: itemlist = sorted(itemlist, key=lambda it: it.title.lower()) itemlist.append(Item(channel=item.channel, action="update_biblio", thumbnail=item.thumbnail, title="Buscar nuevos episodios y actualizar biblioteca", folder=False)) return itemlist
def save_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 @rtype path: str @return: directorio serie """ logger.info() # logger.debug(item.tostring('\n')) path = "" # Si llegados a este punto no tenemos titulo o code, salimos if not (item.contentSerieName or item.infoLabels['code']) or not item.channel: logger.debug("NO ENCONTRADO contentSerieName NI code") return 0, 0, -1, path # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la serie # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code") return 0, 0, -1, path _id = item.infoLabels['code'][0] if config.get_setting( "original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] elif item.infoLabels['tvshowtitle']: base_name = item.infoLabels['tvshowtitle'] elif item.infoLabels['title']: base_name = item.infoLabels['title'] else: base_name = item.contentSerieName base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8") if config.get_setting("lowerize_title", "videolibrary") == 0: base_name = base_name.lower() for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: path = filetools.join(TVSHOWS_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio serie: " + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
def save_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() # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] nostrm_episodelist = [] for root, folders, files in filetools.walk(path): for file in files: season_episode = scrapertools.get_season_and_episode(file) if season_episode == "" or filetools.exists( filetools.join(path, "%s.strm" % season_episode)): continue nostrm_episodelist.append(season_episode) nostrm_episodelist = sorted(set(nostrm_episodelist)) # Silent es para no mostrar progreso (para videolibrary_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress( config.get_localized_string(20000), config.get_localized_string(60064)) p_dialog.update(0, config.get_localized_string(60065)) channel_alt = generictools.verify_channel( serie.channel) #Preparamos para añadir las urls de emergencia emergency_urls_stat = config.get_setting( "emergency_urls", channel_alt) #El canal quiere urls de emergencia? emergency_urls_succ = False channel = __import__('channels.%s' % channel_alt, fromlist=["channels.%s" % channel_alt]) new_episodelist = [] # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean tags = [] if config.get_setting("enable_filter", "videolibrary"): tags = [ x.strip() for x in config.get_setting( "filters", "videolibrary").lower().split(",") ] for e in episodelist: if tags != [] and tags != None and any(tag in e.title.lower() for tag in tags): continue try: season_episode = scrapertools.get_season_and_episode(e.title) # Si se ha marcado la opción de url de emergencia, se añade ésta a cada episodio después de haber ejecutado Findvideos del canal if e.emergency_urls and isinstance(e.emergency_urls, dict): del e.emergency_urls #Borramos trazas anterioires if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode': #Guardamos urls de emergencia? json_path = filetools.join( path, ("%s [%s].json" % (season_episode, e.channel) ).lower()) #Path del .json del episodio if json_path in ficheros: #Si existe el .json sacamos de ahí las urls if overwrite: #pero solo si se se sobrescriben los .json json_epi = Item().fromjson( filetools.read(json_path)) #Leemos el .json if json_epi.emergency_urls: #si existen las urls de emergencia... e.emergency_urls = json_epi.emergency_urls #... las copiamos else: #y si no... e = emergency_urls(e, channel) #... las generamos else: e = emergency_urls( e, channel) #Si el episodio no existe, generamos las urls if e.emergency_urls: #Si ya tenemos urls... emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo elif emergency_urls_stat == 2 and e.contentType == 'episode': #Borramos urls de emergencia? if e.emergency_urls: del e.emergency_urls emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo elif emergency_urls_stat == 3 and e.contentType == 'episode': #Actualizamos urls de emergencia? e = emergency_urls(e, channel) #generamos las urls if e.emergency_urls: #Si ya tenemos urls... emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") new_episodelist.append(e) except: if e.contentType == 'episode': logger.error( "No se ha podido guardar las urls de emergencia de %s en la videoteca" % e.contentTitle) continue # No hay lista de episodios, no hay nada que guardar if not len(new_episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 # fix float porque la division se hace mal en python 2.x t = float(100) / len(new_episodelist) for i, e in enumerate(scraper.sort_episode_list(new_episodelist)): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), config.get_localized_string(60064), e.title) season_episode = "%sx%s" % (e.contentSeason, str( e.contentEpisodeNumber).zfill(2)) strm_path = filetools.join(path, "%s.strm" % season_episode) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) if season_episode in nostrm_episodelist: continue strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros if not strm_exists: # Si no existe season_episode.strm añadirlo item_strm = Item(action='play_from_library', channel='videolibrary', 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 # FILTERTOOLS if item_strm.list_language: # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show 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')) strm_exists = filetools.write( strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo = None if not nfo_exists and e.infoLabels["code"]: # Si no existe season_episode.nfo añadirlo scraper.find_and_set_infoLabels(e) head_nfo = scraper.get_nfo(e) item_nfo = e.clone(channel="videolibrary", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) nfo_exists = filetools.write(nfo_path, head_nfo + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos if nfo_exists and strm_exists: if not json_exists or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: head_nfo, item_nfo = read_nfo(nfo_path) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists: logger.info("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.contentSerieName] = 0 else: logger.info("Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("Fallido: %s" % json_path) fallidos += 1 else: logger.info("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: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) #Si la operación de insertar/borrar urls de emergencia en los .jsons de los episodios ha tenido éxito, se marca el .nfo if emergency_urls_succ: if tvshow_item.emergency_urls and not isinstance( tvshow_item.emergency_urls, dict): del tvshow_item.emergency_urls if emergency_urls_stat in [ 1, 3 ]: #Operación de guardar/actualizar enlaces if not tvshow_item.emergency_urls: tvshow_item.emergency_urls = dict() tvshow_item.emergency_urls.update({serie.channel: True}) elif emergency_urls_stat == 2: #Operación de Borrar enlaces if tvshow_item.emergency_urls and tvshow_item.emergency_urls.get( serie.channel, False): tvshow_item.emergency_urls.pop( serie.channel, None) #borramos la entrada del .nfo if tvshow_item.active == 30: tvshow_item.active = 1 update_last = datetime.date.today() tvshow_item.update_last = update_last.strftime('%Y-%m-%d') update_next = datetime.date.today() + datetime.timedelta( days=int(tvshow_item.active)) tvshow_item.update_next = update_next.strftime('%Y-%m-%d') filetools.write(tvshow_path, head_nfo + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") logger.error( "No se ha podido guardar las urls de emergencia de %s en la videoteca" % tvshow_item.contentSerieName) fallidos = -1 else: # ... si ha sido correcto actualizamos la videoteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_videolibrary xbmc_videolibrary.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 series(item): logger.info("pelisalacarta.channels.biblioteca series") itemlist = [] # Obtenemos todos los tvshow.nfo de la biblioteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk(library.TVSHOWS_PATH): for f in ficheros: if f == "tvshow.nfo": tvshow_path = filetools.join(raiz, f) # logger.debug(tvshow_path) url_scraper, item_tvshow = read_nfo(tvshow_path) item_tvshow.title = item_tvshow.contentTitle item_tvshow.path = raiz item_tvshow.nfo = tvshow_path # Menu contextual: Marcar como visto/no visto visto = item_tvshow.library_playcounts.get( item_tvshow.contentTitle, 0) item_tvshow.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Marcar serie como no vista" contador = 0 else: texto_visto = "Marcar serie como vista" contador = 1 # Menu contextual: Buscar automáticamente nuevos episodios o no if item_tvshow.active: texto_update = "No buscar automáticamente nuevos episodios" value = False item_tvshow.text_color = "green" else: texto_update = "Buscar automáticamente nuevos episodios" value = True item_tvshow.text_color = "0xFFDF7401" # Menu contextual: Eliminar serie/canal num_canales = len(item_tvshow.library_urls) if "descargas" in item_tvshow.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Eliminar serie/canal" multicanal = True else: texto_eliminar = "Eliminar esta serie" multicanal = False item_tvshow.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "biblioteca", "playcount": contador }, { "title": texto_update, "action": "mark_tvshow_as_updatable", "channel": "biblioteca", "active": value }, { "title": texto_eliminar, "action": "eliminar", "channel": "biblioteca", "multicanal": multicanal }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "biblioteca"}] # logger.debug("item_tvshow:\n" + item_tvshow.tostring('\n')) itemlist.append(item_tvshow) return sorted(itemlist, key=lambda it: it.title.lower())
def play( item ): #Permite preparar la descarga de los .torrents y subtítulos externos logger.info() itemlist = [] headers = [] from core import downloadtools from core import ziptools from core import filetools #buscamos la url del .torrent patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?">' patron += '\s*Torrent:<\/td><td class="(?:[^"]+)?">\s*<img src="(?:[^"]+)?"\s*' patron += 'alt="(?:[^"]+)?"\s*border="(?:[^"]+)?"\s*\/>\s*<a onmouseover="' patron += '(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?" href="([^"]+)".*?<\/a>' data, response, item, itemlist = generictools.downloadpage( item.url, timeout=timeout, patron=patron, item=item, itemlist=[], quote_rep=False, check_blocked_IP=True) if not data or response.code in [ 999, 99 ]: # Si ERROR o lista de errores lo reintentamos con otro Host return itemlist # ... Salimos item.url = urlparse.urljoin(host, scrapertools.find_single_match(data, patron)) #buscamos subtítulos en español patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*>\s*Subs.*?<\/td><td class="(?:[^"]+)?"\s*>(.*?)(?:<br\/>)?<\/td><\/tr>' data_subt = scrapertools.find_single_match(data, patron) if data_subt: patron = '<a href="([^"]+)"\s*onmouseover="return overlib\(' patron += "'Download Spanish subtitles'" patron += '\)"\s*onmouseout="(?:[^"]+)?"\s*><img src="(?:[^"]+)?"\s*><\/a>' subt = scrapertools.find_single_match(data_subt, patron) if subt: item.subtitle = urlparse.urljoin(host, subt) if item.subtitle: #Si hay urls de sub-títulos, se descargan from core import httptools headers.append(["User-Agent", httptools.get_user_agent() ]) #Se busca el User-Agent por defecto videolibrary_path = config.get_videolibrary_path( ) #Calculamos el path absoluto a partir de la Videoteca if videolibrary_path.lower().startswith( "smb://"): #Si es una conexión SMB, usamos userdata local videolibrary_path = config.get_data_path( ) #Calculamos el path absoluto a partir de Userdata videolibrary_path = filetools.join(videolibrary_path, "subtitles") #Primero se borra la carpeta de subtitulos para limpiar y luego se crea if filetools.exists(videolibrary_path): filetools.rmtree(videolibrary_path) time.sleep(1) if not filetools.exists(videolibrary_path): filetools.mkdir(videolibrary_path) subtitle_name = 'Rarbg-ES_SUBT.zip' #Nombre del archivo de sub-títulos subtitle_folder_path = filetools.join(videolibrary_path, subtitle_name) #Path de descarga ret = downloadtools.downloadfile(item.subtitle, subtitle_folder_path, headers=headers, continuar=True, silent=True) if filetools.exists(subtitle_folder_path): # Descomprimir zip dentro del addon # --------------------------------- try: unzipper = ziptools.ziptools() unzipper.extract(subtitle_folder_path, videolibrary_path) except: import xbmc xbmc.executebuiltin('Extract("%s", "%s")' % (subtitle_folder_path, videolibrary_path)) time.sleep(1) # Borrar el zip descargado # ------------------------ filetools.remove(subtitle_folder_path) #Tomo el primer archivo de subtítulos como valor por defecto for raiz, subcarpetas, ficheros in filetools.walk( videolibrary_path): for f in ficheros: if f.endswith(".srt"): #f_es = 'rarbg_subtitle.spa.srt' f_es = scrapertools.find_single_match( item.url, '&f=(.*?).torrent$').replace('.', ' ').replace( '-', ' ').lower() + '.spa.srt' if not f_es: f_es = item.infoLabels['originaltitle'] + '.spa.srt' f_es = f_es.replace(':', '').lower() filetools.rename( filetools.join(videolibrary_path, f), filetools.join(videolibrary_path, f_es)) item.subtitle = filetools.join( videolibrary_path, f_es) #Archivo de subtitulos break break itemlist.append(item.clone()) #Reproducción normal return itemlist
def overwrite_tools(item): import videolibrary_service from core import videolibrarytools seleccion = platformtools.dialog_yesno(config.get_localized_string(60581), config.get_localized_string(60582), config.get_localized_string(60583)) if seleccion == 1: # tvshows heading = config.get_localized_string(60584) p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(60585), heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk( videolibrarytools.TVSHOWS_PATH): show_list.extend( [filetools.join(path, f) for f in files if f == "tvshow.nfo"]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) if not serie.active: # si la serie no esta activa descartar continue # Eliminamos la carpeta con la serie ... filetools.rmdirtree(path) # ... y la volvemos a añadir videolibrary_service.update(path, p_dialog, i, t, serie, 3) p_dialog.close() # movies heading = config.get_localized_string(60586) p_dialog2 = platformtools.dialog_progress_bg( config.get_localized_string(60585), heading) p_dialog2.update(0, '') movies_list = [] for path, folders, files in filetools.walk( videolibrarytools.MOVIES_PATH): movies_list.extend([ filetools.join(path, f) for f in files if f.endswith(".json") ]) logger.debug("movies_list %s" % movies_list) if movies_list: t = float(100) / len(movies_list) for i, movie_json in enumerate(movies_list): try: from core import jsontools path = filetools.dirname(movie_json) movie = Item().fromjson(filetools.read(movie_json)) # Eliminamos la carpeta con la pelicula ... filetools.rmdirtree(path) import math heading = config.get_localized_string(60587) p_dialog2.update( int(math.ceil((i + 1) * t)), heading, "%s: %s" % (movie.contentTitle, movie.channel.capitalize())) # ... y la volvemos a añadir videolibrarytools.save_movie(movie) except Exception, ex: logger.error("Error al crear de nuevo la película") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) p_dialog2.close()
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("pelisalacarta.platformcode.library save_library_tvshow") # logger.debug(item.tostring('\n')) path = "" ''''# Itentamos obtener el titulo correcto: # 1. contentSerieName: Este deberia ser el sitio correcto # 2. show if not item.contentSerieName: # Colocamos el titulo en su sitio para que tmdb lo localize item.contentSerieName = item.show''' # Si llegados a este punto no tenemos titulo o tmdb_id, salimos if not (item.contentSerieName or item.infoLabels['tmdb_id']) or not item.channel: logger.debug("NO ENCONTRADO contentSerieName NI tmdb_id") return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llame a uno u otro tmdb_return = tmdb.find_and_set_infoLabels_tmdb(item) # Llegados a este punto podemos tener: # tmdb_return = True: Un item con infoLabels con la información actualizada de la serie # tmdb_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['imdb_id'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not tmdb_return or not item.infoLabels['imdb_id']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN TMDB O NO TIENE IMDB_ID") return 0, 0, -1 _id = item.infoLabels['imdb_id'] if item.infoLabels['title']: base_name = item.infoLabels['title'] else: base_name = item.contentSerieName base_name = filetools.text2filename(base_name) for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH): for c in subcarpetas: if c.endswith("[%s]" % _id): path = filetools.join(raiz, c) break if not path: path = filetools.join(TVSHOWS_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio serie: " + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
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() # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] # 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...') new_episodelist = [] # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean for e in episodelist: try: season_episode = scrapertools.get_season_and_episode(e.title) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") new_episodelist.append(e) except: continue # No hay lista de episodios, no hay nada que guardar if not len(new_episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 # fix float porque la division se hace mal en python 2.x t = float(100) / len(new_episodelist) for i, e in enumerate(scraper.sort_episode_list(new_episodelist)): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Añadiendo episodio...', e.title) season_episode = "%sx%s" % (e.contentSeason, str( e.contentEpisodeNumber).zfill(2)) strm_path = filetools.join(path, "%s.strm" % season_episode) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros if not strm_exists: # Si no existe season_episode.strm añadirlo item_strm = Item(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 # FILTERTOOLS if item_strm.list_idiomas: # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show 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')) strm_exists = filetools.write( strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo = None if not nfo_exists and e.infoLabels["code"]: # Si no existe season_episode.nfo añadirlo scraper.find_and_set_infoLabels(e) head_nfo = scraper.get_nfo(e) item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) nfo_exists = filetools.write(nfo_path, head_nfo + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos if nfo_exists and strm_exists: if not json_exists or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: head_nfo, item_nfo = read_nfo(nfo_path) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists: logger.info("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("Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("Fallido: %s" % json_path) fallidos += 1 else: logger.info("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: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) if tvshow_item.active == 30: tvshow_item.active = 1 update_last = datetime.date.today() tvshow_item.update_last = update_last.strftime('%Y-%m-%d') update_next = datetime.date.today() + datetime.timedelta( days=int(tvshow_item.active)) tvshow_item.update_next = update_next.strftime('%Y-%m-%d') filetools.write(tvshow_path, head_nfo + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") fallidos = -1 else: # ... si ha sido correcto actualizamos la biblioteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_library xbmc_library.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 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() # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('streamondemand', 'Aggiunta episodi...') p_dialog.update(0, 'Aggiunta episodio...') new_episodelist =[] # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean for e in episodelist: try: season_episode = scrapertools.get_season_and_episode(e.title) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") new_episodelist.append(e) except: continue # No hay lista de episodios, no hay nada que guardar if not len(new_episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 # fix float porque la division se hace mal en python 2.x t = float(100) / len(new_episodelist) for i, e in enumerate(scraper.sort_episode_list(new_episodelist)): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Aggiunta episodio...', e.title) season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2)) strm_path = filetools.join(path, "%s.strm" % season_episode) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros if not strm_exists: # Si no existe season_episode.strm añadirlo item_strm = Item(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 # FILTERTOOLS if item_strm.list_idiomas: # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show 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')) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo = None if not nfo_exists and e.infoLabels["code"]: # Si no existe season_episode.nfo añadirlo scraper.find_and_set_infoLabels(e) head_nfo = scraper.get_nfo(e) item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) nfo_exists = filetools.write(nfo_path, head_nfo + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos if nfo_exists and strm_exists: if not json_exists or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: head_nfo, item_nfo = read_nfo(nfo_path) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists: logger.info("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("Sobreescrito: %s" % json_path) sobreescritos += 1 else: logger.info("Fallido: %s" % json_path) fallidos += 1 else: logger.info("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: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) if tvshow_item.active == 30: tvshow_item.active = 1 update_last = datetime.date.today() tvshow_item.update_last = update_last.strftime('%Y-%m-%d') update_next = datetime.date.today() + datetime.timedelta(days=int(tvshow_item.active)) tvshow_item.update_next = update_next.strftime('%Y-%m-%d') filetools.write(tvshow_path, head_nfo + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") fallidos = -1 else: # ... si ha sido correcto actualizamos la biblioteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_library xbmc_library.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 verify_directories_created(): from platformcode import logger from core import filetools from platformcode import xbmc_videolibrary config_paths = [["videolibrarypath", "videolibrary"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) # video store if path == "videolibrarypath": if not saved_path: saved_path = xbmc_videolibrary.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) 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", "Film"], ["folder_tvshows", "Serie TV"]] 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)) # if the directory is created filetools.mkdir(content_path) from platformcode import xbmc_videolibrary xbmc_videolibrary.update_sources(get_setting("videolibrarypath")) xbmc_videolibrary.update_sources(get_setting("downloadpath")) try: from core import scrapertools # We look for the addon.xml file of the active skin skindir = filetools.join(xbmc.translatePath("special://home"), 'addons', xbmc.getSkinDir(), 'addon.xml') if not os.path.isdir(skindir): return # No need to show error in log if folder doesn't exist # We extract the name of the default resolution folder folder = "" data = filetools.read(skindir) res = scrapertools.find_multiple_matches(data, '(<res .*?>)') for r in res: if 'default="true"' in r: folder = scrapertools.find_single_match(r, 'folder="([^"]+)"') break # We check if it exists in the addon and if not, we create it default = filetools.join(get_runtime_path(), 'resources', 'skins', 'Default') if folder and not filetools.exists(filetools.join(default, folder)): filetools.mkdir(filetools.join(default, folder)) # We copy the file to said folder from the 720p folder if it does not exist or if the size is different if folder and folder != '720p': for root, folders, files in filetools.walk(filetools.join(default, '720p')): for f in files: if not filetools.exists(filetools.join(default, folder, f)) or (filetools.getsize(filetools.join(default, folder, f)) != filetools.getsize(filetools.join(default, '720p', f))): filetools.copy(filetools.join(default, '720p', f), filetools.join(default, folder, f), True) except: import traceback logger.error("When checking or creating the resolution folder") logger.error(traceback.format_exc())
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() try: if config.get_setting("update", "videolibrary") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary") heading = config.get_localized_string(60389) p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk( videolibrarytools.TVSHOWS_PATH): show_list.extend([ filetools.join(path, f) for f in files if f == "tvshow.nfo" ]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar continue # obtenemos las fecha de actualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "videolibrary") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta( days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime( '%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "videolibrary" serie.action = "get_seasons" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "videolibrary") == 0: # Actualizamos la videoteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update( folder=filetools.basename(path)) else: update_when_finished = True if config.get_setting( "search_new_content", "videolibrary") == 1 and update_when_finished: # Actualizamos la videoteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update() p_dialog.close() else: logger.info( "No actualiza la videoteca, está desactivado en la configuración de alfa" ) except Exception, ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
def list_tvshows(item): logger.info() itemlist = [] # Obtenemos todos los tvshow.nfo de la videoteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk( videolibrarytools.TVSHOWS_PATH): for f in ficheros: if f == "tvshow.nfo": tvshow_path = filetools.join(raiz, f) # logger.debug(tvshow_path) head_nfo, item_tvshow = videolibrarytools.read_nfo(tvshow_path) item_tvshow.title = item_tvshow.contentTitle item_tvshow.path = raiz item_tvshow.nfo = tvshow_path # Menu contextual: Marcar como visto/no visto visto = item_tvshow.library_playcounts.get( item_tvshow.contentTitle, 0) item_tvshow.infoLabels["playcount"] = visto if visto > 0: texto_visto = "Marcar serie como no vista" contador = 0 else: texto_visto = "Marcar serie como vista" contador = 1 # Menu contextual: Buscar automáticamente nuevos episodios o no if item_tvshow.active and int(item_tvshow.active) > 0: texto_update = "Buscar automáticamente nuevos episodios: Desactivar" value = 0 item_tvshow.text_color = "green" else: texto_update = "Buscar automáticamente nuevos episodios: Activar" value = 1 item_tvshow.text_color = "0xFFDF7401" # Menu contextual: Eliminar serie/canal num_canales = len(item_tvshow.library_urls) if "downloads" in item_tvshow.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Eliminar serie/canal" multicanal = True else: texto_eliminar = "Eliminar esta serie" multicanal = False item_tvshow.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": contador }, { "title": texto_update, "action": "mark_tvshow_as_updatable", "channel": "videolibrary", "active": value }, { "title": texto_eliminar, "action": "delete", "channel": "videolibrary", "multicanal": multicanal }, { "title": "Buscar nuevos episodios ahora", "action": "update_tvshow", "channel": "videolibrary" }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "videolibrary"}] # logger.debug("item_tvshow:\n" + item_tvshow.tostring('\n')) itemlist.append(item_tvshow) if itemlist: itemlist = sorted(itemlist, key=lambda it: it.title.lower()) itemlist.append( Item(channel=item.channel, action="update_videolibrary", thumbnail=item.thumbnail, title="Buscar nuevos episodios y actualizar videoteca", folder=False)) return itemlist
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 = "SERIES_OLD_" + str(time.time()) path_series_old = filetools.join(library.LIBRARY_PATH, new_name) if filetools.rename(library.TVSHOWS_PATH, 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 # 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 config.set_setting("library_version", 'v4') platformtools.dialog_notification( "Biblioteca actualizada al nuevo formato", "%s series convertidas y %s series descartadas. A continuación se va a " "obtener la información de todos los episodios" % (series_insertadas, series_fallidas), time=12000) # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen xbmc_library.clean() return True
def list_movies(item): logger.info() itemlist = [] for raiz, subcarpetas, ficheros in filetools.walk( videolibrarytools.MOVIES_PATH): for f in ficheros: if f.endswith(".nfo"): nfo_path = filetools.join(raiz, f) head_nfo, new_item = videolibrarytools.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 = "Marcar película como no vista" contador = 0 else: texto_visto = "Marcar película como vista" contador = 1 # Menu contextual: Eliminar serie/canal num_canales = len(new_item.library_urls) if "downloads" in new_item.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = "Eliminar película/canal" multicanal = True else: texto_eliminar = "Eliminar esta película" multicanal = False new_item.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": contador }, { "title": texto_eliminar, "action": "delete", "channel": "videolibrary", "multicanal": multicanal }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "videolibrary"}] # logger.debug("new_item: " + new_item.tostring('\n')) itemlist.append(new_item) return sorted(itemlist, key=lambda it: it.title.lower())
def verify_directories_created(): from platformcode import logger from core import filetools from platformcode import xbmc_videolibrary config_paths = [["videolibrarypath", "videolibrary"], ["downloadpath", "downloads"], ["downloadlistpath", "downloads/list"], ["settings_path", "settings_channels"]] for path, default in config_paths: saved_path = get_setting(path) # videoteca if path == "videolibrarypath": if not saved_path: saved_path = xbmc_videolibrary.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) 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", "Film"], ["folder_tvshows", "Serie TV"]] 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) from platformcode import xbmc_videolibrary xbmc_videolibrary.update_sources(get_setting("videolibrarypath")) xbmc_videolibrary.update_sources(get_setting("downloadpath")) try: from core import scrapertools # Buscamos el archivo addon.xml del skin activo skindir = filetools.join(xbmc.translatePath("special://home"), 'addons', xbmc.getSkinDir(), 'addon.xml') if not os.path.isdir(skindir): return # No hace falta mostrar error en el log si no existe la carpeta # Extraemos el nombre de la carpeta de resolución por defecto folder = "" data = filetools.read(skindir) res = scrapertools.find_multiple_matches(data, '(<res .*?>)') for r in res: if 'default="true"' in r: folder = scrapertools.find_single_match(r, 'folder="([^"]+)"') break # Comprobamos si existe en el addon y sino es así, la creamos default = filetools.join(get_runtime_path(), 'resources', 'skins', 'Default') if folder and not filetools.exists(filetools.join(default, folder)): filetools.mkdir(filetools.join(default, folder)) # Copiamos el archivo a dicha carpeta desde la de 720p si éste no existe o si el tamaño es diferente if folder and folder != '720p': for root, folders, files in filetools.walk( filetools.join(default, '720p')): for f in files: if not filetools.exists(filetools.join(default, folder, f)) or \ (filetools.getsize(filetools.join(default, folder, f)) != filetools.getsize(filetools.join(default, '720p', f))): filetools.copy(filetools.join(default, '720p', f), filetools.join(default, folder, f), True) except: import traceback logger.error("Al comprobar o crear la carpeta de resolución") logger.error(traceback.format_exc())
def check_for_update(overwrite=True): logger.debug("Update Series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() estado_verify_playcount_series = False local_ended = True try: if config.get_setting("update", "videolibrary") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary") heading = config.get_localized_string(60389) p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk( videolibrarytools.TVSHOWS_PATH): show_list.extend([ filetools.join(path, f) for f in files if f == "tvshow.nfo" ]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) if serie.local_episodes_path: local_ended = True if serie.infoLabels[ 'number_of_episodes'] == len( serie.local_episodes_list) else False if serie.infoLabels['status'].lower( ) == 'ended' and local_ended: serie.active = 0 filetools.write(tvshow_file, head_nfo + serie.tojson()) path = filetools.dirname(tvshow_file) logger.debug("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) # Check the status of the series.library_playcounts of the Series in case it is incomplete try: estado = False # If we have not done the verification or do not have a playcount, we enter estado = config.get_setting("verify_playcount", "videolibrary") if not estado or estado == False or not serie.library_playcounts: # If it hasn't happened before, we do it now serie, estado = videolibrary.verify_playcount_series( serie, path ) # Also happens if a PlayCount is missing completely except: logger.error(traceback.format_exc()) else: if estado: # If the update was successful ... estado_verify_playcount_series = True # ... is checked to change the Video Library option interval = int(serie.active) # Could be the bool type if not serie.active: # if the series is not active discard if not overwrite: # Synchronize the episodes seen from the Kodi video library with that of Alpha, even if the series is deactivated try: if config.is_xbmc(): # If it's Kodi, we do it from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kod( filetools.join(path, 'tvshow.nfo')) except: logger.error(traceback.format_exc()) continue # Obtain the update date and the next scheduled for this series update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # if the series is active ... if overwrite or config.get_setting("updatetvshows_interval", "videolibrary") == 0: # ... force update regardless of interval serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next = hoy + datetime.timedelta(days=interval) elif interval == 1 and update_next <= hoy: # ...daily update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta( days=7): # if it hasn't been updated for a week, change the interval to weekly interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ... weekly update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # if it has not been updated for 2 weeks, change the interval to monthly interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ... monthly update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if serie_actualizada: update_last = hoy update_next = hoy + datetime.timedelta(days=interval) head_nfo, serie = videolibrarytools.read_nfo( tvshow_file) # Reread the .nfo, which has been modified if interval != int(serie.active) or update_next.strftime( '%Y-%m-%d' ) != serie.update_next or update_last.strftime( '%Y-%m-%d') != serie.update_last: serie.update_last = update_last.strftime('%Y-%m-%d') if update_next > hoy: serie.update_next = update_next.strftime('%Y-%m-%d') serie.active = interval serie.channel = "videolibrary" serie.action = "get_seasons" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "videolibrary") == 0: # We update the Kodi video library: Find content in the series folder if config.is_xbmc() and config.get_setting( "videolibrary_kodi"): from platformcode import xbmc_videolibrary xbmc_videolibrary.update( folder=filetools.basename(path)) else: update_when_finished = True if estado_verify_playcount_series: # If any playcount has been changed, ... estado = config.set_setting( "verify_playcount", True, "videolibrary") # ... we update the Videolibrary option if config.get_setting( "search_new_content", "videolibrary") == 1 and update_when_finished: # We update the Kodi video library: Find content in all series if config.is_xbmc() and config.get_setting( "videolibrary_kodi"): from platformcode import xbmc_videolibrary xbmc_videolibrary.update() p_dialog.close() else: logger.debug("Not update the video library, it is disabled") except Exception as ex: logger.error("An error occurred while updating the series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close() from core.item import Item item_dummy = Item() videolibrary.list_movies(item_dummy, silent=True) if config.get_setting('trakt_sync'): from core import trakt_tools trakt_tools.update_all()
def menu_info(item): logger.info() itemlist = [] data = httptools.downloadpage(item.url).data data = re.sub(r"\n|\r|\t|\s{2}| |<br>", "", data) item.infoLabels["tmdb_id"] = scrapertools.find_single_match(data, '<a href="https://www.themoviedb.org/[^/]+/(\d+)') item.infoLabels["year"] = scrapertools.find_single_match(data, 'class="e_new">(\d{4})') item.infoLabels["plot"] = scrapertools.find_single_match(data, 'itemprop="description">([^<]+)</div>') item.infoLabels["genre"] = ", ".join(scrapertools.find_multiple_matches(data, '<a itemprop="genre"[^>]+>([^<]+)</a>')) if __modo_grafico__: tmdb.set_infoLabels_item(item, __modo_grafico__) action = "findvideos" title = "Ver enlaces" if item.contentType == "tvshow": action = "episodios" title = "Ver capítulos" itemlist.append(item.clone(action=action, title=title)) carpeta = "CINE" tipo = "película" action = "add_pelicula_to_library" extra = "" if item.contentType == "tvshow": carpeta = "SERIES" tipo = "serie" action = "add_serie_to_library" extra = "episodios###library" library_path = config.get_videolibrary_path() if config.get_videolibrary_support(): title = "Añadir %s a la videoteca" % tipo if item.infoLabels["imdb_id"] and not library_path.lower().startswith("smb://"): try: from core import filetools path = filetools.join(library_path, carpeta) files = filetools.walk(path) for dirpath, dirname, filename in files: if item.infoLabels["imdb_id"] in dirpath: namedir = dirpath.replace(path, '')[1:] for f in filename: if f != namedir + ".nfo" and f != "tvshow.nfo": continue from core import videolibrarytools head_nfo, it = videolibrarytools.read_nfo(filetools.join(dirpath, f)) canales = it.library_urls.keys() canales.sort() if "playmax" in canales: canales.pop(canales.index("playmax")) canales.insert(0, "[COLOR red]playmax[/COLOR]") title = "%s ya en tu videoteca. [%s] ¿Añadir?" % (tipo.capitalize(), ",".join(canales)) break except: import traceback logger.error(traceback.format_exc()) pass itemlist.append(item.clone(action=action, title=title, text_color=color5, extra=extra)) token_auth = config.get_setting("token_trakt", "tvmoviedb") if token_auth and item.infoLabels["tmdb_id"]: extra = "movie" if item.contentType != "movie": extra = "tv" itemlist.append(item.clone(channel="tvmoviedb", title="[Trakt] Gestionar con tu cuenta", action="menu_trakt", extra=extra)) itemlist.append(item.clone(channel="trailertools", action="buscartrailer", title="Buscar Tráiler", text_color="magenta", context="")) itemlist.append(item.clone(action="", title="")) ficha = scrapertools.find_single_match(item.url, '-f(\d+)-') if not ficha: ficha = scrapertools.find_single_match(item.url, 'f=(\d+)') itemlist.extend(acciones_fichas(item, sid, ficha, season=True)) itemlist.append(item.clone(action="acciones_cuenta", title="Añadir a una lista", text_color=color3, ficha=ficha)) return itemlist
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() try: if config.get_setting("updatelibrary", "biblioteca") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "biblioteca") heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i+1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar continue # obtenemos las fecha de actualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "biblioteca") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta(days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "biblioteca" serie.action = "get_temporadas" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "biblioteca") == 0: # Actualizamos la biblioteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(folder=filetools.basename(path)) else: update_when_finished = True if config.get_setting("search_new_content", "biblioteca") == 1 and update_when_finished: # Actualizamos la biblioteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update() p_dialog.close() else: logger.info("No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta") except Exception as ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() estado_verify_playcount_series = False try: if config.get_setting("update", "videolibrary") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary") heading = config.get_localized_string(60389) p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(videolibrarytools.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) if not serie: logger.error('.nfo erroneo en ' + str(tvshow_file)) continue path = filetools.dirname(tvshow_file) ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial overwrite_forced = False try: serie, serie, overwrite_forced = generictools.redirect_clone_newpct1(serie, head_nfo, serie, path, overwrite, lookup=True) except: logger.error(traceback.format_exc()) if overwrite_forced == True: overwrite = True serie.update_next = '' logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) #Verificamos el estado del serie.library_playcounts de la Serie por si está incompleto try: estado = False #Si no hemos hecho la verificación o no tiene playcount, entramos estado = config.get_setting("verify_playcount", "videolibrary") if not estado or estado == False or not serie.library_playcounts: #Si no se ha pasado antes, lo hacemos ahora serie, estado = videolibrary.verify_playcount_series(serie, path) #También se pasa si falta un PlayCount por completo except: logger.error(traceback.format_exc()) else: if estado: #Si ha tenido éxito la actualización... estado_verify_playcount_series = True #... se marca para cambiar la opción de la Videoteca interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar if overwrite_forced == False: #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa, aunque la serie esté desactivada try: if config.is_xbmc(): #Si es Kodi, lo hacemos from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_alfa(path + '/tvshow.nfo') except: logger.error(traceback.format_exc()) continue # obtenemos las fecha de actualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "videolibrary") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next = hoy + datetime.timedelta(days=interval) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta(days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if serie_actualizada: update_last = hoy update_next = hoy + datetime.timedelta(days=interval) head_nfo, serie = videolibrarytools.read_nfo(tvshow_file) #Vuelve a leer el.nfo, que ha sido modificado if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next or update_last.strftime('%Y-%m-%d') != serie.update_last: serie.update_last = update_last.strftime('%Y-%m-%d') if update_next > hoy: serie.update_next = update_next.strftime('%Y-%m-%d') if serie.infoLabels["status"] != "Ended": serie.active = interval serie.channel = "videolibrary" serie.action = "get_seasons" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "videolibrary") == 0: # Actualizamos la videoteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(path)) else: update_when_finished = True if estado_verify_playcount_series: #Si se ha cambiado algún playcount, ... estado = config.set_setting("verify_playcount", True, "videolibrary") #... actualizamos la opción de Videolibrary if config.get_setting("search_new_content", "videolibrary") == 1 and update_when_finished: # Actualizamos la videoteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update() p_dialog.close() else: logger.info("No actualiza la videoteca, está desactivado en la configuración de alfa") except Exception, ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
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?' # Rename and create Series directory 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, impossibile creare la directory SERIES") return False else: logger.error("ERROR,impossibile rinominare la directory 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, impossibile creare la directory CINE") return False else: logger.error("ERROR, impossibile rinominare la directory CINE") return False # Convert library from v1 to v4 (xml) 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 aggiornata", 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 # Convert library from v2 to v4 (json) 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 aggiornata", 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 # Convert library from v2 to v4 if version != 'v4': # Get old Series recursively 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 aggiornata", 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( "Film aggiornato", movie.infoLabels['title']) else: movies_fallidas += 1 except: movies_fallidas += 1 config.set_setting("library_version", 'v4') platformtools.dialog_notification( "Libreria aggiornata con il nuovo formato", "%s serie convertite e %s serie scaricate. Continuare per" "ottenere le info sugli episodi" % (series_insertadas, series_fallidas), time=12000) # Cleanup library of empty records if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.clean() return True
def list_tvshows(item): logger.info() itemlist = [] # Obtenemos todos los tvshow.nfo de la videoteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk( videolibrarytools.TVSHOWS_PATH): for f in ficheros: if f == "tvshow.nfo": tvshow_path = filetools.join(raiz, f) # logger.debug(tvshow_path) #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa try: if config.is_xbmc(): #Si es Kodi, lo hacemos from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_alfa( tvshow_path) except: pass head_nfo, item_tvshow = videolibrarytools.read_nfo(tvshow_path) item_tvshow.title = item_tvshow.contentTitle item_tvshow.path = raiz item_tvshow.nfo = tvshow_path # Menu contextual: Marcar como visto/no visto visto = item_tvshow.library_playcounts.get( item_tvshow.contentTitle, 0) item_tvshow.infoLabels["playcount"] = visto if visto > 0: texto_visto = config.get_localized_string(60020) contador = 0 else: texto_visto = config.get_localized_string(60021) contador = 1 # Menu contextual: Buscar automáticamente nuevos episodios o no if item_tvshow.active and int(item_tvshow.active) > 0: texto_update = config.get_localized_string(60022) value = 0 item_tvshow.text_color = "green" else: texto_update = config.get_localized_string(60023) value = 1 item_tvshow.text_color = "0xFFDF7401" # Menu contextual: Eliminar serie/canal num_canales = len(item_tvshow.library_urls) if "downloads" in item_tvshow.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = config.get_localized_string(60024) multicanal = True else: texto_eliminar = config.get_localized_string(60025) multicanal = False item_tvshow.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": contador }, { "title": texto_update, "action": "mark_tvshow_as_updatable", "channel": "videolibrary", "active": value }, { "title": texto_eliminar, "action": "delete", "channel": "videolibrary", "multicanal": multicanal }, { "title": config.get_localized_string(70269), "action": "update_tvshow", "channel": "videolibrary" }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "videolibrary"}] # logger.debug("item_tvshow:\n" + item_tvshow.tostring('\n')) itemlist.append(item_tvshow) if itemlist: itemlist = sorted(itemlist, key=lambda it: it.title.lower()) itemlist.append( Item(channel=item.channel, action="update_videolibrary", thumbnail=item.thumbnail, title=config.get_localized_string(60026), folder=False)) return itemlist
def list_tvshows(item): logger.info() itemlist = [] dead_list = [] zombie_list = [] # Obtenemos todos los tvshow.nfo de la videoteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk( videolibrarytools.TVSHOWS_PATH): for f in ficheros: if f == "tvshow.nfo": tvshow_path = filetools.join(raiz, f) # logger.debug(tvshow_path) #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa try: if config.is_xbmc(): #Si es Kodi, lo hacemos from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_alfa( tvshow_path) except: logger.error(traceback.format_exc()) head_nfo, item_tvshow = videolibrarytools.read_nfo(tvshow_path) if len(item_tvshow.library_urls) > 1: multicanal = True else: multicanal = False ## verifica la existencia de los canales, en caso de no existir el canal se pregunta si se quieren ## eliminar los enlaces de dicho canal for canal in item_tvshow.library_urls: canal = generictools.verify_channel(canal) try: channel_verify = __import__( 'channels.%s' % canal, fromlist=["channels.%s" % canal]) logger.debug('El canal %s parece correcto' % channel_verify) except: dead_item = Item( multicanal=multicanal, contentType='tvshow', dead=canal, path=raiz, nfo=tvshow_path, library_urls=item_tvshow.library_urls, infoLabels={'title': item_tvshow.contentTitle}) if canal not in dead_list and canal not in zombie_list: confirm = platformtools.dialog_yesno( 'Videoteca', 'Parece que el canal [COLOR red]%s[/COLOR] ya no existe.' % canal.upper(), 'Deseas eliminar los enlaces de este canal?') elif canal in zombie_list: confirm = False else: confirm = True if confirm: delete(dead_item) if canal not in dead_list: dead_list.append(canal) continue else: if canal not in zombie_list: zombie_list.append(canal) if len(dead_list) > 0: for canal in dead_list: if canal in item_tvshow.library_urls: del item_tvshow.library_urls[canal] ### continua la carga de los elementos de la videoteca try: #A veces da errores aleatorios, por no encontrar el .nfo. Probablemente problemas de timing item_tvshow.title = item_tvshow.contentTitle item_tvshow.path = raiz item_tvshow.nfo = tvshow_path # Menu contextual: Marcar como visto/no visto visto = item_tvshow.library_playcounts.get( item_tvshow.contentTitle, 0) item_tvshow.infoLabels["playcount"] = visto if visto > 0: texto_visto = config.get_localized_string(60020) contador = 0 else: texto_visto = config.get_localized_string(60021) contador = 1 except: logger.error('No encuentra: ' + str(tvshow_path)) logger.error(traceback.format_exc()) continue # Menu contextual: Buscar automáticamente nuevos episodios o no if item_tvshow.active and int(item_tvshow.active) > 0: texto_update = config.get_localized_string(60022) value = 0 # item_tvshow.text_color = "green" else: texto_update = config.get_localized_string(60023) value = 1 # item_tvshow.text_color = "0xFFDF7401" # Menu contextual: Eliminar serie/canal num_canales = len(item_tvshow.library_urls) if "downloads" in item_tvshow.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = config.get_localized_string(60024) else: texto_eliminar = config.get_localized_string(60025) item_tvshow.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": contador }, { "title": texto_update, "action": "mark_tvshow_as_updatable", "channel": "videolibrary", "active": value }, { "title": texto_eliminar, "action": "delete", "channel": "videolibrary", "multicanal": multicanal }, { "title": config.get_localized_string(70269), "action": "update_tvshow", "channel": "videolibrary" }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "videolibrary"}] # logger.debug("item_tvshow:\n" + item_tvshow.tostring('\n')) ## verifica la existencia de los canales ## if len(item_tvshow.library_urls) > 0: itemlist.append(item_tvshow) if itemlist: itemlist = sorted(itemlist, key=lambda it: it.title.lower()) itemlist.append( Item(channel=item.channel, action="update_videolibrary", thumbnail=item.thumbnail, title=config.get_localized_string(60026), folder=False)) return itemlist
def save_library_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info() # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la peli # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code") return 0, 0, -1 _id = item.infoLabels['code'][0] # progress dialog p_dialog = platformtools.dialog_progress('streamondemand', 'Aggiunta film...') if config.get_setting("original_title_folder", "biblioteca") == 1 and item.infoLabels['originaltitle']: base_name = item.infoLabels['originaltitle'] else: base_name = item.contentTitle base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").lower().encode("utf8") for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio pelicula:" + path) if not filetools.mkdir(path): logger.debug("No se ha podido crear el directorio") return 0, 0, -1 nfo_path = filetools.join(path, "%s [%s].nfo" % (base_name, _id)) strm_path = filetools.join(path, "%s.strm" % base_name) json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel.lower()))) nfo_exists = filetools.exists(nfo_path) strm_exists = filetools.exists(strm_path) json_exists = filetools.exists(json_path) if not nfo_exists: # Creamos .nfo si no existe logger.info("Creando .nfo: " + nfo_path) head_nfo = scraper.get_nfo(item) item_nfo = Item(title=item.contentTitle, channel="biblioteca", action='findvideos', library_playcounts={"%s [%s]" % (base_name, _id): 0}, infoLabels=item.infoLabels, library_urls={}) else: # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # Crear base_name.strm si no existe item_strm = Item(channel='biblioteca', action='play_from_library', strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie', contentTitle = item.contentTitle) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "") # Solo si existen item_nfo y .strm continuamos if item_nfo and strm_exists: if json_exists: logger.info("El fichero existe. Se sobreescribe") sobreescritos += 1 else: insertados += 1 if filetools.write(json_path, item.tojson()): p_dialog.update(100, 'Aggiunta film...', item.contentTitle) item_nfo.library_urls[item.channel] = item.url if filetools.write(nfo_path, head_nfo + item_nfo.tojson()): # actualizamos la biblioteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(FOLDER_MOVIES, filetools.basename(path) + "/") p_dialog.close() return insertados, sobreescritos, fallidos # Si llegamos a este punto es por q algo ha fallado logger.error("No se ha podido guardar %s en la biblioteca" % item.contentTitle) p_dialog.update(100, 'Aggiunta fallita...', item.contentTitle) p_dialog.close() return 0, 0, -1
def get_episodes(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Menu contextual: Releer tvshow.nfo head_nfo, item_nfo = videolibrarytools.read_nfo(item.nfo) # Crear un item en la lista para cada strm encontrado for i in ficheros: if i.endswith('.strm'): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") # Si hay q filtrar por temporada, ignoramos los capitulos de otras temporadas if item.filtrar_season and int(season) != int(item.contentSeason): continue # Obtener los datos del season_episode.nfo nfo_path = filetools.join(raiz, i).replace('.strm', '.nfo') head_nfo, epi = videolibrarytools.read_nfo(nfo_path) # Fijar el titulo del capitulo si es posible if epi.contentTitle: title_episodie = epi.contentTitle.strip() else: title_episodie = config.get_localized_string(60031) % \ (epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2)) epi.contentTitle = "%sx%s" % ( epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2)) epi.title = "%sx%s - %s" % (epi.contentSeason, str(epi.contentEpisodeNumber).zfill(2), title_episodie) if item_nfo.library_filter_show: epi.library_filter_show = item_nfo.library_filter_show # Menu contextual: Marcar episodio como visto o no visto = item_nfo.library_playcounts.get(season_episode, 0) epi.infoLabels["playcount"] = visto if visto > 0: texto = config.get_localized_string(60032) value = 0 else: texto = config.get_localized_string(60033) value = 1 epi.context = [{ "title": texto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": value, "nfo": item.nfo }] # logger.debug("epi:\n" + epi.tostring('\n')) itemlist.append(epi) return sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
def save_library_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info("pelisalacarta.platformcode.library save_library_movie") # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que tmdb lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llamara a uno u otro tmdb_return = tmdb.find_and_set_infoLabels_tmdb(item) # Llegados a este punto podemos tener: # tmdb_return = True: Un item con infoLabels con la información actualizada de la peli # tmdb_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['imdb_id'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not tmdb_return or not item.infoLabels['imdb_id']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN TMDB O NO TIENE IMDB_ID") return 0, 0, -1 _id = item.infoLabels['imdb_id'] # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo película...') base_name = filetools.text2filename(item.contentTitle) for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: if c.endswith("[%s]" % _id): path = filetools.join(raiz, c) break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("pelisalacarta.platformcode.library save_library_movie Creando directorio pelicula:" + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise
def list_movies(item, silent=False): logger.info() itemlist = [] dead_list = [] zombie_list = [] for raiz, subcarpetas, ficheros in filetools.walk( videolibrarytools.MOVIES_PATH): for f in ficheros: if f.endswith(".nfo"): nfo_path = filetools.join(raiz, f) #Sincronizamos las películas vistas desde la videoteca de Kodi con la de Alfa try: if config.is_xbmc(): #Si es Kodi, lo hacemos from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_alfa( nfo_path) except: logger.error(traceback.format_exc()) head_nfo, new_item = videolibrarytools.read_nfo(nfo_path) if not new_item: #Si no ha leído bien el .nfo, pasamos a la siguiente continue if len(new_item.library_urls) > 1: multicanal = True else: multicanal = False ## verifica la existencia de los canales, en caso de no existir el canal se pregunta si se quieren ## eliminar los enlaces de dicho canal for canal_org in new_item.library_urls: canal = generictools.verify_channel(canal_org) try: channel_verify = __import__( 'channels.%s' % canal, fromlist=["channels.%s" % canal]) logger.debug('El canal %s parece correcto' % channel_verify) except: dead_item = Item( multicanal=multicanal, contentType='movie', dead=canal, path=raiz, nfo=nfo_path, library_urls=new_item.library_urls, infoLabels={'title': new_item.contentTitle}) if canal not in dead_list and canal not in zombie_list: confirm = platformtools.dialog_yesno( 'Videoteca', 'Parece que el canal [COLOR red]%s[/COLOR] ya no existe.' % canal.upper(), 'Deseas eliminar los enlaces de este canal?') elif canal in zombie_list: confirm = False else: confirm = True if confirm: delete(dead_item) if canal not in dead_list: dead_list.append(canal) continue else: if canal not in zombie_list: zombie_list.append(canal) if len(dead_list) > 0: for canal in dead_list: if canal in new_item.library_urls: del new_item.library_urls[canal] new_item.nfo = nfo_path new_item.path = raiz new_item.thumbnail = new_item.contentThumbnail # new_item.text_color = "blue" strm_path = new_item.strm_path.replace("\\", "/").rstrip("/") if '/' in new_item.path: new_item.strm_path = strm_path if not filetools.exists( filetools.join(new_item.path, filetools.basename(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 = config.get_localized_string(60016) contador = 0 else: texto_visto = config.get_localized_string(60017) contador = 1 # Menu contextual: Eliminar serie/canal num_canales = len(new_item.library_urls) if "downloads" in new_item.library_urls: num_canales -= 1 if num_canales > 1: texto_eliminar = config.get_localized_string(60018) else: texto_eliminar = config.get_localized_string(60019) new_item.context = [{ "title": texto_visto, "action": "mark_content_as_watched", "channel": "videolibrary", "playcount": contador }, { "title": texto_eliminar, "action": "delete", "channel": "videolibrary", "multicanal": multicanal }] # ,{"title": "Cambiar contenido (PENDIENTE)", # "action": "", # "channel": "videolibrary"}] # logger.debug("new_item: " + new_item.tostring('\n')) itemlist.append(new_item) if silent == False: return sorted(itemlist, key=lambda it: it.title.lower()) else: return
def main(overwrite=True): logger.info("pelisalacarta.library_service Actualizando series...") p_dialog = None try: if config.get_setting("updatelibrary") == "true": if not overwrite: # No venimos del canal configuracion updatelibrary_wait = [0, 10000, 20000, 30000, 60000] wait = updatelibrary_wait[int(config.get_setting("updatelibrary_wait"))] if wait > 0: import xbmc xbmc.sleep(wait) heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"]) # fix float porque la division se hace mal en python 2.x t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): serie = Item().fromjson(filetools.read(tvshow_file, 1)) path = filetools.dirname(tvshow_file) logger.info("pelisalacarta.library_service serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i+1) * t)), heading, serie.contentSerieName) if not serie.active: continue # si la serie esta activa se actualiza logger.info("pelisalacarta.library_service Actualizando " + path) # logger.debug("%s: %s" %(serie.contentSerieName,str(list_canales) )) for channel, url in serie.library_urls.items(): serie.channel = channel serie.url = url p_dialog.update(int(math.ceil((i + 1) * t)), heading, "%s: %s" % (serie.contentSerieName, serie.channel.capitalize())) try: pathchannels = filetools.join(config.get_runtime_path(), "channels", serie.channel + '.py') logger.info("pelisalacarta.library_service Cargando canal: " + pathchannels + " " + serie.channel) if serie.library_filter_show: serie.show = serie.library_filter_show.get(channel, serie.contentSerieName) obj = imp.load_source(serie.channel, pathchannels) itemlist = obj.episodios(serie) try: library.save_library_episodes(path, itemlist, serie, silent=True, overwrite=overwrite) except Exception as ex: logger.info("pelisalacarta.library_service Error al guardar los capitulos de la serie") template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) except Exception as ex: logger.error("Error al obtener los episodios de: {0}". format(serie.show)) template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) p_dialog.close() else: logger.info("No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta") except Exception as ex: logger.info("pelisalacarta.library_service Se ha producido un error al actualizar las series") template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) if p_dialog: p_dialog.close()
def verify_playcount_series(item, path): logger.info() """ Este método revisa y repara el PlayCount de una serie que se haya desincronizado de la lista real de episodios en su carpeta. Las entradas de episodios, temporadas o serie que falten, son creado con la marca de "no visto". Posteriormente se envia a verificar los contadores de Temporadas y Serie En el retorno envía de estado de True si se actualizado o False si no, normalmente por error. Con este estado, el caller puede actualizar el estado de la opción "verify_playcount" en "videolibrary.py". La intención de este método es la de dar una pasada que repare todos los errores y luego desactivarse. Se puede volver a activar en el menú de Videoteca de Alfa. """ #logger.debug("item:\n" + item.tostring('\n')) #Si no ha hecho nunca la verificación, lo forzamos estado = config.get_setting("verify_playcount", "videolibrary") if not estado or estado == False: estado = True #Si no ha hecho nunca la verificación, lo forzamos else: estado = False if item.contentType == 'movie': #Esto es solo para Series return (item, False) if filetools.exists(path): nfo_path = filetools.join(path, "tvshow.nfo") head_nfo, it = videolibrarytools.read_nfo( nfo_path) #Obtenemos el .nfo de la Serie if not hasattr( it, 'library_playcounts' ) or not it.library_playcounts: #Si el .nfo no tiene library_playcounts se lo creamos logger.error('** No tiene PlayCount') it.library_playcounts = {} # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(path).next() # Crear un item en la lista para cada strm encontrado estado_update = False for i in ficheros: if i.endswith('.strm'): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") if season_episode not in it.library_playcounts: #No está incluido el episodio it.library_playcounts.update( {season_episode: 0}) #actualizamos el playCount del .nfo estado_update = True #Marcamos que hemos actualizado algo if 'season %s' % season not in it.library_playcounts: #No está incluida la Temporada it.library_playcounts.update( {'season %s' % season: 0}) #actualizamos el playCount del .nfo estado_update = True #Marcamos que hemos actualizado algo if it.contentSerieName not in it.library_playcounts: #No está incluida la Serie it.library_playcounts.update( {item.contentSerieName: 0}) #actualizamos el playCount del .nfo estado_update = True #Marcamos que hemos actualizado algo if estado_update: logger.error('** Estado de actualización: ' + str(estado) + ' / PlayCount: ' + str(it.library_playcounts)) estado = estado_update # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada for key, value in it.library_playcounts.iteritems(): if key.startswith("season"): season = scrapertools.find_single_match( key, 'season (\d+)') #Obtenemos en núm. de Temporada it = check_season_playcount(it, season) # Guardamos los cambios en item.nfo if filetools.write(nfo_path, head_nfo + it.tojson()): return (it, estado) return (item, False)
def series(item): logger.info("pelisalacarta.channels.biblioteca series") strm_path = library.TVSHOWS_PATH download_path = filetools.join(config.get_library_path(), "Descargas", "Series") itemlist = [] # Obtenemos todos los strm de la biblioteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk(strm_path): for f in ficheros: if f == "tvshow.json": i = filetools.join(raiz, f) tvshow = Item().fromjson(filetools.read(i)) logger.debug(tvshow.tostring()) tvshow.contentChannel = tvshow.channel tvshow.path = os.path.dirname(i) tvshow.title = os.path.basename(os.path.dirname(i)) tvshow.channel = "biblioteca" tvshow.action = "get_temporadas" tvshow.text_color = "blue" itemlist.append(tvshow) # Obtenemos todos los videos de la biblioteca de SERIES recursivamente for raiz, subcarpetas, ficheros in filetools.walk(download_path): for f in ficheros: if f == "tvshow.json": i = filetools.join(raiz, f) tvshow = Item().fromjson(filetools.read(i)) tvshow.contentChannel = "local" tvshow.path = os.path.dirname(i) tvshow.title = os.path.basename(os.path.dirname(i)) tvshow.channel = "biblioteca" tvshow.action = "get_temporadas" tvshow.text_color = "green" itemlist.append(tvshow) library.set_infolabels_from_library(itemlist, tipo="TVShows") # Agrupamos las series por canales join_itemlist = [] for i in range(len(itemlist)): encontrado = False for j in range(i + 1, len(itemlist)): if "tmdb_id" in itemlist[i].infoLabels and "tmdb_id" in itemlist[j].infoLabels: if itemlist[i].infoLabels["tmdb_id"] == itemlist[j].infoLabels["tmdb_id"]: encontrado = True if "list_channels" not in itemlist[i]: list_channels = [] dict_first_channel = {"path": itemlist[i].path, "channel": itemlist[i].contentChannel} list_channels.append(dict_first_channel.copy()) itemlist[j].list_channels = list_channels dict_other_channel = {"path": itemlist[j].path, "channel": itemlist[j].contentChannel} itemlist[j].list_channels.append(dict_other_channel.copy()) itemlist[j].action = "get_canales_tvshow" itemlist[j].text_color = "orange" if "contentTitle" in itemlist[i] and itemlist[i].contentTitle != "": itemlist[i].title = itemlist[i].contentTitle if not encontrado: join_itemlist.append(itemlist[i]) return sorted(join_itemlist, key=lambda it: it.title.lower())
def main(): logger.info("pelisalacarta.library_service Actualizando series...") p_dialog = None try: if config.get_setting("updatelibrary") == "true": heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.json"]) # fix float porque la division se hace mal en python 2.x t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): serie = Item().fromjson(filetools.read(tvshow_file)) path = filetools.dirname(tvshow_file) logger.info("pelisalacarta.library_service serie="+serie.contentSerieName) logger.info("pelisalacarta.library_service Actualizando " + path) logger.info("pelisalacarta.library_service url " + serie.url) show_name = serie.contentTitle if show_name == "": show_name = serie.show p_dialog.update(int(math.ceil((i+1) * t)), heading, show_name) # si la serie esta activa se actualiza if serie.active: try: pathchannels = filetools.join(config.get_runtime_path(), "channels", serie.channel + '.py') logger.info("pelisalacarta.library_service Cargando canal: " + pathchannels + " " + serie.channel) obj = imp.load_source(serie.channel, pathchannels) itemlist = obj.episodios(serie) try: library.save_library_episodes(path, itemlist, serie, True) except Exception as ex: logger.info("pelisalacarta.library_service Error al guardar los capitulos de la serie") template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) except Exception as ex: logger.error("Error al obtener los episodios de: {0}". format(serie.show)) template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) p_dialog.close() else: logger.info("No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta") except Exception as ex: logger.info("pelisalacarta.library_service Se ha producido un error al actualizar las series") template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.info(message) if p_dialog: p_dialog.close()
def peliculas(item): logger.info("pelisalacarta.channels.biblioteca peliculas") strm_path = library.MOVIES_PATH download_path = filetools.join(config.get_library_path(), "Descargas", "Cine") itemlist = [] for raiz, subcarpetas, ficheros in filetools.walk(strm_path): for f in ficheros: if f.endswith(".strm"): i = filetools.join(raiz, f) movie = Item().fromurl(filetools.read(i)) movie.contentChannel = movie.channel movie.path = i movie.title = os.path.splitext(os.path.basename(i))[0].capitalize() movie.channel = "biblioteca" movie.action = "findvideos" movie.text_color = "blue" # fix para que no se ejecute el método de play para la biblioteca de Kodi movie.strm = False itemlist.append(movie) # Obtenemos todos los videos de la biblioteca de CINE recursivamente for raiz, subcarpetas, ficheros in filetools.walk(download_path): for f in ficheros: if not f.endswith(".json") and not f.endswith(".nfo") and not f.endswith(".srt"): i = filetools.join(raiz, f) movie = Item() movie.contentChannel = "local" movie.path = i movie.title = os.path.splitext(os.path.basename(i))[0].capitalize() movie.channel = "biblioteca" movie.action = "play" movie.text_color = "green" itemlist.append(movie) library.set_infolabels_from_library(itemlist, tipo="Movies") # Agrupamos las peliculas por canales join_itemlist = [] for i in range(len(itemlist)): encontrado = False for j in range(i + 1, len(itemlist)): if "tmdb_id" in itemlist[i].infoLabels and "tmdb_id" in itemlist[j].infoLabels: if itemlist[i].infoLabels["tmdb_id"] == itemlist[j].infoLabels["tmdb_id"]: encontrado = True if "list_channels" not in itemlist[i]: list_channels = [] dict_first_channel = {"path": itemlist[i].path, "channel": itemlist[i].contentChannel} list_channels.append(dict_first_channel.copy()) itemlist[j].list_channels = list_channels dict_other_channel = {"path": itemlist[j].path, "channel": itemlist[j].contentChannel} itemlist[j].list_channels.append(dict_other_channel.copy()) itemlist[j].action = "get_canales_movies" itemlist[j].text_color = "orange" # TODO pendiente de probar if "contentTitle" in itemlist[i] and itemlist[i].contentTitle != "": itemlist[i].title = itemlist[i].contentTitle if not encontrado: join_itemlist.append(itemlist[i]) return sorted(join_itemlist, key=lambda it: it.title.lower())
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 save_library_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info("pelisalacarta.platformcode.library save_library_movie") # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que tmdb lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar # TODO configurar para segun el scraper se llamara a uno u otro tmdb_return = tmdb.find_and_set_infoLabels_tmdb(item) # Llegados a este punto podemos tener: # tmdb_return = True: Un item con infoLabels con la información actualizada de la peli # tmdb_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['imdb_id'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not tmdb_return or not item.infoLabels['imdb_id']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN TMDB O NO TIENE IMDB_ID") return 0, 0, -1 _id = item.infoLabels['imdb_id'] # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo película...') base_name = filetools.text2filename(item.contentTitle) for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: if c.endswith("[%s]" % _id): path = filetools.join(raiz, c) break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info( "pelisalacarta.platformcode.library save_library_movie Creando directorio pelicula:" + path) try: filetools.mkdir(path) except OSError, exception: if exception.errno != errno.EEXIST: raise