def delete_all(_item): for file in filetools.listdir(_item.path): if file.endswith(".strm") or file.endswith( ".nfo") or file.endswith(".json") or file.endswith( ".torrent"): filetools.remove(filetools.join(_item.path, file)) raiz, carpeta_serie, ficheros = next(filetools.walk(_item.path)) if ficheros == []: filetools.rmdir(_item.path) if config.is_xbmc(): import xbmc # esperamos 3 segundos para dar tiempo a borrar los ficheros xbmc.sleep(3000) # TODO mirar por qué no funciona al limpiar en la videoteca de Kodi al añadirle un path # limpiamos la videoteca de Kodi from platformcode import xbmc_videolibrary xbmc_videolibrary.clean() logger.info("Eliminados todos los enlaces") platformtools.itemlist_refresh()
def show_option(channel, itemlist, text_color='yellow', thumbnail=None, fanart=None): ''' Agrega la opcion Configurar AutoPlay en la lista recibida :param channel: str :param itemlist: list (lista donde se desea integrar la opcion de configurar AutoPlay) :param text_color: str (color para el texto de la opcion Configurar Autoplay) :param thumbnail: str (direccion donde se encuentra el thumbnail para la opcion Configurar Autoplay) :return: ''' logger.info() if not config.is_xbmc(): return itemlist if thumbnail == None: # thumbnail = 'https://s7.postimg.cc/65ooga04b/Auto_Play.png' thumbnail = os.path.join(config.get_runtime_path(), "resources", "media", "themes", "default", "thumb_autoplay.png") if fanart == None: # fanart = 'https://s7.postimg.cc/65ooga04b/Auto_Play.png' fanart = os.path.join(config.get_runtime_path(), "resources", "media", "themes", "default", "fanart_autoplay.png") plot_autoplay = config.get_localized_string(60399) itemlist.append( Item(channel=__channel__, title=config.get_localized_string(60071), action="autoplay_config", text_color=text_color, thumbnail=thumbnail, fanart=fanart, plot=plot_autoplay, from_channel=channel)) return itemlist
def show_option(channel, itemlist, text_color=colorKOD, thumbnail=None, fanart=None): ''' Agrega la opcion Configurar AutoPlay en la lista recibida :param channel: str :param itemlist: list (lista donde se desea integrar la opcion de configurar AutoPlay) :param text_color: str (color para el texto de la opcion Configurar Autoplay) :param thumbnail: str (direccion donde se encuentra el thumbnail para la opcion Configurar Autoplay) :return: ''' from channelselector import get_thumb from core.support import typo logger.info() if not config.is_xbmc(): return itemlist if thumbnail == None: thumbnail = get_thumb('autoplay.png') # if fanart == None: # fanart = get_thumb('autoplay.png') plot_autoplay = config.get_localized_string(60399) itemlist.append( Item( channel=__channel__, title=typo(config.get_localized_string(60071), 'bold color kod'), action="autoplay_config", text_color=text_color, text_bold=True, thumbnail=thumbnail, # fanart=fanart, plot=plot_autoplay, from_channel=channel, folder=False)) return itemlist
def mainlist(item): logger.info() itemlist = list() itemlist.append(Item(channel=CHANNELNAME, title=config.get_localized_string(60535), action="settings", folder=False, thumbnail=get_thumb("setting_0.png"))) if AUTOSTART is False: autostart_mode = config.get_localized_string(70707) else: autostart_mode = config.get_localized_string(70708) itemlist.append(Item(channel=CHANNELNAME, title=autostart_mode + " " + config.get_localized_string(70706), action="autostart", folder=False, thumbnail=get_thumb("setting_0.png"))) #itemlist.append(Item(channel=CHANNELNAME, title="", action="", folder=False, thumbnail=get_thumb("setting_0.png"))) itemlist.append(Item(channel=CHANNELNAME, title=config.get_localized_string(60536) + ":", text_bold=True, action="", folder=False, thumbnail=get_thumb("setting_0.png"))) itemlist.append(Item(channel=CHANNELNAME, title=" " + config.get_localized_string(60537), action="menu_channels", folder=True, thumbnail=get_thumb("channels.png"))) itemlist.append(Item(channel=CHANNELNAME, title=" " + config.get_localized_string(60538), action="menu_servers", folder=True, thumbnail=get_thumb("channels.png"))) itemlist.append(Item(channel="news", title=" " + config.get_localized_string(60539), action="menu_opciones", folder=True, thumbnail=get_thumb("news.png"))) itemlist.append(Item(channel="search", title=" " + config.get_localized_string(60540), action="opciones", folder=True, thumbnail=get_thumb("search.png"))) itemlist.append(Item(channel=CHANNELNAME, title=" " + config.get_localized_string(60541), action="channel_config", config="downloads", folder=True, thumbnail=get_thumb("downloads.png"))) if config.get_videolibrary_support(): itemlist.append(Item(channel="videolibrary", title=" " + config.get_localized_string(60542), action="channel_config", folder=True, thumbnail=get_thumb("videolibrary.png"))) if config.is_xbmc(): itemlist.append(Item(channel=CHANNELNAME, title=" " + config.get_localized_string(70253), action="setting_torrent", folder=True, thumbnail=get_thumb("channels_torrent.png"))) #itemlist.append(Item(channel=CHANNELNAME, action="", title="", folder=False, thumbnail=get_thumb("setting_0.png"))) itemlist.append(Item(channel=CHANNELNAME, title=config.get_localized_string(60544), action="submenu_tools", folder=True, thumbnail=get_thumb("setting_0.png"))) return itemlist
def test_video_exists(page_url): logger.info("(page_url='%s')" % page_url) try: response = httptools.downloadpage(page_url) except: pass if not response.data or "urlopen error [Errno 1]" in str(response.code): from platformcode import config if config.is_xbmc(): return False, "[Rapidvideo] Questo connettore funziona solo con versione di Kodi 17 o successive" elif config.get_platform() == "plex": return False, "[Rapidvideo] Questo connettore non funziona con la tua versione di Plex, aggiornamento versione richiesto" elif config.get_platform() == "mediaserver": return False, "[Rapidvideo] Questo connettore richiede un aggiornamento di python alla versione 2.7.9 o superiore" if "Object not found" in response.data: return False, "[Rapidvideo] File inesistente o e stato cancellato" if response.code == 500: return False, "[Rapidvideo] Server error, riprova in seguito" return True, ""
def test_video_exists(page_url): logger.info("(page_url='%s')" % page_url) try: response = httptools.downloadpage(page_url) except: pass if not response.data or "urlopen error [Errno 1]" in str(response.code): from platformcode import config if config.is_xbmc(): return False, "[Rapidvideo] Este conector solo funciona a partir de Kodi 17" elif config.get_platform() == "plex": return False, "[Rapidvideo] Este conector no funciona con tu versión de Plex, intenta actualizarla" elif config.get_platform() == "mediaserver": return False, "[Rapidvideo] Este conector requiere actualizar python a la versión 2.7.9 o superior" if "Object not found" in response.data: return False, "[Rapidvideo] El archivo no existe o ha sido borrado" if response.code == 500: return False, "[Rapidvideo] Error de servidor, inténtelo más tarde." return True, ""
def test_video_exists(page_url): logger.info("(page_url='%s')" % page_url) try: response = httptools.downloadpage(page_url) except: pass if not response.data or "urlopen error [Errno 1]" in str(response.code): from platformcode import config if config.is_xbmc(): return False, "[Rapidvideo] Questo connettore funziona solo con versioni le versioni 17 di Kodi" elif config.get_platform() == "plex": return False, "[Rapidvideo] Questo connettore non funziona con la tua versione Plex installata" elif config.get_platform() == "mediaserver": return False, "[Rapidvideo] Questo connettore richiede la versione di Python 2.7.9 o successive" if "Object not found" in response.data: return False, "[Rapidvideo] Il file non esiste oppure e stato cancellato" if response.code == 500: return False, "[Rapidvideo] Problemi temporanei nel server" return True, ""
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc() and item.contentType == 'episode': from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi( item, item.playcount) platformtools.itemlist_refresh()
def 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 delete_videolibrary(item): logger.info() if not platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(80037)): return p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80038)) p_dialog.update(0) if config.is_xbmc() and config.get_setting("videolibrary_kodi"): from platformcode import xbmc_videolibrary xbmc_videolibrary.clean() p_dialog.update(10) filetools.rmdirtree(videolibrarytools.MOVIES_PATH) p_dialog.update(50) filetools.rmdirtree(videolibrarytools.TVSHOWS_PATH) p_dialog.update(90) config.verify_directories_created() p_dialog.update(100) xbmc.sleep(1000) p_dialog.close() platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80039), time=5000, sound=False)
def mark_content_as_watched(item): logger.info() #logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) if item.contentType == 'movie': name_file = os.path.splitext(filetools.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # it is verified that if all the episodes of a season are marked, tb the season is marked if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # We save the changes to item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow' and item.type != 'episode' : # Update entire series new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def mark_content_as_watched2(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.isfile(item.nfo): head_nfo, it = videolibrarytools.read_nfo(item.nfo) name_file = "" if item.contentType == 'movie' or item.contentType == 'tvshow': name_file = os.path.splitext(filetools.basename(item.nfo))[0] if name_file != 'tvshow' : it.library_playcounts.update({name_file: item.playcount}) if item.contentType == 'episode' or item.contentType == 'tvshow' or item.contentType == 'list' or name_file == 'tvshow': name_file = os.path.splitext(filetools.basename(item.strm_path))[0] num_season = name_file [0] item.__setattr__('contentType', 'episode') item.__setattr__('contentSeason', num_season) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # it is verified that if all the episodes of a season are marked, tb the season is marked if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # We save the changes to item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if config.is_xbmc(): from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_content_as_watched_on_kodi(item , item.playcount)
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 service if service.update(item.path, p_dialog, 0, 100, item, False) and config.is_xbmc() and config.get_setting("videolibrary_kodi"): from platformcode import xbmc_videolibrary xbmc_videolibrary.update(folder=filetools.basename(item.path)) p_dialog.close() # check if the TV show is ended or has been canceled and ask the user to remove it from the video library update nfo_path = filetools.join(item.path, "tvshow.nfo") head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path) if item.active and not item_nfo.active: # if not platformtools.dialog_yesno(config.get_localized_string(60037).replace('...',''), config.get_localized_string(70268) % item.contentSerieName): item_nfo.active = 1 filetools.write(nfo_path, head_nfo + item_nfo.tojson()) platformtools.itemlist_refresh()
def show_option(channel, itemlist, text_color='yellow', thumbnail=None, fanart=None): ''' Agrega la opcion Configurar AutoPlay en la lista recibida :param channel: str :param itemlist: list (lista donde se desea integrar la opcion de configurar AutoPlay) :param text_color: str (color para el texto de la opcion Configurar Autoplay) :param thumbnail: str (direccion donde se encuentra el thumbnail para la opcion Configurar Autoplay) :return: ''' logger.info() if not config.is_xbmc(): return itemlist if thumbnail == None: thumbnail = 'https://s7.postimg.org/65ooga04b/Auto_Play.png' if fanart == None: fanart = 'https://s7.postimg.org/65ooga04b/Auto_Play.png' plot_autoplay = 'AutoPlay permite auto reproducir los enlaces directamente, basándose en la configuracion de tus ' \ 'servidores y calidades favoritas. ' itemlist.append( Item(channel=__channel__, title="Configurar AutoPlay", action="autoplay_config", text_color=text_color, thumbnail=thumbnail, fanart=fanart, plot=plot_autoplay, from_channel=channel)) return itemlist
def move_videolibrary(current_path, new_path, current_movies_folder, new_movies_folder, current_tvshows_folder, new_tvshows_folder): logger.info() backup_current_path = current_path backup_new_path = new_path logger.info('current_path: ' + current_path) logger.info('new_path: ' + new_path) logger.info('current_movies_folder: ' + current_movies_folder) logger.info('new_movies_folder: ' + new_movies_folder) logger.info('current_tvshows_folder: ' + current_tvshows_folder) logger.info('new_tvshows_folder: ' + new_tvshows_folder) notify = False progress = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80011)) current_path = u'' + xbmc.translatePath(current_path) new_path = u'' + xbmc.translatePath(new_path) current_movies_path = u'' + filetools.join(current_path, current_movies_folder) new_movies_path = u'' + filetools.join(new_path, new_movies_folder) current_tvshows_path = u'' + filetools.join(current_path, current_tvshows_folder) new_tvshows_path = u'' + filetools.join(new_path, new_tvshows_folder) logger.info('current_movies_path: ' + current_movies_path) logger.info('new_movies_path: ' + new_movies_path) logger.info('current_tvshows_path: ' + current_tvshows_path) logger.info('new_tvshows_path: ' + new_tvshows_path) from platformcode import xbmc_videolibrary movies_path, tvshows_path = xbmc_videolibrary.check_sources(new_movies_path, new_tvshows_path) logger.info('check_sources: ' + str(movies_path) + ', ' + str(tvshows_path)) if movies_path or tvshows_path: if not movies_path: filetools.rmdir(new_movies_path) if not tvshows_path: filetools.rmdir(new_tvshows_path) config.set_setting("videolibrarypath", backup_current_path) config.set_setting("folder_movies", current_movies_folder) config.set_setting("folder_tvshows", current_tvshows_folder) xbmc_videolibrary.update_sources(backup_current_path, backup_new_path) progress.update(100) xbmc.sleep(1000) progress.close() platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80028)) return config.verify_directories_created() progress.update(10, config.get_localized_string(20000) + '\n' + config.get_localized_string(80012)) if current_movies_path != new_movies_path: if filetools.listdir(current_movies_path): dir_util.copy_tree(current_movies_path, new_movies_path) notify = True filetools.rmdirtree(current_movies_path) progress.update(40) if current_tvshows_path != new_tvshows_path: if filetools.listdir(current_tvshows_path): dir_util.copy_tree(current_tvshows_path, new_tvshows_path) notify = True filetools.rmdirtree(current_tvshows_path) progress.update(70) if current_path != new_path and not filetools.listdir(current_path) and not "plugin.video.kod\\videolibrary" in current_path: filetools.rmdirtree(current_path) xbmc_videolibrary.update_sources(backup_new_path, backup_current_path) if config.is_xbmc() and config.get_setting("videolibrary_kodi"): xbmc_videolibrary.update_db(backup_current_path, backup_new_path, current_movies_folder, new_movies_folder, current_tvshows_folder, new_tvshows_folder, progress) else: progress.update(100) xbmc.sleep(1000) progress.close() if notify: platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80014), time=5000, sound=False)
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) path = filetools.dirname(tvshow_file) 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 not overwrite: #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') 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 peliculas(item): logger.info() itemlist = [] if "valores" in item and item.valores: itemlist.append( item.clone(action="", title=item.valores, text_color=color4)) action = "findvideos" data = httptools.downloadpage(item.url).data bloque = scrapertools.find_multiple_matches( data, '<div class="media-card "(.*?)<div class="hidden-info">') for match in bloque: if item.extra == "mapa": patron = '.*?src="([^"]+)".*?href="([^"]+)">([^<]+)</a>' matches = scrapertools.find_multiple_matches(match, patron) for scrapedthumbnail, scrapedurl, scrapedtitle in matches: url = urlparse.urljoin(host, scrapedurl) filter_thumb = scrapedthumbnail.replace( "https://image.tmdb.org/t/p/w200_and_h300_bestv2", "") filter_list = {"poster_path": filter_thumb} filter_list = filter_list.items() itemlist.append( Item(channel=item.channel, action=action, title=scrapedtitle, url=url, extra="media", thumbnail=scrapedthumbnail, contentTitle=scrapedtitle, fulltitle=scrapedtitle, text_color=color2, contentType="movie", infoLabels={'filtro': filter_list})) else: patron = '<div class="audio-info">(.*?)<div (class="quality.*?)src="([^"]+)".*?href="([^"]+)">([^<]+)</a>' matches = scrapertools.find_multiple_matches(match, patron) for idiomas, calidad, scrapedthumbnail, scrapedurl, scrapedtitle in matches: calidad = scrapertools.find_single_match( calidad, '<div class="quality-info".*?>([^<]+)</div>') if calidad: calidad = calidad.capitalize().replace("Hd", "HD") audios = [] if "medium-es" in idiomas: audios.append('CAST') if "medium-vs" in idiomas: audios.append('VOSE') if "medium-la" in idiomas: audios.append('LAT') if "medium-en" in idiomas or 'medium-"' in idiomas: audios.append('VO') title = "%s [%s]" % (scrapedtitle, "/".join(audios)) if calidad: title += " (%s)" % calidad url = urlparse.urljoin(host, scrapedurl) filter_thumb = scrapedthumbnail.replace( "https://image.tmdb.org/t/p/w200_and_h300_bestv2", "") filter_list = {"poster_path": filter_thumb} filter_list = filter_list.items() itemlist.append( Item(channel=item.channel, action=action, title=title, url=url, extra="media", thumbnail=scrapedthumbnail, contentTitle=scrapedtitle, fulltitle=scrapedtitle, text_color=color2, contentType="movie", quality=calidad, language=audios, infoLabels={'filtro': filter_list})) next_page = scrapertools.find_single_match( data, 'href="([^"]+)"[^>]+>Siguiente') tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) if next_page != "" and item.title != "": itemlist.append( Item(channel=item.channel, action="peliculas", title=">> Siguiente", url=next_page, thumbnail=item.thumbnail, extra=item.extra, text_color=color3)) if not config.get_setting("last_page", item.channel) and config.is_xbmc(): itemlist.append( Item(channel=item.channel, action="select_page", title="Ir a página...", url=next_page, thumbnail=item.thumbnail, text_color=color5)) return itemlist
def show_infobox(info_dict): logger.info() from textwrap import wrap box_items_kodi = { 'r_up_corner': u'\u250c', 'l_up_corner': u'\u2510', 'center': u'\u2502', 'r_center': u'\u251c', 'l_center': u'\u2524', 'fill': u'\u2500', 'r_dn_corner': u'\u2514', 'l_dn_corner': u'\u2518', } box_items = { 'r_up_corner': '+', 'l_up_corner': '+', 'center': '|', 'r_center': '+', 'l_center': '+', 'fill': '-', 'r_dn_corner': '+', 'l_dn_corner': '+', } width = 60 version = '%s: %s' % (config.get_localized_string(20000), __version) if config.is_xbmc(): box = box_items_kodi else: box = box_items logger.info('%s%s%s' % (box['r_up_corner'], box['fill'] * width, box['l_up_corner'])) logger.info('%s%s%s' % (box['center'], version.center(width), box['center'])) logger.info('%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center'])) count = 0 for key, value in info_dict: count += 1 text = '%s: %s' % (key, value) if len(text) > (width - 2): text = wrap(text, width) else: text = text.ljust(width, ' ') if isinstance(text, list): for line in text: if len(line) < width: line = line.ljust(width, ' ') logger.info('%s%s%s' % (box['center'], line, box['center'])) else: logger.info('%s%s%s' % (box['center'], text, box['center'])) if count < len(info_dict): logger.info( '%s%s%s' % (box['r_center'], box['fill'] * width, box['l_center'])) else: logger.info( '%s%s%s' % (box['r_dn_corner'], box['fill'] * width, box['l_dn_corner'])) return
def add_tvshow(item, channel=None): """ Guarda contenido en la libreria de series. Este contenido puede ser uno de estos dos: - La serie con todos los capitulos incluidos en la lista episodelist. - Un solo capitulo descargado previamente en local. Para añadir episodios descargados en local, el item debe tener exclusivamente: - contentSerieName (o show): Titulo de la serie - contentTitle: titulo del episodio para extraer season_and_episode ("1x01 Piloto") - title: titulo a mostrar junto al listado de enlaces -findvideos- ("Reproducir video local") - infoLabels["tmdb_id"] o infoLabels["imdb_id"] - contentType != "movie" - channel = "downloads" - url : ruta local al video @type item: item @param item: item que representa la serie a guardar @type channel: modulo @param channel: canal desde el que se guardara la serie. Por defecto se importara item.from_channel o item.channel """ logger.info("show=#" + item.show + "#") if item.channel == "downloads": itemlist = [item.clone()] else: # Esta marca es porque el item tiene algo más aparte en el atributo "extra" item.action = item.extra if isinstance(item.extra, str) and "###" in item.extra: item.action = item.extra.split("###")[0] item.extra = item.extra.split("###")[1] if item.from_action: item.__dict__["action"] = item.__dict__.pop("from_action") if item.from_channel: item.__dict__["channel"] = item.__dict__.pop("from_channel") if not channel: try: channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel]) except ImportError: exec("import channels." + item.channel + " as channel") #Para desambiguar títulos, se provoca que TMDB pregunte por el título realmente deseado #El usuario puede seleccionar el título entre los ofrecidos en la primera pantalla #o puede cancelar e introducir un nuevo título en la segunda pantalla #Si lo hace en "Introducir otro nombre", TMDB buscará automáticamente el nuevo título #Si lo hace en "Completar Información", cambia parcialmente al nuevo título, pero no busca en TMDB. Hay que hacerlo #Si se cancela la segunda pantalla, la variable "scraper_return" estará en False. El usuario no quiere seguir item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels #if item.tmdb_stat: # del item.tmdb_stat #Limpiamos el status para que no se grabe en la Videoteca # Obtiene el listado de episodios itemlist = getattr(channel, item.action)(item) global magnet_caching magnet_caching = False insertados, sobreescritos, fallidos, path = save_tvshow(item, itemlist) if not insertados and not sobreescritos and not fallidos: platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60067)) logger.error("La serie %s no se ha podido añadir a la videoteca. No se ha podido obtener ningun episodio" % item.show) elif fallidos == -1: platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60068)) logger.error("La serie %s no se ha podido añadir a la videoteca" % item.show) elif fallidos > 0: platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60069)) logger.error("No se han podido añadir %s episodios de la serie %s a la videoteca" % (fallidos, item.show)) else: platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60070)) logger.info("Se han añadido %s episodios de la serie %s a la videoteca" % (insertados, item.show)) if config.is_xbmc(): if config.get_setting("sync_trakt_new_tvshow", "videolibrary"): import xbmc from platformcode import xbmc_videolibrary if config.get_setting("sync_trakt_new_tvshow_wait", "videolibrary"): # Comprobar que no se esta buscando contenido en la videoteca de Kodi while xbmc.getCondVisibility('Library.IsScanningVideo()'): xbmc.sleep(1000) # Se lanza la sincronizacion para la videoteca de Kodi xbmc_videolibrary.sync_trakt_kodi() # Se lanza la sincronización para la videoteca del addon xbmc_videolibrary.sync_trakt_addon(path)
def getmainlist(view="thumb_"): logger.info() itemlist = list() # Añade los canales que forman el menú principal itemlist.append( Item(title=config.get_localized_string(30130), channel="news", action="mainlist", thumbnail=get_thumb("news.png", view), category=config.get_localized_string(30119), viewmode="thumbnails", context=[{ "title": config.get_localized_string(70285), "channel": "news", "action": "news_setting" }])) itemlist.append( Item(title=config.get_localized_string(30118), channel="channelselector", action="getchanneltypes", thumbnail=get_thumb("channels.png", view), view=view, category=config.get_localized_string(30119), viewmode="thumbnails")) itemlist.append( Item(title="Lista de deseos", channel="info_popup", action="mainlist", thumbnail=get_thumb("wishlist.png", view), category="wishlist", viewmode="thumbnails", context=[{ "title": "Configurar Lista de deseos", "channel": "info_popup", "action": "show_settings" }])) itemlist.append( Item(title=config.get_localized_string(70527), channel="alfavorites", action="mainlist", thumbnail=get_thumb("mylink.png", view), view=view, category=config.get_localized_string(70527), viewmode="thumbnails")) itemlist.append( Item(title=config.get_localized_string(30103), channel="search", action="mainlist", thumbnail=get_thumb("search.png", view), category=config.get_localized_string(30119), viewmode="list", context=[{ "title": config.get_localized_string(70286), "channel": "search", "action": "opciones", "goto": True }])) itemlist.append( Item(title=config.get_localized_string(30102), channel="favorites", action="mainlist", thumbnail=get_thumb("favorites.png", view), category=config.get_localized_string(30102), viewmode="thumbnails")) if config.get_videolibrary_support(): itemlist.append( Item(title=config.get_localized_string(30131), channel="videolibrary", action="mainlist", thumbnail=get_thumb("videolibrary.png", view), category=config.get_localized_string(30119), viewmode="thumbnails", context=[{ "title": config.get_localized_string(70287), "channel": "videolibrary", "action": "channel_config" }])) itemlist.append( Item(title=config.get_localized_string(30101), channel="downloads", action="mainlist", thumbnail=get_thumb("downloads.png", view), viewmode="list", context=[{ "title": config.get_localized_string(70288), "channel": "setting", "config": "downloads", "action": "channel_config" }])) thumb_setting = "setting_%s.png" % 0 # config.get_setting("plugin_updates_available") itemlist.append( Item(title=config.get_localized_string(30100), channel="setting", action="mainlist", thumbnail=get_thumb(thumb_setting, view), category=config.get_localized_string(30100), viewmode="list")) if config.is_xbmc(): itemlist.append( Item(title=config.get_localized_string(70761), channel="setting", action="report_menu", thumbnail=get_thumb("error.png", view), category=config.get_localized_string(30104), viewmode="list")) itemlist.append( Item(title=config.get_localized_string(30104) + " (" + config.get_localized_string(20000) + " " + config.get_addon_version(with_fix=False, from_xml=True) + ")", channel="help", action="mainlist", thumbnail=os.path.join(config.get_runtime_path(), "resources", 'Screenshot.jpg'), category=config.get_localized_string(30104), viewmode="list")) try: versiones = config.get_versions_from_repo() except: versiones = {} logger.error(traceback.format_exc()) if versiones and config.get_addon_version(with_fix=False, from_xml=True) != versiones.get( 'plugin.video.alfa', ''): itemlist.append( Item( title= "[COLOR hotpink][B]Actualizar a versión[/B][/COLOR] [COLOR gold][B]%s[/B][/COLOR] (versión instalada: %s)" % (versiones['plugin.video.alfa'], config.get_addon_version(with_fix=False, from_xml=True)), channel="channelselector", action="install_alfa", thumbnail=os.path.join(config.get_runtime_path(), "resources", 'Screenshot.jpg'), category=config.get_localized_string(30104), viewmode="list")) from lib import generictools browser, res = generictools.call_browser('', lookup=True) if not browser: action = '' itemlist.append( Item(channel="setting", action=action, url='https://alfa-addon.com/foros/tutoriales.11/', title=config.get_localized_string(70758) + " [COLOR gold](" + config.get_localized_string(70759) + ": Chrome, Firefox, Opera)[/COLOR]:", thumbnail=get_thumb("help.png", view), unify=False, folder=False, category=config.get_localized_string(30104), viewmode="list")) else: action = 'call_browser' itemlist.append( Item(channel="setting", action=action, url='https://alfa-addon.com/foros/tutoriales.11/', title=config.get_localized_string(70758) + (" [COLOR limegreen]" + config.get_localized_string(70760) + "[/COLOR]") % browser, thumbnail=get_thumb("help.png", view), unify=False, folder=False, category=config.get_localized_string(30104), viewmode="list")) itemlist.append( Item( channel="setting", action=action, url= 'https://alfa-addon.com/threads/si-tienes-android-10-y-kodi-19-vas-a-tener-problemas-con-los-torrents.4211/', title= "- [COLOR yellow]Si tienes Android 10+ y Kodi 19+ vas a tener problemas con los torrents[/COLOR] " + "https://alfa-addon.com/threads/si-tienes-android-10-y-kodi-19-vas-a-tener-problemas-con-los-torrents.4211/", thumbnail=get_thumb("help.png", view), unify=False, folder=False, category=config.get_localized_string(30104), viewmode="list")) itemlist.append( Item( channel="setting", action=action, url= 'https://alfa-addon.com/threads/torrest-el-gestor-de-torrents-definitivo.4085/', title= "- [COLOR yellow]Torrest: el gestor de torrents definitivo[/COLOR] " + "https://alfa-addon.com/threads/torrest-el-gestor-de-torrents-definitivo.4085/", thumbnail=get_thumb("help.png", view), unify=False, folder=False, category=config.get_localized_string(30104), viewmode="list")) return itemlist
def start(itemlist, item): ''' Metodo principal desde donde se reproduce automaticamente los enlaces - En caso la opcion de personalizar activa utilizara las opciones definidas por el usuario. - En caso contrario intentara reproducir cualquier enlace que cuente con el idioma preferido. :param itemlist: list (lista de items listos para reproducir, o sea con action='play') :param item: item (el item principal del canal) :return: intenta autoreproducir, en caso de fallar devuelve el itemlist que recibio en un principio ''' logger.info() if not config.is_xbmc(): #platformtools.dialog_notification('AutoPlay ERROR', 'Sólo disponible para XBMC/Kodi') return itemlist global autoplay_node if not autoplay_node: # Obtiene el nodo AUTOPLAY desde el json autoplay_node = jsontools.get_node_from_file('autoplay', 'AUTOPLAY') if not item.channel in autoplay_node: return itemlist # Agrega servidores y calidades que no estaban listados a autoplay_node new_options = check_value(item.channel, itemlist) # Obtiene el nodo del canal desde autoplay_node channel_node = autoplay_node.get(item.channel, {}) # Obtiene los ajustes des autoplay para este canal settings_node = channel_node.get('settings', {}) if settings_node['active']: url_list_valid = [] autoplay_list = [] autoplay_b = [] favorite_servers = [] favorite_quality = [] # Guarda el valor actual de "Accion y Player Mode" en preferencias user_config_setting_action = config.get_setting("default_action") user_config_setting_player = config.get_setting("player_mode") # Habilita la accion "Ver en calidad alta" (si el servidor devuelve más de una calidad p.e. gdrive) if user_config_setting_action != 2: config.set_setting("default_action", 2) if user_config_setting_player != 0: config.set_setting("player_mode", 0) # Informa que AutoPlay esta activo #platformtools.dialog_notification('AutoPlay Activo', '', sound=False) # Prioridades a la hora de ordenar itemlist: # 0: Servidores y calidades # 1: Calidades y servidores # 2: Solo servidores # 3: Solo calidades # 4: No ordenar if settings_node['custom_servers'] and settings_node['custom_quality']: priority = settings_node[ 'priority'] # 0: Servidores y calidades o 1: Calidades y servidores elif settings_node['custom_servers']: priority = 2 # Solo servidores elif settings_node['custom_quality']: priority = 3 # Solo calidades else: priority = 4 # No ordenar # Obtiene las listas servidores, calidades disponibles desde el nodo del json de AutoPlay server_list = channel_node.get('servers', []) quality_list = channel_node.get('quality', []) # Si no se definen calidades la se asigna default como calidad unica if len(quality_list) == 0: quality_list = ['default'] # Se guardan los textos de cada servidor y calidad en listas p.e. favorite_servers = ['openload', # 'streamcloud'] for num in range(1, 4): favorite_servers.append( channel_node['servers'][settings_node['server_%s' % num]]) favorite_quality.append( channel_node['quality'][settings_node['quality_%s' % num]]) # Se filtran los enlaces de itemlist y que se correspondan con los valores de autoplay for item in itemlist: autoplay_elem = dict() b_dict = dict() # Comprobamos q se trata de un item de video if 'server' not in item: continue # Agrega la opcion configurar AutoPlay al menu contextual if 'context' not in item: item.context = list() if not filter(lambda x: x['action'] == 'autoplay_config', context): item.context.append({ "title": "Configurar AutoPlay", "action": "autoplay_config", "channel": "autoplay", "from_channel": item.channel }) # Si no tiene calidad definida le asigna calidad 'default' if item.quality == '': item.quality = 'default' # Se crea la lista para configuracion personalizada if priority < 2: # 0: Servidores y calidades o 1: Calidades y servidores # si el servidor y la calidad no se encuentran en las listas de favoritos o la url esta repetida, # descartamos el item if item.server not in favorite_servers or item.quality not in favorite_quality \ or item.url in url_list_valid: item.type_b = True b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_server"] = favorite_servers.index( item.server) autoplay_elem["indice_quality"] = favorite_quality.index( item.quality) elif priority == 2: # Solo servidores # si el servidor no se encuentra en la lista de favoritos o la url esta repetida, # descartamos el item if item.server not in favorite_servers or item.url in url_list_valid: item.type_b = True b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_server"] = favorite_servers.index( item.server) elif priority == 3: # Solo calidades # si la calidad no se encuentra en la lista de favoritos o la url esta repetida, # descartamos el item if item.quality not in favorite_quality or item.url in url_list_valid: item.type_b = True b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_quality"] = favorite_quality.index( item.quality) else: # No ordenar # si la url esta repetida, descartamos el item if item.url in url_list_valid: continue # Si el item llega hasta aqui lo añadimos al listado de urls validas y a autoplay_list url_list_valid.append(item.url) item.plan_b = True autoplay_elem['videoitem'] = item # autoplay_elem['server'] = item.server # autoplay_elem['quality'] = item.quality autoplay_list.append(autoplay_elem) # Ordenamos segun la prioridad if priority == 0: # Servidores y calidades autoplay_list.sort(key=lambda orden: (orden['indice_server'], orden['indice_quality'])) elif priority == 1: # Calidades y servidores autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server'])) elif priority == 2: # Solo servidores autoplay_list.sort(key=lambda orden: orden['indice_server']) elif priority == 3: # Solo calidades autoplay_list.sort(key=lambda orden: orden['indice_quality']) # Se prepara el plan b, en caso de estar activo se agregan los elementos no favoritos al final plan_b = settings_node['plan_b'] ready = False text_b = '' if plan_b: autoplay_list.extend(autoplay_b) # Si hay elementos en la lista de autoplay se intenta reproducir cada elemento, hasta encontrar uno # funcional o fallen todos if autoplay_list or (plan_b and autoplay_b): played = False max_intentos = 5 max_intentos_servers = {} # Si se esta reproduciendo algo detiene la reproduccion if platformtools.is_playing(): platformtools.stop_video() for autoplay_elem in autoplay_list: play_item = Item # Si no es un elemento favorito si agrega el texto plan b if autoplay_elem['videoitem'].type_b: text_b = '(Plan B)' if not platformtools.is_playing() and not played: videoitem = autoplay_elem['videoitem'] logger.debug('videoitem %s' % videoitem) if videoitem.server not in max_intentos_servers: max_intentos_servers[videoitem.server] = max_intentos # Si se han alcanzado el numero maximo de intentos de este servidor saltamos al siguiente if max_intentos_servers[videoitem.server] == 0: continue lang = " " if hasattr(videoitem, 'language') and videoitem.language != "": lang = " '%s' " % videoitem.language platformtools.dialog_notification( "AutoPlay %s" % text_b, "%s%s%s" % (videoitem.server.upper(), lang, videoitem.quality.upper()), sound=False) # TODO videoitem.server es el id del server, pero podria no ser el nombre!!! # Intenta reproducir los enlaces # Si el canal tiene metodo play propio lo utiliza channel = __import__('channels.%s' % item.channel, None, None, ["channels.%s" % item.channel]) if hasattr(channel, 'play'): resolved_item = getattr(channel, 'play')(videoitem) if len(resolved_item) > 0: if isinstance(resolved_item[0], list): videoitem.video_urls = resolved_item else: videoitem = resolved_item[0] # Si no directamente reproduce y marca como visto # Verifica si el item viene de la videoteca try: if item.contentChannel == 'videolibrary': # Marca como visto from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_auto_as_watched(item) # Rellena el video con los datos del item principal y reproduce play_item = item.clone(url=videoitem) platformtools.play_video(play_item.url, autoplay=True) else: # Si no viene de la videoteca solo reproduce platformtools.play_video(videoitem, autoplay=True) except: pass try: if platformtools.is_playing(): played = True break except: logger.debug(str(len(autoplay_list))) # Si hemos llegado hasta aqui es por q no se ha podido reproducir max_intentos_servers[videoitem.server] -= 1 # Si se han alcanzado el numero maximo de intentos de este servidor # preguntar si queremos seguir probando o lo ignoramos if max_intentos_servers[videoitem.server] == 0: text = "Parece que los enlaces de %s no estan funcionando." % videoitem.server.upper( ) if not platformtools.dialog_yesno( "AutoPlay", text, "¿Desea ignorar todos los enlaces de este servidor?" ): max_intentos_servers[ videoitem.server] = max_intentos # Si no quedan elementos en la lista se informa if autoplay_elem == autoplay_list[-1]: platformtools.dialog_notification( 'AutoPlay', 'No hubo enlaces funcionales') else: platformtools.dialog_notification('AutoPlay No Fue Posible', 'No Hubo Coincidencias') if new_options: platformtools.dialog_notification( "AutoPlay", "Nueva Calidad/Servidor disponible en la " "configuracion", sound=False) # Restaura si es necesario el valor previo de "Accion y Player Mode" en preferencias if user_config_setting_action != 2: config.set_setting("default_action", user_config_setting_action) if user_config_setting_player != 0: config.set_setting("player_mode", user_config_setting_player) # devuelve la lista de enlaces para la eleccion manual return itemlist
def init(channel, list_servers, list_quality): ''' Comprueba la existencia de canal en el archivo de configuracion de Autoplay y si no existe lo añade. Es necesario llamar a esta funcion al entrar a cualquier canal que incluya la funcion Autoplay. :param channel: (str) id del canal :param list_servers: (list) lista inicial de servidores validos para el canal. No es necesario incluirlos todos, ya que la lista de servidores validos se ira actualizando dinamicamente. :param list_quality: (list) lista inicial de calidades validas para el canal. No es necesario incluirlas todas, ya que la lista de calidades validas se ira actualizando dinamicamente. :return: (bool) True si la inicializacion ha sido correcta. ''' logger.info() change = False result = True if not config.is_xbmc(): # platformtools.dialog_notification('AutoPlay ERROR', 'Sólo disponible para XBMC/Kodi') result = False else: autoplay_path = os.path.join(config.get_data_path(), "settings_channels", 'autoplay_data.json') if os.path.exists(autoplay_path): autoplay_node = jsontools.get_node_from_file( 'autoplay', "AUTOPLAY") else: change = True autoplay_node = {"AUTOPLAY": {}} if channel not in autoplay_node: change = True # Se comprueba que no haya calidades ni servidores duplicados if 'default' not in list_quality: list_quality.append('default') list_servers = list(set(list_servers)) list_quality = list(set(list_quality)) # Creamos el nodo del canal y lo añadimos channel_node = { "servers": list_servers, "quality": list_quality, "settings": { "active": False, "custom_servers": False, "custom_quality": False, "priority": 0 } } for n in range(1, 4): s = c = 0 if len(list_servers) >= n: s = n - 1 if len(list_quality) >= n: c = n - 1 channel_node["settings"]["server_%s" % n] = s channel_node["settings"]["quality_%s" % n] = c autoplay_node[channel] = channel_node if change: result, json_data = jsontools.update_node(autoplay_node, 'autoplay', 'AUTOPLAY') if not result: heading = "Error al iniciar AutoPlay" msj = "Consulte su log para obtener mas información." icon = 1 platformtools.dialog_notification(heading, msj, icon, sound=False) return result
def delete(item): def delete_all(_item): for file in filetools.listdir(_item.path): if file.endswith(".strm") or file.endswith(".nfo") or file.endswith(".json")or file.endswith(".torrent"): filetools.remove(filetools.join(_item.path, file)) if _item.contentType == 'movie': heading = config.get_localized_string(70084) else: heading = config.get_localized_string(70085) if config.is_xbmc() and config.get_setting("videolibrary_kodi"): from platformcode import xbmc_videolibrary if _item.local_episodes_path: platformtools.dialog_ok(heading, config.get_localized_string(80047) % _item.infoLabels['title']) path_list = [_item.extra] xbmc_videolibrary.clean(path_list) raiz, carpeta_serie, ficheros = next(filetools.walk(_item.path)) if ficheros == []: filetools.rmdir(_item.path) elif platformtools.dialog_yesno(heading, config.get_localized_string(70081) % filetools.basename(_item.path)): filetools.rmdirtree(_item.path) logger.info("All links removed") xbmc.sleep(1000) platformtools.itemlist_refresh() # logger.debug(item.tostring('\n')) if item.contentType == 'movie': heading = config.get_localized_string(70084) else: heading = config.get_localized_string(70085) if item.multichannel: # Get channel list if item.dead == '': opciones = [] channels = [] for k in list(item.library_urls.keys()): if k != "downloads": opciones.append(config.get_localized_string(70086) % k.capitalize()) channels.append(k) opciones.insert(0, heading) index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index == 0: # Selected Delete movie / series delete_all(item) return elif index > 0: # Selected Delete channel X canal = opciones[index].replace(config.get_localized_string(70079), "").lower() channels.remove(canal) else: return else: canal = item.dead num_enlaces = 0 path_list = [] for fd in filetools.listdir(item.path): if fd.endswith(canal + '].json') or scrapertools.find_single_match(fd, r'%s]_\d+.torrent' % canal): if filetools.remove(filetools.join(item.path, fd)): num_enlaces += 1 # Remove strm and nfo if no other channel episode = fd.replace(' [' + canal + '].json', '') found_ch = False for ch in channels: if filetools.exists(filetools.join(item.path, episode + ' [' + ch + '].json')): found_ch = True break if found_ch == False: filetools.remove(filetools.join(item.path, episode + '.nfo')) strm_path = filetools.join(item.path, episode + '.strm') # if it is a local episode, do not delete the strm if 'plugin://plugin.video.kod/?' in filetools.read(strm_path): filetools.remove(strm_path) path_list.append(filetools.join(item.extra, episode + '.strm')) if config.is_xbmc() and config.get_setting("videolibrary_kodi") and path_list: from platformcode import xbmc_videolibrary xbmc_videolibrary.clean(path_list) if num_enlaces > 0: # Update .nfo head_nfo, item_nfo = videolibrarytools.read_nfo(item.nfo) del item_nfo.library_urls[canal] if item_nfo.emergency_urls and item_nfo.emergency_urls.get(canal, False): del item_nfo.emergency_urls[canal] filetools.write(item.nfo, head_nfo + item_nfo.tojson()) msg_txt = config.get_localized_string(70087) % (num_enlaces, canal) logger.info(msg_txt) platformtools.dialog_notification(heading, msg_txt) platformtools.itemlist_refresh() else: if platformtools.dialog_yesno(heading, config.get_localized_string(70088) % item.infoLabels['title']): delete_all(item)
def downloadfile(url, nombrefichero, headers=None, silent=False, continuar=False, resumir=True, header=''): logger.info("url= " + url) logger.info("filename= " + nombrefichero) if headers is None: headers = [] if not header: header = "plugin" progreso = None if config.is_xbmc() and nombrefichero.startswith("special://"): import xbmc nombrefichero = xbmc.translatePath(nombrefichero) try: # If it is not XBMC, always "Silent" from platformcode import platformtools # before # f=open(nombrefichero,"wb") try: import xbmc nombrefichero = xbmc.makeLegalFilename(nombrefichero) except: pass logger.info("filename= " + nombrefichero) # The file exists and you want to continue if filetools.exists(nombrefichero) and continuar: f = filetools.file_open(nombrefichero, 'r+b', vfs=VFS) if resumir: exist_size = filetools.getsize(nombrefichero) logger.info("the file exists, size= %d" % exist_size) grabado = exist_size f.seek(exist_size) else: exist_size = 0 grabado = 0 # the file already exists and you don't want to continue, it aborts elif filetools.exists(nombrefichero) and not continuar: logger.info("the file exists, it does not download again") return -3 # the file does not exist else: exist_size = 0 logger.info("the file does not exist") f = filetools.file_open(nombrefichero, 'wb', vfs=VFS) grabado = 0 # Create the progress dialog if not silent: progreso = platformtools.dialog_progress(header, "Downloading..." + '\n' + url + '\n' + nombrefichero) # If the platform does not return a valid dialog box, it assumes silent mode if progreso is None: silent = True if "|" in url: additional_headers = url.split("|")[1] if "&" in additional_headers: additional_headers = additional_headers.split("&") else: additional_headers = [additional_headers] for additional_header in additional_headers: logger.info("additional_header: " + additional_header) name = re.findall("(.*?)=.*?", additional_header)[0] value = urllib.parse.unquote_plus(re.findall(".*?=(.*?)$", additional_header)[0]) headers.append([name, value]) url = url.split("|")[0] logger.info("url=" + url) # Socket timeout at 60 seconds socket.setdefaulttimeout(60) h = urllib.request.HTTPHandler(debuglevel=0) request = urllib.request.Request(url) for header in headers: logger.info("Header= " + header[0] + ": " + header[1]) request.add_header(header[0], header[1]) if exist_size > 0: request.add_header('Range', 'bytes= %d-' % (exist_size,)) opener = urllib.request.build_opener(h) urllib.request.install_opener(opener) try: connexion = opener.open(request) except urllib.error.HTTPError as e: logger.error("error %d (%s) opening url %s" % (e.code, e.msg, url)) f.close() if not silent: progreso.close() # Error 416 is that the requested range is greater than the file => is that it is already complete if e.code == 416: return 0 else: return -2 try: totalfichero = int(connexion.headers["Content-Length"]) except ValueError: totalfichero = 1 if exist_size > 0: totalfichero = totalfichero + exist_size logger.info("Content-Length= %s" % totalfichero) blocksize = 100 * 1024 bloqueleido = connexion.read(blocksize) logger.info("Starting downloading the file, blocked= %s" % len(bloqueleido)) maxreintentos = 10 while len(bloqueleido) > 0: try: # Write the block read f.write(bloqueleido) grabado += len(bloqueleido) percent = int(float(grabado) * 100 / float(totalfichero)) totalmb = float(float(totalfichero) / (1024 * 1024)) descargadosmb = float(float(grabado) / (1024 * 1024)) # Read the next block, retrying not to stop everything at the first timeout reintentos = 0 while reintentos <= maxreintentos: try: before = time.time() bloqueleido = connexion.read(blocksize) after = time.time() if (after - before) > 0: velocidad = old_div(len(bloqueleido), (after - before)) falta = totalfichero - grabado if velocidad > 0: tiempofalta = old_div(falta, velocidad) else: tiempofalta = 0 # logger.info(sec_to_hms(tiempofalta)) if not silent: progreso.update(percent, "%.2fMB/%.2fMB (%d%%) %.2f Kb/s %s" % (descargadosmb, totalmb, percent, old_div(velocidad, 1024), sec_to_hms(tiempofalta))) break except: reintentos += 1 logger.info("ERROR in block download, retry %d" % reintentos) import traceback logger.error(traceback.print_exc()) # The user cancels the download try: if progreso.iscanceled(): logger.info("Download of file canceled") f.close() progreso.close() return -1 except: pass # There was an error in the download if reintentos > maxreintentos: logger.info("ERROR in the file download") f.close() if not silent: progreso.close() return -2 except: import traceback logger.error(traceback.print_exc()) f.close() if not silent: progreso.close() # platformtools.dialog_ok('Error al descargar' , 'Se ha producido un error' , 'al descargar el archivo') return -2 except: if url.startswith("rtmp"): error = downloadfileRTMP(url, nombrefichero, silent) if error and not silent: from platformcode import platformtools platformtools.dialog_ok("You cannot download that video "," RTMP downloads not yet supported") else: import traceback from pprint import pprint exc_type, exc_value, exc_tb = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_tb) for line in lines: line_splits = line.split("\n") for line_split in line_splits: logger.error(line_split) try: f.close() except: pass if not silent: try: progreso.close() except: pass logger.info("End of file download")
message = template % (type(ex).__name__, ex.args) logger.error(message) except Exception, 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) 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(): #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()) return insertados_total > 0 def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today()
def _unshorten_linkbucks(self, uri): ''' (Attempt) to decode linkbucks content. HEAVILY based on the OSS jDownloader codebase. This has necessidated a license change. ''' if config.is_xbmc(): import xbmc r = httptools.downloadpage(uri, timeout=self._timeout) firstGet = time.time() baseloc = r.url if "/notfound/" in r.url or \ "(>Link Not Found<|>The link may have been deleted by the owner|To access the content, you must complete a quick survey\.)" in r.data: return uri, 'Error: Link not found or requires a survey!' link = None content = r.data regexes = [ r"<div id=\"lb_header\">.*?/a>.*?<a.*?href=\"(.*?)\".*?class=\"lb", r"AdBriteInit\(\"(.*?)\"\)", r"Linkbucks\.TargetUrl = '(.*?)';", r"Lbjs\.TargetUrl = '(http://[^<>\"]*?)'", r"src=\"http://static\.linkbucks\.com/tmpl/mint/img/lb\.gif\" /></a>.*?<a href=\"(.*?)\"", r"id=\"content\" src=\"([^\"]*)", ] for regex in regexes: if self.inValidate(link): link = find_in_text(regex, content) if self.inValidate(link): match = find_in_text(r"noresize=\"[0-9+]\" src=\"(http.*?)\"", content) if match: link = find_in_text(r"\"frame2\" frameborder.*?src=\"(.*?)\"", content) if self.inValidate(link): scripts = re.findall( "(<script type=\"text/javascript\">[^<]+</script>)", content) if not scripts: return uri, "No script bodies found?" js = False for script in scripts: # cleanup script = re.sub(r"[\r\n\s]+\/\/\s*[^\r\n]+", "", script) if re.search( r"\s*var\s*f\s*=\s*window\['init'\s*\+\s*'Lb'\s*\+\s*'js'\s*\+\s*''\];[\r\n\s]+", script): js = script if not js: return uri, "Could not find correct script?" token = find_in_text(r"Token\s*:\s*'([a-f0-9]{40})'", js) if not token: token = find_in_text(r"\?t=([a-f0-9]{40})", js) assert token authKeyMatchStr = r"A(?:'\s*\+\s*')?u(?:'\s*\+\s*')?t(?:'\s*\+\s*')?h(?:'\s*\+\s*')?K(?:'\s*\+\s*')?e(?:'\s*\+\s*')?y" l1 = find_in_text( r"\s*params\['" + authKeyMatchStr + r"'\]\s*=\s*(\d+?);", js) l2 = find_in_text( r"\s*params\['" + authKeyMatchStr + r"'\]\s*=\s?params\['" + authKeyMatchStr + r"'\]\s*\+\s*(\d+?);", js) if any([not l1, not l2, not token]): return uri, "Missing required tokens?" authkey = int(l1) + int(l2) p1_url = urljoin(baseloc, "/director/?t={tok}".format(tok=token)) r2 = httptools.downloadpage(p1_url, timeout=self._timeout) p1_url = urljoin( baseloc, "/scripts/jquery.js?r={tok}&{key}".format(tok=token, key=l1)) r2 = httptools.downloadpage(p1_url, timeout=self._timeout) time_left = 5.033 - (time.time() - firstGet) if config.is_xbmc(): xbmc.sleep(max(time_left, 0) * 1000) else: time.sleep(5 * 1000) p3_url = urljoin( baseloc, "/intermission/loadTargetUrl?t={tok}&aK={key}&a_b=false". format(tok=token, key=str(authkey))) r3 = httptools.downloadpage(p3_url, timeout=self._timeout) resp_json = json.loads(r3.data) if "Url" in resp_json: return resp_json['Url'], r3.code return "Wat", "wat"
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 novedades(item): logger.info() global list_newest threads = [] list_newest = [] start_time = time.time() mode = item.mode if mode == '': mode = 'normal' if mode == 'get_cached': if os.path.exists(menu_cache_path): return get_from_cache(item) multithread = config.get_setting("multithread", "news") logger.info("multithread= " + str(multithread)) if not multithread: if platformtools.dialog_yesno(config.get_localized_string(60515), config.get_localized_string(60516), config.get_localized_string(60517), config.get_localized_string(60518)): if config.set_setting("multithread", True, "news"): multithread = True if mode == 'normal': progreso = platformtools.dialog_progress( item.category, config.get_localized_string(60519)) list_canales, any_active = get_channels_list() if config.is_xbmc(): from channels import side_menu if mode == 'silent' and any_active and len( list_canales[item.extra]) > 0: side_menu.set_menu_settings(item) aux_list = [] for canal in list_canales[item.extra]: if len(aux_list) < 2: aux_list.append(canal) list_canales[item.extra] = aux_list if mode == 'set_cache': list_canales[item.extra] = list_canales[item.extra][2:] if any_active and len(list_canales[item.extra]) > 0: import math # fix float porque la division se hace mal en python 2.x number_of_channels = float(100) / len(list_canales[item.extra]) for index, channel in enumerate(list_canales[item.extra]): channel_id, channel_title = channel percentage = int(math.ceil((index + 1) * number_of_channels)) # if progreso.iscanceled(): # progreso.close() # logger.info("Búsqueda cancelada") # return itemlist # Modo Multi Thread if multithread: t = Thread(target=get_newest, args=[channel_id, item.extra], name=channel_title) t.start() threads.append(t) if mode == 'normal': progreso.update( percentage, "", config.get_localized_string(60520) % channel_title) # Modo single Thread else: if mode == 'normal': logger.info("Obteniendo novedades de channel_id=" + channel_id) progreso.update( percentage, "", config.get_localized_string(60520) % channel_title) get_newest(channel_id, item.extra) # Modo Multi Thread: esperar q todos los hilos terminen if multithread: pendent = [a for a in threads if a.isAlive()] t = float(100) / len(pendent) while pendent: index = (len(threads) - len(pendent)) + 1 percentage = int(math.ceil(index * t)) list_pendent_names = [a.getName() for a in pendent] if mode == 'normal': mensaje = config.get_localized_string(30994) % ( ", ".join(list_pendent_names)) progreso.update( percentage, config.get_localized_string(60521) % (len(threads) - len(pendent), len(threads)), mensaje) logger.debug(mensaje) if progreso.iscanceled(): logger.info("Busqueda de novedades cancelada") break time.sleep(0.5) pendent = [a for a in threads if a.isAlive()] if mode == 'normal': mensaje = config.get_localized_string(60522) % ( len(list_newest), time.time() - start_time) progreso.update(100, mensaje, " ", " ") logger.info(mensaje) start_time = time.time() # logger.debug(start_time) result_mode = config.get_setting("result_mode", "news") if mode != 'normal': result_mode = 0 if result_mode == 0: # Agrupados por contenido ret = group_by_content(list_newest) elif result_mode == 1: # Agrupados por canales ret = group_by_channel(list_newest) else: # Sin agrupar ret = no_group(list_newest) while time.time() - start_time < 2: # mostrar cuadro de progreso con el tiempo empleado durante almenos 2 segundos time.sleep(0.5) if mode == 'normal': progreso.close() if mode == 'silent': set_cache(item) item.mode = 'set_cache' ret = add_menu_items(item, ret) if mode != 'set_cache': return ret else: if mode != 'set_cache': no_channels = platformtools.dialog_ok( 'Novedades - %s' % item.extra, 'No se ha definido ningun canal para la ' 'busqueda.', 'Utilice el menu contextual ' 'para agregar al menos uno') return
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 start(itemlist, item): ''' Main method from which the links are automatically reproduced - In case the option to activate it will use the options defined by the user. - Otherwise it will try to reproduce any link that has the preferred language. :param itemlist: list (list of items ready to play, ie with action = 'play') :param item: item (the main item of the channel) :return: try to auto-reproduce, in case of failure it returns the itemlist that it received in the beginning ''' if item.global_search: return itemlist logger.debug() global PLAYED PLAYED = False base_item = item if not config.is_xbmc(): return itemlist if config.get_setting('autoplay'): url_list_valid = [] autoplay_list = [] autoplay_b = [] favorite_quality = [] favorite_servers = [] blacklisted_servers = config.get_setting("black_list", server='servers') if not blacklisted_servers: blacklisted_servers = [] from core import servertools servers_list = list(servertools.get_servers_list().items()) for server, server_parameters in servers_list: if config.get_setting('favorites_servers_list', server=server): favorite_servers.append(server.lower()) if not favorite_servers: config.set_setting('favorites_servers_list', [], server='servers') favorite_servers = [] else: favorite_servers = list( set(favorite_servers) - set(blacklisted_servers)) # Save the current value of "Action and Player Mode" in preferences user_config_setting_action = config.get_setting("default_action") # user_config_setting_player = config.get_setting("player_mode") # Enable the "View in high quality" action (if the server returns more than one quality, eg gdrive) if not user_config_setting_action: config.set_setting("default_action", 2) # if user_config_setting_player != 0: config.set_setting("player_mode", 0) # Priorities when ordering itemlist: # 0: Servers and qualities # 1: Qualities and servers # 2: Servers only # 3: Only qualities # 4: Do not order if config.get_setting('favorites_servers' ) and favorite_servers and config.get_setting( 'default_action'): priority = 0 # 0: Servers and qualities or 1: Qualities and servers elif config.get_setting('favorites_servers') and favorite_servers: priority = 2 # Servers only elif config.get_setting('default_action'): priority = 3 # Only qualities else: priority = 4 # Do not order if config.get_setting('default_action') == 1: quality_list.reverse() favorite_quality = quality_list for item in itemlist: autoplay_elem = dict() b_dict = dict() # We check that it is a video item if 'server' not in item: continue if item.server.lower() in blacklisted_servers: continue # If it does not have a defined quality, it assigns a 'default' quality. if item.quality.lower() not in quality_list: item.quality = 'default' # The list for custom settings is created if priority < 2: # 0: Servers and qualities or 1: Qualities and servers # if the server and the quality are not in the favorites lists or the url is repeated, we discard the item if item.server.lower( ) not in favorite_servers or item.quality.lower( ) not in favorite_quality or item.url in url_list_valid: item.type_b = True item.play_from = base_item.play_from b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_server"] = favorite_servers.index( item.server.lower()) autoplay_elem["indice_quality"] = favorite_quality.index( item.quality.lower()) elif priority == 2: # Servers only # if the server is not in the favorites list or the url is repeated, we discard the item if item.server.lower( ) not in favorite_servers or item.url in url_list_valid: item.type_b = True item.play_from = base_item.play_from b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_server"] = favorite_servers.index( item.server.lower()) elif priority == 3: # Only qualities # if the quality is not in the favorites list or the url is repeated, we discard the item if item.quality.lower( ) not in favorite_quality or item.url in url_list_valid: item.type_b = True item.play_from = base_item.play_from b_dict['videoitem'] = item autoplay_b.append(b_dict) continue autoplay_elem["indice_quality"] = favorite_quality.index( item.quality.lower()) else: # Do not order # if the url is repeated, we discard the item item.play_from = base_item.play_from if item.url in url_list_valid: continue # If the item reaches here we add it to the list of valid urls and to autoplay_list url_list_valid.append(item.url) item.plan_b = True item.play_from = base_item.play_from autoplay_elem['videoitem'] = item autoplay_list.append(autoplay_elem) # We order according to priority if priority == 0: autoplay_list.sort(key=lambda orden: ( (orden['indice_server'], orden['indice_quality'])) ) # Servers and qualities elif priority == 1: autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server'] )) # Qualities and servers elif priority == 2: autoplay_list.sort(key=lambda orden: (orden['indice_server'])) # Servers only elif priority == 3: autoplay_list.sort(key=lambda orden: (orden['indice_quality'])) # Only qualities logger.debug('PRIORITY', priority, autoplay_list) # if quality priority is active if priority == 0 and config.get_setting('quality_priority'): max_quality = autoplay_list[0][ "indice_quality"] if autoplay_list and "indice_quality" in autoplay_list[ 0] else 0 for n, item in enumerate(itemlist): if 'server' not in item: continue if item.server.lower() in blacklisted_servers: continue # If it does not have a defined quality, it assigns a 'default' quality. if item.quality == '': item.quality = 'default' if favorite_quality.index(item.quality.lower()) < max_quality: item.type_b = False autoplay_elem["indice_server"] = n autoplay_elem["indice_quality"] = favorite_quality.index( item.quality.lower()) autoplay_elem['videoitem'] = item autoplay_list.append(autoplay_elem) autoplay_list.sort(key=lambda orden: (orden['indice_quality'], orden['indice_server'])) # Plan b is prepared, in case it is active the non-favorite elements are added at the end # try: plan_b = settings_node['plan_b'] # except: plan_b = True text_b = '' if plan_b: autoplay_list.extend(autoplay_b) # If there are elements in the autoplay list, an attempt is made to reproduce each element, until one is found or all fail. if autoplay_list or (plan_b and autoplay_b): max_intentos = 5 max_intentos_servers = {} # If something is playing it stops playing if platformtools.is_playing(): platformtools.stop_video() for autoplay_elem in autoplay_list: play_item = Item channel_id = autoplay_elem['videoitem'].channel if autoplay_elem['videoitem'].channel == 'videolibrary': channel_id = autoplay_elem['videoitem'].contentChannel # If it is not a favorite element if you add the text plan b if autoplay_elem['videoitem'].type_b: text_b = '(Plan B)' if not platformtools.is_playing() and not PLAYED: videoitem = autoplay_elem['videoitem'] if videoitem.server.lower() not in max_intentos_servers: max_intentos_servers[ videoitem.server.lower()] = max_intentos # If the maximum number of attempts of this server have been reached, we jump to the next if max_intentos_servers[videoitem.server.lower()] == 0: continue lang = " " if hasattr(videoitem, 'language') and videoitem.language != "": lang = " '%s' " % videoitem.language name = servername(videoitem.server) platformtools.dialog_notification( "AutoPlay %s" % text_b, "%s%s%s" % (name, lang, videoitem.quality.upper()), sound=False) # Try to play the links If the channel has its own play method, use it try: channel = __import__('channels.%s' % channel_id, None, None, ["channels.%s" % channel_id]) except: channel = __import__('specials.%s' % channel_id, None, None, ["specials.%s" % channel_id]) if hasattr(channel, 'play'): resolved_item = getattr(channel, 'play')(videoitem) if len(resolved_item) > 0: if isinstance(resolved_item[0], list): videoitem.video_urls = resolved_item else: videoitem = resolved_item[0] play_item.autoplay = True # If not directly reproduce and mark as seen # Check if the item comes from the video library try: if base_item.contentChannel == 'videolibrary' or base_item.nfo: # Fill the video with the data of the main item and play play_item = base_item.clone(**videoitem.__dict__) platformtools.play_video(play_item, autoplay=True) else: # If it doesn't come from the video library, just play platformtools.play_video(videoitem, autoplay=True) except: pass sleep(3) try: if platformtools.is_playing(): PLAYED = True break except: logger.debug(str(len(autoplay_list))) # If we have come this far, it is because it could not be reproduced max_intentos_servers[videoitem.server.lower()] -= 1 # If the maximum number of attempts of this server has been reached, ask if we want to continue testing or ignore it. if max_intentos_servers[videoitem.server.lower()] == 0: text = config.get_localized_string(60072) % name if not platformtools.dialog_yesno( "AutoPlay", text, config.get_localized_string(60073)): max_intentos_servers[ videoitem.server.lower()] = max_intentos # If there are no items in the list, it is reported if autoplay_elem == autoplay_list[-1]: platformtools.dialog_notification( 'AutoPlay', config.get_localized_string(60072) % name) else: platformtools.dialog_notification( config.get_localized_string(60074), config.get_localized_string(60075)) # Restore if necessary the previous value of "Action and Player Mode" in preferences if not user_config_setting_action: config.set_setting("default_action", user_config_setting_action) # if user_config_setting_player != 0: config.set_setting("player_mode", user_config_setting_player) return itemlist