def emergency_urls(item, channel=None, path=None): logger.info() import re """ Llamamos a Findvideos del canal con la variable "item.videolibray_emergency_urls = True" para obtener la variable "item.emergency_urls" con la lista de listas de tuplas de los enlaces torrent y de servidores directos para ese episodio o película En la lista [0] siempre deben ir los enlaces torrents, si los hay. Si se desea cachear los .torrents, la búsqueda va contra esa lista. En la lista dos irán los enlaces de servidores directos, pero también pueden ir enlaces magnet (que no son cacheables) """ #lanazamos un "lookup" en el "findvideos" del canal para obtener los enlaces de emergencia try: if channel == None: #Si el llamador no ha aportado la estructura de channel, se crea channel = generictools.verify_channel(item.channel) #Se verifica si es un clon, que devuelva "newpct1" channel = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel]) if hasattr(channel, 'findvideos'): #Si el canal tiene "findvideos"... item.videolibray_emergency_urls = True #... se marca como "lookup" channel_save = item.channel #... guarda el canal original por si hay fail-over en Newpct1 item_res = getattr(channel, 'findvideos')(item) #... se procesa Findvideos item_res.channel = channel_save #... restaura el canal original por si hay fail-over en Newpct1 item_res.category = channel_save.capitalize() #... y la categoría del item_res.videolibray_emergency_urls #... y se borra la marca de lookup except: logger.error('ERROR al procesar el título en Findvideos del Canal: ' + item.channel + ' / ' + item.title) logger.error(traceback.format_exc()) item_res = item.clone() #Si ha habido un error, se devuelve el Item original #Si el usuario ha activado la opción "emergency_urls_torrents", se descargarán los archivos .torrent de cada título else: #Si se han cacheado con éxito los enlaces... try: channel_bis = generictools.verify_channel(item.channel) if config.get_setting("emergency_urls_torrents", channel_bis) and item_res.emergency_urls and path != None: videolibrary_path = config.get_videolibrary_path() #detectamos el path absoluto del título movies = config.get_setting("folder_movies") series = config.get_setting("folder_tvshows") if movies in path: folder = movies else: folder = series videolibrary_path = filetools.join(videolibrary_path, folder) i = 1 for url in item_res.emergency_urls[0]: #Recorremos las urls de emergencia... torrents_path = re.sub(r'(?:\.\w+$)', '_%s.torrent' % str(i).zfill(2), path) path_real = caching_torrents(url, torrents_path=torrents_path) #... para descargar los .torrents if path_real: #Si ha tenido éxito... item_res.emergency_urls[0][i-1] = path_real.replace(videolibrary_path, '') #se guarda el "path" relativo i += 1 except: logger.error('ERROR al cachear el .torrent de: ' + item.channel + ' / ' + item.title) logger.error(traceback.format_exc()) item_res = item.clone() #Si ha habido un error, se devuelve el Item original #logger.debug(item_res.emergency_urls) return item_res #Devolvemos el Item actualizado con los enlaces de emergencia
def emergency_urls(item, channel=None): """ Llamamos a Findvideos del canal con la variable "item.videolibray_emergency_urls = True" para obtener la variable "item.matches" con la lista de listas de tuplas de los enlaces torrent y de servidores directos para ese episodio o película """ try: if channel == None: channel = generictools.verify_channel(item.channel) channel = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel]) if hasattr(channel, 'findvideos'): item.videolibray_emergency_urls = True item_res = getattr(channel, 'findvideos')(item) del item_res.videolibray_emergency_urls except: item_res = item.clone() #logger.debug(item_res.emergency_urls) return item_res
def update_tvshow(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) heading = config.get_localized_string(60037) p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), heading) p_dialog.update(0, heading, item.contentSerieName) import videolibrary_service if videolibrary_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(item.path)) p_dialog.close() for channel, url in list(item.library_urls.items()): channel_f = generictools.verify_channel(channel) if config.get_setting('auto_download_new', channel_f): from channels import downloads downloads.download_auto(item) break
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. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize 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 if not PY3: base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8") else: base_name = filetools.validate_path(base_name.replace('/', '-')) 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: headers = {} if item.headers: headers = item.headers channel = generictools.verify_channel(item.channel) if config.get_setting("emergency_urls", channel) in [1, 3]: item = emergency_urls(item, None, json_path, headers=headers) 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) logger.error(traceback.format_exc()) 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 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 = next(filetools.walk(path)) 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]) if serie.torrent_caching_fail: #Si el proceso de conversión ha fallado, no se cachean emergency_urls_stat = 0 del serie.torrent_caching_fail 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: headers = {} if e.headers: headers = e.headers 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) if not season_episode: continue # 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 anteriores json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) #Path del .json del episodio if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode': #Guardamos urls de emergencia? if not silent: p_dialog.update(0, 'Cacheando enlaces y archivos .torrent...', e.title) #progress dialog 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, json_path, headers=headers) #... las generamos else: e = emergency_urls(e, channel, json_path, headers=headers) #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? if not silent: p_dialog.update(0, 'Cacheando enlaces y archivos .torrent...', e.title) #progress dialog e = emergency_urls(e, channel, json_path, headers=headers) #generamos las urls if e.emergency_urls: #Si ya tenemos urls... emergency_urls_succ = True #... es un éxito y vamos a marcar el .nfo if not e.infoLabels["tmdb_id"] or (serie.infoLabels["tmdb_id"] and e.infoLabels["tmdb_id"] != serie.infoLabels["tmdb_id"]): #en series multicanal, prevalece el infolabels... e.infoLabels = serie.infoLabels #... del canal actual y no el del original e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") if e.videolibray_emergency_urls: del e.videolibray_emergency_urls if e.channel_redir: del e.channel_redir #... y se borran las marcas de redirecciones 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) logger.error(traceback.format_exc()) 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 try: t = float(100) / len(new_episodelist) except: t = 0 last_season_episode = '' 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) high_sea = e.contentSeason high_epi = e.contentEpisodeNumber if scrapertools.find_single_match(e.title, '[a|A][l|L]\s*(\d+)'): high_epi = int(scrapertools.find_single_match(e.title, 'al\s*(\d+)')) max_sea = e.infoLabels["number_of_seasons"] max_epi = 0 if e.infoLabels["number_of_seasons"] and (e.infoLabels["temporada_num_episodios"] or e.infoLabels["number_of_seasons"] == 1): if e.infoLabels["number_of_seasons"] == 1 and e.infoLabels["number_of_episodes"]: max_epi = e.infoLabels["number_of_episodes"] else: max_epi = e.infoLabels["temporada_num_episodios"] 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: logger.error('Error en la estructura de la Videoteca: Serie ' + serie.contentSerieName + ' ' + season_episode) 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, "")) if item_nfo.emergency_urls: del item_nfo.emergency_urls #Solo se mantiene en el .json del episodio 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) # En series multicanal, prevalece el infolabels del canal actual y no el del original if not e.infoLabels["tmdb_id"] or (item_nfo.infoLabels["tmdb_id"] \ and e.infoLabels["tmdb_id"] != item_nfo.infoLabels["tmdb_id"]): 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 #logger.debug('high_sea x high_epi: %sx%s' % (str(high_sea), str(high_epi))) #logger.debug('max_sea x max_epi: %sx%s' % (str(max_sea), str(max_epi))) if not silent: p_dialog.close() if news_in_playcounts or emergency_urls_succ or serie.infoLabels["status"] == "Ended" or serie.infoLabels["status"] == "Canceled": # 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() if tvshow_item.library_urls.get(serie.channel, False): 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 if tvshow_item.infoLabels["tmdb_id"] == serie.infoLabels["tmdb_id"]: tvshow_item.infoLabels = serie.infoLabels tvshow_item.infoLabels["title"] = tvshow_item.infoLabels["tvshowtitle"] if max_sea == high_sea and max_epi == high_epi and (tvshow_item.infoLabels["status"] == "Ended" or tvshow_item.infoLabels["status"] == "Canceled") and insertados == 0 and fallidos == 0: tvshow_item.active = 0 # ... no la actualizaremos más logger.debug("%s [%s]: serie 'Terminada' o 'Cancelada'. Se desactiva la actualización periódica" % \ (serie.contentSerieName, serie.channel)) 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) logger.error(traceback.format_exc()) 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 update(path, p_dialog, i, t, serie, overwrite): logger.info("Actualizando " + path) from core import filetools from core import channeltools, videolibrarytools from platformcode import platformtools from channels import videolibrary from lib import generictools if config.is_xbmc(): from platformcode import xbmc_videolibrary insertados_total = 0 head_nfo, it = videolibrarytools.read_nfo(path + '/tvshow.nfo') category = serie.category # logger.debug("%s: %s" %(serie.contentSerieName,str(list_canales) )) for channel, url in list(serie.library_urls.items()): serie.channel = channel serie.url = url ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial try: head_nfo, it = videolibrarytools.read_nfo( path + '/tvshow.nfo') #Refresca el .nfo para recoger actualizaciones if not it: logger.error('.nfo erroneo en ' + str(path)) continue if it.emergency_urls: serie.emergency_urls = it.emergency_urls serie.category = category serie, it, overwrite = generictools.redirect_clone_newpct1( serie, head_nfo, it, path, overwrite) except: logger.error(traceback.format_exc()) channel_enabled = channeltools.is_enabled(serie.channel) if channel_enabled: heading = config.get_localized_string(60389) 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("Cargando canal: " + pathchannels) if serie.library_filter_show: serie.show = serie.library_filter_show.get( serie.channel, serie.contentSerieName) obj = __import__('channels.%s' % serie.channel, fromlist=["channels.%s" % serie.channel]) itemlist = getattr(obj, 'episodios')( serie) #... se procesa Episodios para ese canal try: if int(overwrite) == 3: # Sobrescribir todos los archivos (tvshow.nfo, 1x01.nfo, 1x01 [canal].json, 1x01.strm, etc...) insertados, sobreescritos, fallidos, notusedpath = videolibrarytools.save_tvshow( serie, itemlist) #serie= videolibrary.check_season_playcount(serie, serie.contentSeason) #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()): # serie.infoLabels['playcount'] = serie.playcount else: insertados, sobreescritos, fallidos = videolibrarytools.save_episodes( path, itemlist, serie, silent=True, overwrite=overwrite) #it = videolibrary.check_season_playcount(it, it.contentSeason) #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()): # serie.infoLabels['playcount'] = serie.playcount insertados_total += insertados except Exception as ex: logger.error("Error al guardar los capitulos de la serie") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) logger.error(traceback.format_exc()) except Exception as ex: logger.error("Error al obtener los episodios de: %s" % serie.show) template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) logger.error(traceback.format_exc()) #Si el canal lo permite, se comienza el proceso de descarga de los nuevos episodios descargados serie.channel = generictools.verify_channel(serie.channel) if insertados > 0 and config.get_setting( 'auto_download_new', serie.channel, default=False): config.set_setting( "search_new_content", 1, "videolibrary") # Escaneamos a final todas la series serie.sub_action = 'auto' serie.category = itemlist[0].category from channels import downloads downloads.save_download(serie, silent=True) if serie.sub_action: del serie.sub_action else: logger.debug("Canal %s no activo no se actualiza" % serie.channel) #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa try: if config.is_xbmc() and not config.get_setting( 'cleanlibrary', 'videolibrary', default=False): #Si es Kodi, lo hacemos xbmc_videolibrary.mark_content_as_watched_on_alfa(path + '/tvshow.nfo') except: logger.error(traceback.format_exc()) return insertados_total > 0
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 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