def mainlist(item): logger.info("pelisalacarta.channels.ayuda mainlist") itemlist = [] cuantos = 0 if cuantos > 0: itemlist.append(Item(channel=item.channel, action="tutoriales", title="Ver guías y tutoriales en vídeo")) else: itemlist.extend(tutoriales(item)) itemlist.append(Item(channel=item.channel, action="", title="", folder=False)) if config.is_xbmc(): #FIXME Al poner folder=False el log muestra: "WARNING: Attempt to use invalid handle -1" itemlist.append(Item(channel=item.channel, action="force_creation_advancedsettings", title="Crear fichero advancedsettings.xml optimizado", folder=True)) cuantos += cuantos if config.is_xbmc(): itemlist.append(Item(channel=item.channel, action="recover_advancedsettings", title="Restaurar advancedsettings.xml del backup", folder=False)) cuantos += cuantos return itemlist
def mainlist(item): logger.info("tvalacarta.channels.configuracion mainlist") itemlist = [] itemlist.append(Item(channel=CHANNELNAME, title="Preferencias", action="settings", folder=False)) itemlist.append(Item(channel=CHANNELNAME, title="", action="", folder=False)) itemlist.append(Item(channel=CHANNELNAME, title="Ajustes especiales", action="", folder=False)) itemlist.append(Item(channel="novedades", title=" Ajustes de la sección 'Novedades'", action="menu_opciones", folder=True)) itemlist.append(Item(channel="buscador", title=" Ajustes del buscador global", action="opciones", folder=True)) if config.is_xbmc(): itemlist.append(Item(channel=item.channel, action="updatebiblio", title=" Buscar nuevos episodios y actualizar biblioteca", folder=False)) itemlist.append(Item(channel=CHANNELNAME, title=" Comprobar actualizaciones", action="check_for_updates", folder=False)) itemlist.append(Item(channel=CHANNELNAME, title=" Añadir o Actualizar canal/conector desde una URL", action="menu_addchannels")) itemlist.append(Item(channel=item.channel, action="", title="", folder=False)) itemlist.append(Item(channel=CHANNELNAME, title="Ajustes por canales", action="", folder=False)) import channelselector from core import channeltools channel_list = channelselector.filterchannels("all") for channel in channel_list: jsonchannel = channeltools.get_channel_json(channel.channel) if jsonchannel.get("settings"): setting = jsonchannel["settings"] if type(setting) == list: if len([s for s in setting if "id" in s and not "include_in_" in s["id"]]): itemlist.append(Item(channel=CHANNELNAME, title=" Configuración del canal '%s'" % channel.title, action="channel_config", config=channel.channel, folder=False)) return itemlist
def remove_from_hidden(item): logger.info("tvalacarta.channels.api_programas remove_from_hidden item="+repr(item)) api.remove_from_hidden(item.url) if config.is_xbmc(): import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def add_to_favorites(item): logger.info("tvalacarta.channels.api_programas add_to_favorites item="+repr(item)) api.add_to_favorites(item.url) if config.is_xbmc(): import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def check_bookmark(readpath): # Crea un listado con las entradas de favoritos itemlist = [] if readpath.startswith("special://") and config.is_xbmc(): import xbmc readpath = xbmc.translatePath(readpath) for fichero in sorted(filetools.listdir(readpath)): # Ficheros antiguos (".txt") if fichero.endswith(".txt"): # Esperamos 0.1 segundos entre ficheros, para que no se solapen los nombres de archivo time.sleep(0.1) # Obtenemos el item desde el .txt canal, titulo, thumbnail, plot, server, url, fulltitle = readbookmark(filetools.join(readpath, fichero)) if canal == "": canal = "favoritos" item = Item(channel=canal, action="play", url=url, server=server, title=fulltitle, thumbnail=thumbnail, plot=plot, fanart=thumbnail, fulltitle=fulltitle, folder=False) filetools.rename(filetools.join(readpath, fichero),fichero[:-4] + ".old") itemlist.append(item) # Si hay Favoritos q guardar if itemlist: favourites_list = read_favourites() for item in itemlist: data = "ActivateWindow(10025,"plugin://plugin.video.pelisalacarta/?" + item.tourl() + "",return)" favourites_list.append((item.title, item.thumbnail, data)) if save_favourites(favourites_list): logger.debug("Conversion de txt a xml correcta")
def context(): _context = "" ''' configuración para mostrar la opción de filtro, actualmente sólo se permite en xbmc, se cambiará cuando 'platformtools.show_channel_settings' esté disponible para las distintas plataformas ''' if config.is_xbmc(): _context = [{"title": "Menu Filtro", "action": "config_item", "channel": "filtertools"}] # elif command == "guardar_filtro": # context_commands.append(("Guardar Filtro Serie", "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone( # channel="filtertools", # action="save_filter", # from_channel=item.channel # ).tourl()))) # # elif command == "borrar_filtro": # context_commands.append(("Eliminar Filtro", "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone( # channel="filtertools", # action="del_filter", # from_channel=item.channel # ).tourl()))) return _context
def download_and_install_package(item): logger.info() from core import updater from core import versiontools if item.package=="plugin": if int(item.version)<versiontools.get_current_plugin_version(): if not platformtools.dialog_yesno("Instalando versión anterior","¿Seguro que quieres instalar una versión anterior?"): return elif int(item.version)==versiontools.get_current_plugin_version(): if not platformtools.dialog_yesno("Reinstalando versión actual","¿Seguro que quieres reinstalar la misma versión que ya tienes?"): return elif int(item.version)>versiontools.get_current_plugin_version(): if not platformtools.dialog_yesno("Instalando nueva versión","¿Seguro que quieres instalar esta nueva versión?"): return else: if not platformtools.dialog_yesno("Instalando paquete","¿Seguro que quieres instalar este paquete?"): return local_file_name = os.path.join( config.get_data_path() , item.filename) updater.download_and_install(item.url,local_file_name) if config.is_xbmc() and config.get_system_platform() != "xbox": import xbmc xbmc.executebuiltin("Container.Refresh")
def format_plot(self,plot): ret= plot if not plot: return "" elif config.is_xbmc(): try: # Comprobamos si existe la funcion xbmctools.set_infoLabels() from platformcode import xbmctools if hasattr(xbmctools, "set_infoLabels"): return ret except: pass # Si no es xbmc o si no existe xbmctools.set_infoLabels(): # intentamos recuperar la sinopsis del infoLabels try: if plot.startswith("{'infoLabels'"): infoLabels=ast.literal_eval(plot)['infoLabels'] ret= infoLabels['plot'] except: pass return ret
def listchannels(params,url,category): logger.info("channelselector.listchannels") lista = filterchannels(category) for channel in lista: if config.is_xbmc() and (channel.type=="xbmc" or channel.type=="generic"): addfolder(channel.title , channel.channel , "mainlist" , channel.channel) elif config.get_platform()=="boxee" and channel.extra!="rtmp": addfolder(channel.title , channel.channel , "mainlist" , channel.channel) if config.get_platform()=="kodi-krypton": import plugintools plugintools.set_view( plugintools.TV_SHOWS ) # Label (top-right)... import xbmcplugin xbmcplugin.setPluginCategory( handle=int( sys.argv[ 1 ] ), category=category ) xbmcplugin.addSortMethod( handle=int( sys.argv[ 1 ] ), sortMethod=xbmcplugin.SORT_METHOD_NONE ) xbmcplugin.endOfDirectory( handle=int( sys.argv[ 1 ] ), succeeded=True ) if config.get_setting("forceview")=="true": # Confluence - Thumbnail import xbmc xbmc.executebuiltin("Container.SetViewMode(500)")
def download_and_install_package(item): logger.info() from core import updater from platformcode import platformtools if item.package=="plugin": if int(item.version)<updater.get_current_plugin_version(): if not platformtools.dialog_yesno("Installazione versione precedente","Sei sicuro di voler installare una versione precedente?"): return elif int(item.version)==updater.get_current_plugin_version(): if not platformtools.dialog_yesno("Reinstallare versione attuale","Sei sicuro di voler reinstallare la stessa versione già presente?"): return elif int(item.version)>updater.get_current_plugin_version(): if not platformtools.dialog_yesno("Installazione nuova versione","Sei sicuro di voler installare questa nuova versione?"): return else: if not platformtools.dialog_yesno("Pacchetto di installazione","Sei sicuro di voler installare questo pacchetto?"): return local_file_name = os.path.join( config.get_data_path() , item.filename) updater.download_and_install(item.url,local_file_name) if item.package=="channels": updater.set_current_channels_version(item.version) elif item.package=="servers": updater.set_current_servers_version(item.version) elif item.package=="plugin": updater.set_current_plugin_version(item.version) if config.is_xbmc() and config.get_system_platform() != "xbox": import xbmc xbmc.executebuiltin("Container.Refresh")
def mark_content_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_content_as_watched") # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): url_scraper = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == "movie": name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == "episode": name_file = item.contentSeason + "x" + item.contentEpisodeNumber else: name_file = item.contentTitle if not hasattr(it, "library_playcounts"): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != "movie": it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, url_scraper + it.tojson()): item.infoLabels["playcount"] = item.playcount if item.contentType == "tvshow": # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def mark_content_as_watched(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) if filetools.exists(item.nfo): head_nfo = filetools.read(item.nfo, 0, 1) it = Item().fromjson(filetools.read(item.nfo, 1)) if item.contentType == 'movie': name_file = os.path.splitext(os.path.basename(item.nfo))[0] elif item.contentType == 'episode': name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2)) else: name_file = item.contentTitle if not hasattr(it, 'library_playcounts'): it.library_playcounts = {} it.library_playcounts.update({name_file: item.playcount}) # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada if item.contentType != 'movie': it = check_season_playcount(it, item.contentSeason) # Guardamos los cambios en item.nfo if filetools.write(item.nfo, head_nfo + it.tojson()): item.infoLabels['playcount'] = item.playcount if item.contentType == 'tvshow': # Actualizar toda la serie new_item = item.clone(contentSeason=-1) mark_season_as_watched(new_item) if config.is_xbmc(): library.mark_content_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def update_biblio(item): logger.info() # Actualizar las series activas sobreescribiendo import library_service if item.extra == "overwrite_everything": if config.is_xbmc(): seleccion = platformtools.dialog_yesno(config.PLUGIN_NAME, "Avviso: devi attendere.", "Vuoi continuare ?") if seleccion == 1: library_service.check_for_update(overwrite="everything") else: library_service.check_for_update(overwrite="everything") else: library_service.check_for_update(overwrite=True) # Eliminar las carpetas de peliculas que no contengan archivo strm for raiz, subcarpetas, ficheros in filetools.walk(library.MOVIES_PATH): strm = False for f in ficheros: if f.endswith(".strm"): strm = True break if ficheros and not strm: logger.debug("Borrando carpeta de pelicula eliminada: %s" % raiz) filetools.rmdirtree(raiz)
def add_pelicula_to_library(item): """ guarda una pelicula en la libreria de cine. La pelicula puede ser un enlace dentro de un canal o un video descargado previamente. Para añadir episodios descargados en local, el item debe tener exclusivamente: - contentTitle: titulo de la pelicula - title: titulo a mostrar junto al listado de enlaces -findvideos- ("Reproducir video local HD") - infoLabels["tmdb_id"] o infoLabels["imdb_id"] - contentType == "movie" - channel = "descargas" - url : ruta local al video @type item: item @param item: elemento que se va a guardar. """ logger.info() if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.ask_set_content() new_item = item.clone(action="findvideos") insertados, sobreescritos, fallidos = save_library_movie(new_item) if fallidos == 0: platformtools.dialog_ok(config.get_localized_string(30131), new_item.contentTitle, config.get_localized_string(30135)) # 'se ha añadido a la biblioteca' else: platformtools.dialog_ok(config.get_localized_string(30131), "ERRORE, il contenuto non è stato aggiunto alla libreria")
def configuracion(item): from platformcode import platformtools platformtools.show_channel_settings() if config.is_xbmc(): import xbmc xbmc.executebuiltin("Container.Refresh")
def mark_as_unwatched(item): logger.info("tvalacarta.channels.api_programas mark_as_unwatched item="+repr(item)) api.mark_as_unwatched(item) if config.is_xbmc(): import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def peliculas(item): logger.info() itemlist = [] if "valores" in item and item.valores: itemlist.append(item.clone(action="", title=item.valores, text_color=color4)) if __menu_info__: action = "menu_info" else: 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) 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")) else: patron = '<div class="audio-info">(.*?)</div>(.*?)' \ '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('V.O') title = "%s [%s]" % (scrapedtitle, "/".join(audios)) if calidad: title += " (%s)" % calidad url = urlparse.urljoin(host, scrapedurl) 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")) next_page = scrapertools.find_single_match(data, 'href="([^"]+)"[^>]+>Siguiente') 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 add_to_hidden(item): logger.info("tvalacarta.channels.api_programas add_to_hidden item="+repr(item)) api.add_to_hidden(item) if config.is_xbmc(): import xbmcgui xbmcgui.Dialog().ok( "Programa ocultado" , "Ya no verás este programa ni sus vídeos, puedes volver a mostrarlo desde el menú de configuración.") import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def mainlist(item): logger.info("pelisalacarta.channels.ayuda mainlist") itemlist = [] cuantos = 0 if cuantos > 0: itemlist.append(Item(channel=item.channel, action="tutoriales", title="Ver guías y tutoriales en vídeo")) else: itemlist.extend(tutoriales(item)) itemlist.append(Item(channel=item.channel, action="", title="", folder=False)) if config.is_xbmc(): #FIXME Al poner folder=False el log muestra: "WARNING: Attempt to use invalid handle -1" itemlist.append(Item(channel=item.channel, action="force_creation_advancedsettings", title="Crear fichero advancedsettings.xml optimizado", folder=True)) cuantos += cuantos if config.is_xbmc(): itemlist.append(Item(channel=item.channel, action="recover_advancedsettings", title="Restaurar advancedsettings.xml del backup", folder=False)) cuantos += cuantos if not config.is_xbmc(): from core import channeltools title = "Activar cuenta real-debrid (No activada)" action = "realdebrid" token_auth = channeltools.get_channel_setting("realdebrid_token", "realdebrid") if config.get_setting("realdebridpremium") == "false": title = "Activar cuenta real-debrid (Marca la casilla en la ventana de configuración de pelisalacarta para continuar)" action = "" elif token_auth: title = "Activar cuenta real-debrid (Activada correctamente)" itemlist.append(Item(channel=item.channel, action=action, title=title)) return itemlist
def format_text(self,text): ''' [B]bold[/B] - bold text. [I]italics[/I] - italic text. [CR] - carriage return (line break). [COLOR red]red text[/COLOR] - colored text. http://www.w3schools.com/tags/ref_colornames.asp [COLOR 0xAARRGGBB]color text[/COLOR] colored text. http://www.w3schools.com/tags/ref_colorpicker.asp No implementados aun: [UPPERCASE]force text uppercase[/UPPERCASE] - force text to uppercase. [LOWERCASE]Force Text Lowercase[/LOWERCASE] - force text to lowercase. [CAPITALIZE]Force first letter to uppercase[/CAPITALIZE] - makes the first letter of a sentence a capital letter (Isengard only). ''' bbcode= (('[B]','<b>'), ('[/B]','</b>'), ('[I]','<i>'), ('[/I]','</i>'), ('[/COLOR]','</span>'), ('[UPPERCASE]',''), ('[/UPPERCASE]',''), ('[LOWERCASE]',''), ('[/LOWERCASE]',''), ('[CAPITALIZE]',''), ('[/CAPITALIZE]',''), ('[CR]','<br>')) if not text or config.is_xbmc(): return text elif config.get_platform().startswith("plex") or config.get_platform().startswith("mediaserver"): # Plex o html: adaptar bbcode (basado de la funcion bbcode_kodi2html de robalo) # COLOR color_orig= ('yellow', 'white') color_sust= ('gold', 'auto') colores = re.findall(r'\[COLOR\s([^\]]+)\]',text) for color in colores: tag_orig = '\[COLOR\s' + color + '\]' if color.startswith('0x'): color= "#" + color[4:] elif color in color_orig: color= color_sust[color_orig.index(color)] text = re.sub(tag_orig, '<span style="color:' + color + '">', text) # Otros TAGs for b in bbcode: text = text.replace(b[0],b[1]) else: # Plataforma desconocida: eliminar bbcode text = re.sub(r'\[COLOR\s([^\]]+)\]','', text) for b in bbcode: text = text.replace(b[0],'') return text
def context(): _context = "" ''' configuración para mostrar la opción de renumeración, actualmente sólo se permite en xbmc, se cambiará cuando 'platformtools.show_channel_settings' esté disponible para las distintas plataformas ''' if config.is_xbmc(): _context = [{"title": "RENUMERAR", "action": "config_item", "channel": "renumbertools"}] return _context
def unsubscribe_to_program(item): logger.info("tvalacarta.channels.api_programas subscribe_to_program item="+repr(item)) if suscription.already_suscribed(item): suscription.remove_suscription(item) if config.is_xbmc(): import xbmcgui xbmcgui.Dialog().ok( "Descarga automática cancelada" , "Los vídeos que hayas descargado se mantienen, pero los nuevos ya no se descargarán ellos solos.") import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def eliminar_todo(item): filetools.rmdirtree(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 biblioteca de Kodi al añadirle un path # limpiamos la biblioteca de Kodi library.clean() logger.info("Eliminados todos los enlaces") platformtools.itemlist_refresh()
def mainlist(item): logger.info("pelisalacarta.channels.ayuda mainlist") itemlist = [] cuantos = 0 if config.is_xbmc(): itemlist.append(Item(channel=item.channel, action="force_creation_advancedsettings", title="Crear fichero advancedsettings.xml optimizado")) cuantos += cuantos if config.is_xbmc(): itemlist.append(Item(channel=item.channel, action="updatebiblio", title="Buscar nuevos episodios y actualizar biblioteca")) cuantos += cuantos if cuantos > 0: itemlist.append(Item(channel=item.channel, action="tutoriales", title="Ver guías y tutoriales en vídeo")) else: itemlist.extend(tutoriales(item)) return itemlist
def subscribe_to_program(item): logger.info("tvalacarta.channels.api_programas subscribe_to_program item="+repr(item)) item.action = "videos_get_by_program" if not suscription.already_suscribed(item): suscription.append_suscription(item) if config.is_xbmc(): import xbmcgui xbmcgui.Dialog().ok( "tvalacarta" , "Suscripción a \""+item.title+"\" creada") import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def unsubscribe_to_program(item): logger.info("tvalacarta.channels.api_programas subscribe_to_program item="+repr(item)) item.action = "videos_get_by_program" if suscription.already_suscribed(item): suscription.remove_suscription(item) if config.is_xbmc(): import xbmcgui xbmcgui.Dialog().ok( "tvalacarta" , "Suscripción a \""+item.title+"\" eliminada" , "Los vídeos que hayas descargado se mantienen" ) import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()");
def update_serie(item): logger.info() #logger.debug("item:\n" + item.tostring('\n')) heading = 'Actualizando serie....' p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading) p_dialog.update(0, heading, item.contentSerieName) import library_service if library_service.update(item.path, p_dialog, 1, 1, item, False) and config.is_xbmc(): library.update(folder=filetools.basename(item.path)) p_dialog.close()
def administrar_suscripciones(item): logger.info("core.descargas administrar_suscripciones") itemlist=[] current_suscriptions = suscription.get_current_suscriptions() for suscription_item in current_suscriptions: itemlist.append( Item( channel="descargas" , action="borrar_suscripcion" , url=suscription_item.url , title=suscription_item.title, thumbnail=suscription_item.thumbnail, plot=suscription_item.plot, fanart=suscription_item.thumbnail, folder=False )) if len(itemlist)==0 and config.is_xbmc(): import xbmcgui xbmcgui.Dialog().ok( "No tienes descargas automáticas" , "Elige un programa con el menú contextual, y añádelo a descargas automáticas para que los vídeos se descarguen solos a medida que se vayan publicando.") return itemlist
def mark_season_as_watched(item): logger.info("pelisalacarta.channels.biblioteca mark_season_as_watched") # logger.debug("item:\n" + item.tostring('\n')) # Obtener el diccionario de episodios marcados f = filetools.join(item.path, "tvshow.nfo") url_scraper = filetools.read(f, 0, 1) it = Item().fromjson(filetools.read(f, 1)) if not hasattr(it, "library_playcounts"): it.library_playcounts = {} # Obtenemos los archivos de los episodios raiz, carpetas_series, ficheros = filetools.walk(item.path).next() # Marcamos cada uno de los episodios encontrados de esta temporada episodios_marcados = 0 for i in ficheros: if i.endswith(".strm"): season_episode = scrapertools.get_season_and_episode(i) if not season_episode: # El fichero no incluye el numero de temporada y episodio continue season, episode = season_episode.split("x") if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason): name_file = os.path.splitext(os.path.basename(i))[0] it.library_playcounts[name_file] = item.playcount episodios_marcados += 1 if episodios_marcados: if int(item.contentSeason) == -1: # Añadimos todas las temporadas al diccionario item.library_playcounts for k in it.library_playcounts.keys(): if k.startswith("season"): it.library_playcounts[k] = item.playcount else: # Añadimos la temporada al diccionario item.library_playcounts it.library_playcounts["season %s" % item.contentSeason] = item.playcount # se comprueba que si todas las temporadas están vistas, se marque la serie como vista it = check_tvshow_playcount(it, item.contentSeason) # Guardamos los cambios en tvshow.nfo filetools.write(f, url_scraper + it.tojson()) item.infoLabels["playcount"] = item.playcount if config.is_xbmc(): # Actualizamos la BBDD de Kodi library.mark_season_as_watched_on_kodi(item, item.playcount) platformtools.itemlist_refresh()
def get_video_url(page_url, premium=False, video_password=""): logger.info("pelisalacarta.servers.realdebrid get_video_url( page_url='%s' , video_password=%s)" % (page_url, video_password)) # Se comprueba si existe un token guardado y sino se ejecuta el proceso de autentificación token_auth = channeltools.get_channel_setting("realdebrid_token", "realdebrid") if token_auth is None or token_auth == "": if config.is_xbmc(): token_auth = authentication() if token_auth == "": return [["REAL-DEBRID: No se ha completado el proceso de autentificación", ""]] else: return [["Es necesario activar la cuenta. Accede al menú de ayuda", ""]] post_link = urllib.urlencode([("link", page_url), ("password", video_password)]) headers["Authorization"] = "Bearer %s" % token_auth url = "https://api.real-debrid.com/rest/1.0/unrestrict/link" data = scrapertools.downloadpage(url, post=post_link, headers=headers.items()) data = jsontools.load_json(data) # Si el token es erróneo o ha caducado, se solicita uno nuevo if "error" in data and data["error"] == "bad_token": debrid_id = channeltools.get_channel_setting("realdebrid_id", "realdebrid") secret = channeltools.get_channel_setting("realdebrid_secret", "realdebrid") refresh = channeltools.get_channel_setting("realdebrid_refresh", "realdebrid") post_token = urllib.urlencode({"client_id": debrid_id, "client_secret": secret, "code": refresh, "grant_type": "http://oauth.net/grant_type/device/1.0"}) renew_token = scrapertools.downloadpage("https://api.real-debrid.com/oauth/v2/token", post=post_token, headers=headers.items()) renew_token = jsontools.load_json(renew_token) if not "error" in renew_token: token_auth = renew_token["access_token"] channeltools.set_channel_setting("realdebrid_token", token_auth, "realdebrid") headers["Authorization"] = "Bearer %s" % token_auth data = scrapertools.downloadpage(url, post=post_link, headers=headers.items()) data = jsontools.load_json(data) if "download" in data: return get_enlaces(data) else: if "error" in data: msg = data["error"].decode("utf-8","ignore") msg = msg.replace("hoster_unavailable", "Servidor no disponible") \ .replace("unavailable_file", "Archivo no disponible") \ .replace("hoster_not_free", "Servidor no gratuito") \ .replace("bad_token", "Error en el token") return [["REAL-DEBRID: " + msg, ""]] else: return [["REAL-DEBRID: No se ha generado ningún enlace", ""]]
def mainlist(item): logger.info() itemlist = list() itemlist.append( Item(channel=CHANNELNAME, title="Preferencias", action="settings", folder=False, thumbnail=config.get_thumb("thumb_setting_0.png"))) # if config.get_setting("plugin_updates_available") == 0: # nuevas = "" # elif config.get_setting("plugin_updates_available") == 1: # nuevas = " (1 nueva)" # else: # nuevas = " (%s nuevas)" % config.get_setting("plugin_updates_available") # # thumb_configuracion = "thumb_setting_%s.png" % config.get_setting("plugin_updates_available") # # itemlist.append(Item(channel=CHANNELNAME, title="Descargar e instalar otras versiones" + nuevas, # action="get_all_versions", folder=True, # thumbnail=config.get_thumb(thumb_configuracion))) itemlist.append( Item(channel=CHANNELNAME, title="", action="", folder=False, thumbnail=config.get_thumb("thumb_setting_0.png"))) itemlist.append( Item(channel=CHANNELNAME, title="Ajustes especiales", action="", folder=False, thumbnail=config.get_thumb("thumb_setting_0.png"))) itemlist.append( Item(channel=CHANNELNAME, title=" Ajustes de Canales", action="menu_channels", folder=True, thumbnail=config.get_thumb("thumb_channels.png"))) itemlist.append( Item(channel=CHANNELNAME, title=" Ajustes de Servidores", action="menu_servers", folder=True, thumbnail=config.get_thumb("thumb_channels.png"))) itemlist.append( Item(channel="news", title=" Ajustes de la sección 'Novedades'", action="menu_opciones", folder=True, thumbnail=config.get_thumb("thumb_news.png"))) itemlist.append( Item(channel="search", title=" Ajustes del buscador global", action="opciones", folder=True, thumbnail=config.get_thumb("thumb_search.png"))) itemlist.append( Item(channel=CHANNELNAME, title=" Ajustes de descargas", action="channel_config", config="downloads", folder=True, thumbnail=config.get_thumb("thumb_downloads.png"))) if config.get_videolibrary_support(): itemlist.append( Item(channel="videolibrary", title=" Ajustes de la videoteca", action="channel_config", folder=True, thumbnail=config.get_thumb("thumb_videolibrary.png"))) if config.is_xbmc(): itemlist.append( Item(channel=CHANNELNAME, title=" Ajustes de cliente Torrent", action="setting_torrent", folder=True, thumbnail=config.get_thumb("thumb_channels_torrent.png"))) # itemlist.append(Item(channel=CHANNELNAME, title=" Añadir o Actualizar canal/conector desde una URL", # action="menu_addchannels")) itemlist.append( Item(channel=CHANNELNAME, action="", title="", folder=False, thumbnail=config.get_thumb("thumb_setting_0.png"))) itemlist.append( Item(channel=CHANNELNAME, title="Otras herramientas", action="submenu_tools", folder=True, thumbnail=config.get_thumb("thumb_setting_0.png"))) return itemlist
def peliculas(item): logger.info() itemlist = [] if "valores" in item and item.valores: itemlist.append( item.clone(action="", title=item.valores, text_color=color4)) if __menu_info__: action = "menu_info" else: 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) 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")) else: patron = '<div class="audio-info">(.*?)</div>(.*?)' \ '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('V.O') title = "%s [%s]" % (scrapedtitle, "/".join(audios)) if calidad: title += " (%s)" % calidad url = urlparse.urljoin(host, scrapedurl) 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")) next_page = scrapertools.find_single_match( data, 'href="([^"]+)"[^>]+>Siguiente') 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
# ------------------------------------------------------------ # MiTvSpain - XBMC Plugin # ------------------------------------------------------------ import re import urlparse from os import path from core import config from core import filetools from core import httptools from core import logger from core import scrapertools from core.item import Item from core import channeltools if config.is_xbmc(): from channels import renumbertools if not config.is_xbmc(): from platformcode import platformtools platformtools.dialog_notification( "¡ALERTA!", "El renumerado no funciona " "en la version Plex o Mediaserver") CHANNEL_HOST = "http://animeflv.me/" CHANNEL_DEFAULT_HEADERS = [["User-Agent", "Mozilla/5.0"], ["Accept-Encoding", "gzip, deflate"], ["Referer", CHANNEL_HOST]] REGEX_NEXT_PAGE = r"class='current'>\d+?</li><li><a href=\"([^']+?)\"" REGEX_TITLE = r'(?:bigChar_a" href=.+?>)(.+?)(?:</a>)' REGEX_THUMB = r'src="(http://media.animeflv\.me/uploads/thumbs/[^"]+?)"'
def check_for_update(overwrite=True): logger.info("Actualizando series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() try: if config.get_setting("updatelibrary", "biblioteca") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "biblioteca") heading = 'Actualizando biblioteca....' p_dialog = platformtools.dialog_progress_bg( 'pelisalacarta', heading) p_dialog.update(0, '') show_list = [] for path, folders, files in filetools.walk(library.TVSHOWS_PATH): show_list.extend([ filetools.join(path, f) for f in files if f == "tvshow.nfo" ]) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Podria ser del tipo bool if not serie.active: # si la serie no esta activa descartar continue # obtenemos las fecha de actualizacion y de la proxima programada para esta serie update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # si la serie esta activa ... if overwrite or config.get_setting("updatetvshows_interval", "biblioteca") == 0: # ... forzar actualizacion independientemente del intervalo serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...actualizacion diaria serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta( days=7): # si hace una semana q no se actualiza, pasar el intervalo a semanal interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...actualizacion semanal serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...actualizacion mensual serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime( '%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "biblioteca" serie.action = "get_temporadas" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "biblioteca") == 0: # Actualizamos la biblioteca de Kodi: Buscar contenido en la carpeta de la serie if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update( folder=filetools.basename(path)) else: update_when_finished = True if config.get_setting("search_new_content", "biblioteca") == 1 and update_when_finished: # Actualizamos la biblioteca de Kodi: Buscar contenido en todas las series if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update() p_dialog.close() else: logger.info( "No actualiza la biblioteca, está desactivado en la configuración de pelisalacarta" ) except Exception as ex: logger.error("Se ha producido un error al actualizar las series") template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) if p_dialog: p_dialog.close()
def add_serie_to_library(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 = "descargas" - 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 + "#") # logger.debug(item.tostring('\n')) if item.channel == "descargas": 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" # Obtiene el listado de episodios itemlist = getattr(channel, item.action)(item) # Eliminamos de la lista lo q no sean episodios for it in itemlist: if not scrapertools.get_season_and_episode(it.title): itemlist.remove(it) if not itemlist: platformtools.dialog_ok("Biblioteca", "ERROR, la serie NO se ha añadido a la biblioteca", "No se ha podido obtener ningun episodio") logger.error("La serie %s no se ha podido añadir a la biblioteca. No se ha podido obtener ningun episodio" % item.show) return insertados, sobreescritos, fallidos = save_library_tvshow(item, itemlist) if fallidos == -1: platformtools.dialog_ok("Biblioteca", "ERROR, la serie NO se ha añadido a la biblioteca") logger.error("La serie %s no se ha podido añadir a la biblioteca" % item.show) elif fallidos > 0: platformtools.dialog_ok("Biblioteca", "ERROR, la serie NO se ha añadido completa a la biblioteca") logger.error("No se han podido añadir %s episodios de la serie %s a la biblioteca" % (fallidos, item.show)) else: platformtools.dialog_ok("Biblioteca", "La serie se ha añadido a la biblioteca") logger.info("[launcher.py] Se han añadido %s episodios de la serie %s a la biblioteca" % (insertados, item.show)) if config.is_xbmc(): if config.get_setting("sync_trakt_new_tvshow", "biblioteca"): import xbmc from platformcode import xbmc_library if config.get_setting("sync_trakt_new_tvshow_wait", "biblioteca"): # Comprobar que no se esta buscando contenido en la biblioteca de Kodi while xbmc.getCondVisibility('Library.IsScanningVideo()'): xbmc.sleep(1000) # Se lanza la sincronizacion xbmc_library.sync_trakt()
def save_library_episodes(path, episodelist, serie, silent=False, overwrite=True): """ guarda en la ruta indicada todos los capitulos incluidos en la lista episodelist @type path: str @param path: ruta donde guardar los episodios @type episodelist: list @param episodelist: listado de items que representan los episodios que se van a guardar. @type serie: item @param serie: serie de la que se van a guardar los episodios @type silent: bool @param silent: establece si se muestra la notificación @param overwrite: permite sobreescribir los ficheros existentes @type overwrite: bool @rtype insertados: int @return: el número de episodios insertados @rtype sobreescritos: int @return: el número de episodios sobreescritos @rtype fallidos: int @return: el número de episodios fallidos """ logger.info() # No hay lista de episodios, no hay nada que guardar if not len(episodelist): logger.info("No hay lista de episodios, salimos sin crear strm") return 0, 0, 0 insertados = 0 sobreescritos = 0 fallidos = 0 news_in_playcounts = {} if overwrite == "everything": overwrite = True overwrite_everything = True else: overwrite_everything = False # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno raiz, carpetas_series, ficheros = filetools.walk(path).next() ficheros = [filetools.join(path, f) for f in ficheros] # Silent es para no mostrar progreso (para library_service) if not silent: # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo episodios...') p_dialog.update(0, 'Añadiendo episodio...') # fix float porque la division se hace mal en python 2.x t = float(100) / len(episodelist) for i, e in enumerate(episodelist): if not silent: p_dialog.update(int(math.ceil((i + 1) * t)), 'Añadiendo episodio...', e.title) try: season_episode = scrapertools.get_season_and_episode(e.title.lower()) e.infoLabels = serie.infoLabels e.contentSeason, e.contentEpisodeNumber = season_episode.split("x") season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2)) except: continue strm_path = filetools.join(path, "%s.strm" % season_episode) nfo_path = filetools.join(path, "%s.nfo" % season_episode) json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower()) strm_exists = strm_path in ficheros nfo_exists = nfo_path in ficheros json_exists = json_path in ficheros strm_exists_before = True nfo_exists_before = True json_exists_before = True if not strm_exists or overwrite_everything: if not overwrite_everything: strm_exists_before = False # Si no existe season_episode.strm añadirlo item_strm = Item(action='play_from_library', channel='biblioteca', strm_path=strm_path.replace(TVSHOWS_PATH, ""), infoLabels={}) item_strm.contentSeason = e.contentSeason item_strm.contentEpisodeNumber = e.contentEpisodeNumber item_strm.contentType = e.contentType item_strm.contentTitle = season_episode # FILTERTOOLS if item_strm.list_idiomas: # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar if "library_filter_show" in serie: item_strm.library_filter_show = serie.library_filter_show if item_strm.library_filter_show == "": logger.error("Se ha producido un error al obtener el nombre de la serie a filtrar") # logger.debug("item_strm" + item_strm.tostring('\n')) # logger.debug("serie " + serie.tostring('\n')) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo = None if (not nfo_exists or overwrite_everything) and e.infoLabels["code"]: if not overwrite_everything: nfo_exists_before = False # Si no existe season_episode.nfo añadirlo scraper.find_and_set_infoLabels(e) head_nfo = scraper.get_nfo(e) item_nfo = e.clone(channel="biblioteca", url="", action='findvideos', strm_path=strm_path.replace(TVSHOWS_PATH, "")) nfo_exists = filetools.write(nfo_path, head_nfo + item_nfo.tojson()) # Solo si existen season_episode.nfo y season_episode.strm continuamos if nfo_exists and strm_exists: if not json_exists or overwrite: # Obtenemos infoLabel del episodio if not item_nfo: head_nfo, item_nfo = read_nfo(nfo_path) e.infoLabels = item_nfo.infoLabels if filetools.write(json_path, e.tojson()): if not json_exists or overwrite_everything: if not overwrite_everything: json_exists_before = False logger.info("Insertado: %s" % json_path) else: logger.info("Sobreescritos todos los archivos!") # Marcamos episodio como no visto news_in_playcounts[season_episode] = 0 # Marcamos la temporada como no vista news_in_playcounts["season %s" % e.contentSeason] = 0 # Marcamos la serie como no vista # logger.debug("serie " + serie.tostring('\n')) news_in_playcounts[serie.contentTitle] = 0 if not overwrite_everything and not json_exists: json_exists = True 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 strm_exists_before or not nfo_exists_before or not json_exists_before: if strm_exists and nfo_exists and json_exists: insertados += 1 else: logger.error("El archivo strm, nfo o json no existe") if not silent and p_dialog.iscanceled(): break if not silent: p_dialog.close() if news_in_playcounts: # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ... tvshow_path = filetools.join(path, "tvshow.nfo") try: import datetime head_nfo, tvshow_item = read_nfo(tvshow_path) tvshow_item.library_playcounts.update(news_in_playcounts) if tvshow_item.active == 30: tvshow_item.active = 1 update_last = datetime.date.today() tvshow_item.update_last = update_last.strftime('%Y-%m-%d') update_next = datetime.date.today() + datetime.timedelta(days=int(tvshow_item.active)) tvshow_item.update_next = update_next.strftime('%Y-%m-%d') filetools.write(tvshow_path, head_nfo + tvshow_item.tojson()) except: logger.error("Error al actualizar tvshow.nfo") fallidos = -1 # ... y actualizamos la biblioteca de Kodi if config.is_xbmc() and not silent: from platformcode import xbmc_library xbmc_library.update(FOLDER_TVSHOWS, filetools.basename(path)) if fallidos == len(episodelist): fallidos = -1 logger.debug("%s [%s]: insertados= %s, sobreescritos= %s, fallidos= %s" % (serie.contentSerieName, serie.channel, insertados, sobreescritos, fallidos)) return insertados, sobreescritos, fallidos
logger.info("LIBRARY_PATH (RAW): " + LIBRARY_PATH) # logger.info("MOVIES_PATH (RAW): " + MOVIES_PATH) # logger.info("TVSHOWS_PATH (RAW): " + TVSHOWS_PATH) logger.info("FOLDER_MOVIES (RAW): " + FOLDER_MOVIES) logger.info("FOLDER_TVSHOWS (RAW): " + FOLDER_TVSHOWS) addon_name = "plugin://plugin.video.pelisalacarta/" # TODO: mover todo esto a config.verify_directories_created() if not filetools.exists(LIBRARY_PATH): logger.info("Library path doesn't exist:" + LIBRARY_PATH) config.verify_directories_created() if not filetools.exists(MOVIES_PATH): logger.info("Movies path doesn't exist:" + MOVIES_PATH) if filetools.mkdir(MOVIES_PATH)and config.is_xbmc(): if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.establecer_contenido(FOLDER_MOVIES) if not filetools.exists(TVSHOWS_PATH): logger.info("Tvshows path doesn't exist:" + TVSHOWS_PATH) if filetools.mkdir(TVSHOWS_PATH) and config.is_xbmc(): if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.establecer_contenido(FOLDER_TVSHOWS) def read_nfo(path_nfo, item=None): """ Metodo para leer archivos nfo.
def findvideos(item): logger.info() itemlist = list() try: filtro_idioma = config.get_setting("filterlanguages", item.channel) filtro_enlaces = config.get_setting("filterlinks", item.channel) except: filtro_idioma = 3 filtro_enlaces = 2 dict_idiomas = {'Castellano': 2, 'Latino': 1, 'Subtitulada': 0} data = httptools.downloadpage(item.url).data data = re.sub(r"\n|\r|\t| |\s{2}", "", data) if not item.infoLabels["tmdb_id"]: year = scrapertools.find_single_match(data, 'Lanzamiento.*?(\d{4})') if year != "": item.infoLabels['filtro'] = "" item.infoLabels['year'] = int(year) # Ampliamos datos en tmdb try: tmdb.set_infoLabels_item(item, __modo_grafico__) except: pass if not item.infoLabels['plot']: plot = scrapertools.find_single_match(data, '<p class="plot">(.*?)</p>') item.infoLabels['plot'] = plot if filtro_enlaces != 0: list_enlaces = bloque_enlaces(data, filtro_idioma, dict_idiomas, "Ver Online", item) if list_enlaces: itemlist.append( item.clone(action="", title="Enlaces Online", text_color=color1, text_bold=True)) itemlist.extend(list_enlaces) if filtro_enlaces != 1: list_enlaces = bloque_enlaces(data, filtro_idioma, dict_idiomas, "Descarga Directa", item) if list_enlaces: itemlist.append( item.clone(action="", title="Enlaces Descarga", text_color=color1, text_bold=True)) itemlist.extend(list_enlaces) # Opción "Añadir esta película a la videoteca de XBMC" if itemlist and item.contentType == "movie": contextual = config.is_xbmc() itemlist.append( item.clone(channel="trailertools", title="Buscar Tráiler", action="buscartrailer", context="", text_color="magenta", contextual=contextual)) if item.extra != "findvideos": if config.get_videolibrary_support(): itemlist.append( Item(channel=item.channel, title="Añadir enlaces a la videoteca", text_color="green", filtro=True, action="add_pelicula_to_library", fulltitle=item.fulltitle, extra="findvideos", url=item.url, infoLabels=item.infoLabels, contentType=item.contentType, contentTitle=item.contentTitle, show=item.show)) elif not itemlist and item.contentType == "movie": itemlist.append( item.clone(title="Película sin enlaces disponibles", action="", text_color=color3)) return itemlist
def convert_old_to_v4(): logger.info() path_series_xml = filetools.join(config.get_data_path(), "series.xml") path_series_json = filetools.join(config.get_data_path(), "series.json") series_insertadas = 0 series_fallidas = 0 version = 'v?' # Renombrar carpeta Series y crear una vacia import time new_name = str(time.time()) path_series_old = filetools.join(library.LIBRARY_PATH, "SERIES_OLD_" + new_name) if filetools.rename(library.TVSHOWS_PATH, "SERIES_OLD_" + new_name): if not filetools.mkdir(library.TVSHOWS_PATH): logger.error( "ERROR, no se ha podido crear la nueva carpeta de SERIES") return False else: logger.error( "ERROR, no se ha podido renombrar la antigua carpeta de SERIES") return False path_cine_old = filetools.join(library.LIBRARY_PATH, "CINE_OLD_" + new_name) if filetools.rename(library.MOVIES_PATH, "CINE_OLD_" + new_name): if not filetools.mkdir(library.MOVIES_PATH): logger.error( "ERROR, no se ha podido crear la nueva carpeta de CINE") return False else: logger.error( "ERROR, no se ha podido renombrar la antigua carpeta de CINE") return False # Convertir libreria de v1(xml) a v4 if filetools.exists(path_series_xml): try: data = filetools.read(path_series_xml) for line in data.splitlines(): try: aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item(contentSerieName=tvshow, url=url, channel=channel, action="episodios", title=tvshow, active=True) patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall( serie.contentSerieName) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow( serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification( "Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_xml, "series.xml.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_xml) return False # Convertir libreria de v2(json) a v4 if filetools.exists(path_series_json): try: data = jsontools.load_json(filetools.read(path_series_json)) for tvshow in data: for channel in data[tvshow]["channels"]: try: serie = Item( contentSerieName=data[tvshow]["channels"][channel] ["tvshow"], url=data[tvshow]["channels"][channel]["url"], channel=channel, action="episodios", title=data[tvshow]["name"], active=True) if not tvshow.startswith("t_"): serie.infoLabels["tmdb_id"] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow( serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification( "Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_json, "series.json.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_json) return False # Convertir libreria de v3 a v4 if version != 'v4': # Obtenemos todos los tvshow.json de la biblioteca de SERIES_OLD recursivamente for raiz, subcarpetas, ficheros in filetools.walk(path_series_old): for f in ficheros: if f == "tvshow.json": try: serie = Item().fromjson( filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_tvshow( serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification( "Serie actualizada", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 movies_insertadas = 0 movies_fallidas = 0 for raiz, subcarpetas, ficheros in filetools.walk(path_cine_old): for f in ficheros: if f.endswith(".strm.json"): try: movie = Item().fromjson( filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_movie( movie) if fallidos == 0: movies_insertadas += 1 platformtools.dialog_notification( "Película actualizada", movie.infoLabels['title']) else: movies_fallidas += 1 except: movies_fallidas += 1 config.set_setting("library_version", 'v4') platformtools.dialog_notification( "Biblioteca actualizada al nuevo formato", "%s series convertidas y %s series descartadas.\n" "%s peliculas convertidas y %s peliculas descartadas." "A continuación se va a obtener la información de todos los episodios" % (series_insertadas, series_fallidas, movies_insertadas, movies_fallidas), time=12000) # Por ultimo limpia la libreria, por que las rutas anteriores ya no existen if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.clean() return True
def downloadall(item): logger.info("core.descargas downloadall") # Lee la lista de ficheros if usingsamba: ficheros = samba.get_files(DOWNLOAD_LIST_PATH) else: ficheros = os.listdir(DOWNLOAD_LIST_PATH) logger.info("core.descargas numero de ficheros=%d" % len(ficheros)) # La ordena ficheros.sort() # Crea un listado con las entradas de favoritos for fichero in ficheros: # El primer video de la lista logger.info("core.descargas fichero=" + fichero) if fichero != "error" and fichero != ".DS_Store": # Descarga el vídeo try: # Lee el bookmark canal, titulo, thumbnail, plot, server, url, fulltitle = favoritos.readbookmark( fichero, DOWNLOAD_LIST_PATH) logger.info("core.descargas url=" + url) # Averigua la URL del vídeo exec "from servers import " + server + " as server_connector" video_urls = server_connector.get_video_url( page_url=url, premium=(config.get_setting("megavideopremium") == "true"), user=config.get_setting("megavideouser"), password=config.get_setting("megavideopassword")) # La primera es la de mayor calidad, lo mejor para la descarga mediaurl = video_urls[0][1] logger.info("core.descargas mediaurl=" + mediaurl) # Genera el NFO nfofilepath = downloadtools.getfilefromtitle( "sample.nfo", fulltitle) outfile = open(nfofilepath, "w") outfile.write("<movie>\n") outfile.write("<title>(" + fulltitle + ")</title>\n") outfile.write("<originaltitle></originaltitle>\n") outfile.write("<rating>0.000000</rating>\n") outfile.write("<year>2009</year>\n") outfile.write("<top250>0</top250>\n") outfile.write("<votes>0</votes>\n") outfile.write("<outline></outline>\n") outfile.write("<plot>" + plot + "</plot>\n") outfile.write("<tagline></tagline>\n") outfile.write("<runtime></runtime>\n") outfile.write("<thumb></thumb>\n") outfile.write("<mpaa>Not available</mpaa>\n") outfile.write("<playcount>0</playcount>\n") outfile.write("<watched>false</watched>\n") outfile.write("<id>tt0432337</id>\n") outfile.write("<filenameandpath></filenameandpath>\n") outfile.write("<trailer></trailer>\n") outfile.write("<genre></genre>\n") outfile.write("<credits></credits>\n") outfile.write("<director></director>\n") outfile.write("<actor>\n") outfile.write("<name></name>\n") outfile.write("<role></role>\n") outfile.write("</actor>\n") outfile.write("</movie>") outfile.flush() outfile.close() logger.info("core.descargas Creado fichero NFO") # Descarga el thumbnail if thumbnail != "": logger.info("core.descargas thumbnail=" + thumbnail) thumbnailfile = downloadtools.getfilefromtitle( thumbnail, fulltitle) thumbnailfile = thumbnailfile[:-4] + ".tbn" logger.info("core.descargas thumbnailfile=" + thumbnailfile) try: downloadtools.downloadfile(thumbnail, thumbnailfile) logger.info("core.descargas Thumbnail descargado") except: logger.info( "core.descargas error al descargar thumbnail") for line in sys.exc_info(): logger.error("%s" % line) # Descarga el video dev = downloadtools.downloadtitle(mediaurl, fulltitle) if dev == -1: # El usuario ha cancelado la descarga logger.info("core.descargas Descarga cancelada") return elif dev == -2: # Error en la descarga, lo mueve a ERROR y continua con el siguiente logger.info("core.descargas ERROR EN DESCARGA DE " + fichero) if not usingsamba: origen = os.path.join(DOWNLOAD_LIST_PATH, fichero) destino = os.path.join(ERROR_PATH, fichero) import shutil shutil.move(origen, destino) else: favoritos.savebookmark(canal, titulo, url, thumbnail, server, plot, fulltitle, ERROR_PATH) favoritos.deletebookmark(fichero, DOWNLOAD_LIST_PATH) else: logger.info("core.descargas Video descargado") # Borra el bookmark e itera para obtener el siguiente video filepath = os.path.join(DOWNLOAD_LIST_PATH, fichero) if usingsamba: os.remove(filepath) else: favoritos.deletebookmark(fichero, DOWNLOAD_LIST_PATH) logger.info("core.descargas " + fichero + " borrado") except: logger.info("core.descargas ERROR EN DESCARGA DE " + fichero) import sys for line in sys.exc_info(): logger.error("%s" % line) if not usingsamba: origen = os.path.join(DOWNLOAD_LIST_PATH, fichero) destino = os.path.join(ERROR_PATH, fichero) import shutil shutil.move(origen, destino) else: favoritos.savebookmark(canal, titulo, url, thumbnail, server, plot, fulltitle, ERROR_PATH) favoritos.deletebookmark(fichero, DOWNLOAD_LIST_PATH) if config.is_xbmc(): import xbmc xbmc.executebuiltin("XBMC.Container.Refresh()")
def set_content(content_type, silent=False): """ Procedimiento para auto-configurar la biblioteca de kodi con los valores por defecto @type content_type: str ('CINE' o 'SERIES') @param content_type: tipo de contenido para configurar, series o peliculas """ if config.is_xbmc(): continuar = True msg_text = "" librarypath = config.get_setting("librarypath") if content_type == 'CINE': if not xbmc.getCondVisibility( 'System.HasAddon(metadata.themoviedb.org)'): if not silent: # Preguntar si queremos instalar metadata.themoviedb.org install = platformtools.dialog_yesno( "The Movie Database", "No se ha encontrado el Scraper de películas de TheMovieDB.", "¿Desea instalarlo ahora?") else: install = True if install: try: # Instalar metadata.themoviedb.org xbmc.executebuiltin( 'xbmc.installaddon(metadata.themoviedb.org)', True) logger.info( "Instalado el Scraper de películas de TheMovieDB") except: pass continuar = (install and xbmc.getCondVisibility( 'System.HasAddon(metadata.themoviedb.org)')) if not continuar: msg_text = "The Movie Database no instalado." else: # SERIES # Instalar The TVDB if not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvdb.com)'): if not silent: # Preguntar si queremos instalar metadata.tvdb.com install = platformtools.dialog_yesno( "The TVDB", "No se ha encontrado el Scraper de series de The TVDB.", "¿Desea instalarlo ahora?") else: install = True if install: try: # Instalar metadata.tvdb.com xbmc.executebuiltin( 'xbmc.installaddon(metadata.tvdb.com)', True) logger.info( "Instalado el Scraper de series de The TVDB") except: pass continuar = (install and xbmc.getCondVisibility( 'System.HasAddon(metadata.tvdb.com)')) if not continuar: msg_text = "The TVDB no instalado." # Instalar TheMovieDB if continuar and not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvshows.themoviedb.org)'): continuar = False if not silent: # Preguntar si queremos instalar metadata.tvshows.themoviedb.org install = platformtools.dialog_yesno( "The Movie Database", "No se ha encontrado el Scraper de series de TheMovieDB.", "¿Desea instalarlo ahora?") else: install = True if install: try: # Instalar metadata.tvshows.themoviedb.org # 1º Probar desde el repositorio ... xbmc.executebuiltin( 'xbmc.installaddon(metadata.tvshows.themoviedb.org)', True) if not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvshows.themoviedb.org)' ): # ...si no funciona descargar e instalar desde la web url = "http://mirrors.kodi.tv/addons/jarvis/metadata.tvshows.themoviedb.org/metadata.tvshows.themoviedb.org-1.3.1.zip" path_down = xbmc.translatePath( "special://home/addons/packages/metadata.tvshows.themoviedb.org-1.3.1.zip" ) path_unzip = xbmc.translatePath( "special://home/addons/") header = ( "User-Agent", "Kodi/15.2 (Windows NT 10.0; WOW64) App_Bitness/32 Version/15.2-Git:20151019-02e7013" ) from core import downloadtools from core import ziptools downloadtools.downloadfile(url, path_down, continuar=True, headers=[header]) unzipper = ziptools.ziptools() unzipper.extract(path_down, path_unzip) xbmc.executebuiltin('UpdateLocalAddons') strSettings = '<settings>\n' \ ' <setting id="fanart" value="true" />\n' \ ' <setting id="keeporiginaltitle" value="false" />\n' \ ' <setting id="language" value="es" />\n' \ '</settings>' path_settings = xbmc.translatePath( "special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml" ) tv_themoviedb_addon_path = filetools.dirname( path_settings) if not filetools.exists(tv_themoviedb_addon_path): filetools.mkdir(tv_themoviedb_addon_path) if filetools.write(path_settings, strSettings): continuar = True except: pass continuar = (install and continuar) if not continuar: msg_text = "The Movie Database no instalado." idPath = 0 idParentPath = 0 if continuar: continuar = False # Buscamos el idPath sql = 'SELECT MAX(idPath) FROM path' nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idPath = records[0][0] + 1 sql_librarypath = librarypath if sql_librarypath.startswith("special://"): sql_librarypath = sql_librarypath.replace( '/profile/', '/%/').replace('/home/userdata/', '/%/') sep = '/' elif sql_librarypath.startswith("smb://"): sep = '/' else: sep = os.sep if not sql_librarypath.endswith(sep): sql_librarypath += sep # Buscamos el idParentPath sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_librarypath nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idParentPath = records[0][0] librarypath = records[0][1][:-1] continuar = True else: # No existe librarypath en la BD: la insertamos sql_librarypath = librarypath if not sql_librarypath.endswith(sep): sql_librarypath += sep sql = 'INSERT INTO path (idPath, strPath, scanRecursive, useFolderNames, noUpdate, exclude) VALUES ' \ '(%s, "%s", 0, 0, 0, 0)' % (idPath, sql_librarypath) nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True idParentPath = idPath idPath += 1 else: msg_text = "Error al fijar librarypath en BD" if continuar: continuar = False # Fijamos strContent, strScraper, scanRecursive y strSettings if content_type == 'CINE': strContent = 'movies' strScraper = 'metadata.themoviedb.org' scanRecursive = 2147483647 strSettings = "<settings><setting id='RatingS' value='TMDb' /><setting id='certprefix' value='Rated ' />" \ "<setting id='fanart' value='true' /><setting id='keeporiginaltitle' value='false' />" \ "<setting id='language' value='es' /><setting id='tmdbcertcountry' value='us' />" \ "<setting id='trailer' value='true' /></settings>" strActualizar = "¿Desea configurar este Scraper en español como opción por defecto para películas?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting( "folder_movies") + sep else: strContent = 'tvshows' strScraper = 'metadata.tvdb.com' scanRecursive = 0 strSettings = "<settings><setting id='RatingS' value='TheTVDB' />" \ "<setting id='absolutenumber' value='false' />" \ "<setting id='dvdorder' value='false' />" \ "<setting id='fallback' value='true' />" \ "<setting id='fanart' value='true' />" \ "<setting id='language' value='es' /></settings>" strActualizar = "¿Desea configurar este Scraper en español como opción por defecto para series?" if not librarypath.endswith(sep): librarypath += sep strPath = librarypath + config.get_setting( "folder_tvshows") + sep logger.info("%s: %s" % (content_type, strPath)) # Comprobamos si ya existe strPath en la BD para evitar duplicados sql = 'SELECT idPath FROM path where strPath="%s"' % strPath nun_records, records = execute_sql_kodi(sql) sql = "" if nun_records == 0: # Insertamos el scraper sql = 'INSERT INTO path (idPath, strPath, strContent, strScraper, scanRecursive, useFolderNames, ' \ 'strSettings, noUpdate, exclude, idParentPath) VALUES (%s, "%s", "%s", "%s", %s, 0, ' \ '"%s", 0, 0, %s)' % ( idPath, strPath, strContent, strScraper, scanRecursive, strSettings, idParentPath) else: if not silent: # Preguntar si queremos configurar themoviedb.org como opcion por defecto actualizar = platformtools.dialog_yesno( "The TVDB", strActualizar) else: actualizar = True if actualizar: # Actualizamos el scraper idPath = records[0][0] sql = 'UPDATE path SET strContent="%s", strScraper="%s", scanRecursive=%s, strSettings="%s" ' \ 'WHERE idPath=%s' % (strContent, strScraper, scanRecursive, strSettings, idPath) if sql: nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True if not continuar: msg_text = "Error al configurar el scraper en la BD." if not continuar: heading = "Biblioteca %s no configurada" % content_type elif content_type == 'SERIES' and not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvshows.themoviedb.org)'): heading = "Biblioteca %s configurada" % content_type msg_text = "Es necesario reiniciar Kodi para que los cambios surtan efecto." else: heading = "Biblioteca %s configurada" % content_type msg_text = "Felicidades la biblioteca de Kodi ha sido configurada correctamente." platformtools.dialog_notification(heading, msg_text, icon=1, time=10000) logger.info("%s: %s" % (heading, msg_text))
def do_search(item): logger.info("streamondemand.channels.saghe do_search") tecleado = item.extra mostra = item.fulltitle itemlist = [] channels_path = os.path.join(config.get_runtime_path(), "channels", '*.xml') logger.info("streamondemand.channels.buscador channels_path=" + channels_path) channel_language = config.get_setting("channel_language") logger.info("streamondemand.channels.buscador channel_language=" + channel_language) if channel_language == "": channel_language = "all" logger.info("streamondemand.channels.buscador channel_language=" + channel_language) if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create("Ricerca di " + mostra) except: show_dialog = False def worker(infile, queue): channel_result_itemlist = [] try: basename_without_extension = os.path.basename(infile)[:-4] # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile[:-4] + ".py") logger.info("streamondemand.channels.buscador cargado " + basename_without_extension + " de " + infile) channel_result_itemlist.extend(obj.search(Item(), tecleado)) for item in channel_result_itemlist: item.title = " [COLOR azure] " + item.title + " [/COLOR] [COLOR orange]su[/COLOR] [COLOR green]" + basename_without_extension + "[/COLOR]" item.viewmode = "list" except: import traceback logger.error(traceback.format_exc()) queue.put(channel_result_itemlist) channel_files = glob.glob(channels_path) channel_files_tmp = [] for infile in channel_files: basename_without_extension = os.path.basename(infile)[:-4] channel_parameters = channeltools.get_channel_parameters( basename_without_extension) # No busca si es un canal inactivo if channel_parameters["active"] != "true": continue # No busca si es un canal para adultos, y el modo adulto está desactivado if channel_parameters["adult"] == "true" and config.get_setting( "adult_mode") == "false": continue # No busca si el canal es en un idioma filtrado if channel_language != "all" and channel_parameters[ "language"] != channel_language: continue # No busca si es un canal excluido de la busqueda global include_in_global_search = channel_parameters[ "include_in_global_search"] if include_in_global_search == "": # Buscar en la configuracion del canal include_in_global_search = str( config.get_setting("include_in_global_search", basename_without_extension)) if include_in_global_search.lower() != "true": continue channel_files_tmp.append(infile) channel_files = channel_files_tmp result = Queue.Queue() threads = [ threading.Thread(target=worker, args=(infile, result)) for infile in channel_files ] for t in threads: t.start() number_of_channels = len(channel_files) for index, t in enumerate(threads): percentage = index * 100 / number_of_channels if show_dialog: progreso.update(percentage, ' Sto cercando "' + mostra + '"') t.join() itemlist.extend(result.get()) itemlist = sorted([ item for item in itemlist if fuzz.WRatio(mostra, item.fulltitle) > 85 ], key=lambda Item: Item.title) if show_dialog: progreso.close() return itemlist
def episodios(item): logger.info() itemlist = [] html_serie = get_url_contents(item.url) info_serie = __extract_info_from_serie(html_serie) plot = info_serie[3] if info_serie else '' episodes = re.findall(REGEX_EPISODE, html_serie, re.DOTALL) es_pelicula = False for url, title, date in episodes: episode = scrapertools.find_single_match(title, r'Episodio (\d+)') # El enlace pertenece a un episodio if episode: season = 1 episode = int(episode) if config.is_xbmc(): season, episode = renumbertools.numbered_for_tratk( item.channel, item.show, season, episode) title = "{0}x{1:02d} {2} ({3})".format(season, episode, "Episodio " + str(episode), date) # El enlace pertenece a una pelicula else: title = "{0} ({1})".format(title, date) item.url = url es_pelicula = True logger.debug("title=[{0}], url=[{1}], thumbnail=[{2}]".format( title, url, item.thumbnail)) itemlist.append( Item(channel=item.channel, action="findvideos", title=title, url=url, thumbnail=item.thumbnail, plot=plot, show=item.show, fulltitle="{0} {1}".format(item.show, title), viewmode="movies_with_plot", folder=True)) # El sistema soporta la biblioteca y se encontro por lo menos un episodio # o pelicula if config.get_library_support() and len(itemlist) > 0: if es_pelicula: item_title = "Añadir película a la biblioteca" item_action = "add_pelicula_to_library" item_extra = "" else: item_title = "Añadir serie a la biblioteca" item_action = "add_serie_to_library" item_extra = "episodios" itemlist.append( Item(channel=item.channel, title=item_title, url=item.url, action=item_action, extra=item_extra, show=item.show)) if not es_pelicula: itemlist.append( Item(channel=item.channel, title="Descargar todos los episodios", url=item.url, action="download_all_episodes", extra="episodios", show=item.show)) return itemlist
def do_search(item): logger.info("pelisalacarta.channels.buscador do_search") tecleado = item.extra itemlist = [] import os import glob import imp master_exclude_data_file = os.path.join(config.get_runtime_path(), "resources", "global_search_exclusion.txt") logger.info("pelisalacarta.channels.buscador master_exclude_data_file=" + master_exclude_data_file) exclude_data_file = os.path.join(config.get_data_path(), "global_search_exclusion.txt") logger.info("pelisalacarta.channels.buscador exclude_data_file=" + exclude_data_file) channels_path = os.path.join(config.get_runtime_path(), "channels", '*.py') logger.info("pelisalacarta.channels.buscador channels_path=" + channels_path) excluir = "" # El fichero que se distribuyó en la 4.0.2 no era completo ''' if os.path.exists(exclude_data_file): fileexclude = open(exclude_data_file,"r") excluir= fileexclude.read() fileexclude.close() else: excluir = "seriesly\n" fileexclude = open(exclude_data_file,"w") fileexclude.write(excluir) fileexclude.close() ''' if os.path.exists(master_exclude_data_file): logger.info( "pelisalacarta.channels.buscador Encontrado fichero exclusiones") fileexclude = open(master_exclude_data_file, "r") excluir = fileexclude.read() fileexclude.close() else: logger.info( "pelisalacarta.channels.buscador No encontrado fichero exclusiones" ) excluir = "seriesly\nbuscador\ntengourl\n__init__" if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create("Buscando " + tecleado.title()) except: show_dialog = False channel_files = glob.glob(channels_path) number_of_channels = len(channel_files) for index, infile in enumerate(channel_files): percentage = index * 100 / number_of_channels basename = os.path.basename(infile) basename_without_extension = basename[:-3] if basename_without_extension not in excluir: if show_dialog: progreso.update(percentage, ' Buscando "' + tecleado + '"', basename_without_extension) logger.info( "pelisalacarta.channels.buscador Intentado busqueda en " + basename_without_extension + " de " + tecleado) try: # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile) logger.info("pelisalacarta.channels.buscador cargado " + basename_without_extension + " de " + infile) channel_result_itemlist = obj.search(Item(), tecleado) for item in channel_result_itemlist: item.title = item.title + "[" + basename_without_extension + "]" item.viewmode = "list" itemlist.extend(channel_result_itemlist) except: import traceback logger.error(traceback.format_exc()) else: logger.info( "pelisalacarta.channels.buscador do_search_results, Excluido server " + basename_without_extension) itemlist = sorted(itemlist, key=lambda Item: Item.title) if show_dialog: progreso.close() return itemlist
def mainlist(item): logger.info() itemlist = [] if config.is_xbmc(): itemlist.append( Item(channel=item.channel, action="", title="FAQ:", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False)) itemlist.append( Item(channel=item.channel, action="faq", title=" - ¿Se pueden filtrar los enlaces?", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="filtrar_enlaces")) itemlist.append( Item(channel=item.channel, action="faq", title=" - ¿Se pueden activar/desactivar los canales?", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="onoff_canales")) itemlist.append( Item(channel=item.channel, action="faq", title= " - ¿Es posible la sincronización automática con Trakt?", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="trakt_sync")) itemlist.append( Item( channel=item.channel, action="faq", title= " - ¿Es posible mostrar todos los resultados juntos en el buscador global?", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="buscador_juntos")) itemlist.append( Item(channel=item.channel, action="faq", title=" - Los enlaces tardan en aparecer.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="tiempo_enlaces")) itemlist.append( Item(channel=item.channel, action="faq", title= " - La búsqueda de contenido no se hace correctamente.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="prob_busquedacont")) itemlist.append( Item(channel=item.channel, action="faq", title=" - Algún canal no funciona correctamente.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="canal_fallo")) itemlist.append( Item(channel=item.channel, action="faq", title=" - Los enlaces Torrent no funcionan.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="prob_torrent")) itemlist.append( Item(channel=item.channel, action="faq", title=" - No se actualiza correctamente la biblioteca.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=True, extra="prob_bib")) itemlist.append( Item(channel="ayuda", action="faq", title=" - Aparece un error al pulsar sobre un episodio.", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=True, extra="prob_bib")) itemlist.append( Item(channel="ayuda", action="faq", title=" - Otros", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, extra="")) itemlist.append( Item(channel=item.channel, title="Videotutoriales:", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False, action="")) itemlist.extend(tutoriales(item)) if config.is_xbmc(): itemlist.append( Item(channel=item.channel, action="force_creation_advancedsettings", title="Optimizar fichero advancedsettings.xml", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False)) itemlist.append( Item(channel=item.channel, action="recover_advancedsettings", title="Restaurar advancedsettings.xml del backup", thumbnail=get_thumbnail_path("thumb_ayuda.png"), folder=False)) if not config.is_xbmc(): from core import channeltools title = "Activar cuenta real-debrid (No activada)" action = "realdebrid" token_auth = config.get_setting("token", server="realdebrid") if not config.get_setting("premium", server="realdebrid"): title = "Activar cuenta real-debrid (Marca la casilla en la ventana de configuración de pelisalacarta para continuar)" action = "" elif token_auth: title = "Activar cuenta real-debrid (Activada correctamente)" itemlist.append(Item(channel="ayuda", action=action, title=title)) return itemlist
def fichas(item): logger.info() itemlist = [] data = httptools.downloadpage(item.url).data # data = re.sub(r"\n|\r|\t|\s{2}|-\s", "", data) fichas_marca = {'1': 'Siguiendo', '2': 'Pendiente', '3': 'Favorita', '4': 'Vista', '5': 'Abandonada'} patron = '<div class="c_fichas_image".*?href="\.([^"]+)".*?src-data="\.([^"]+)".*?' \ '<div class="c_fichas_data".*?marked="([^"]*)".*?serie="([^"]*)".*?' \ '<div class="c_fichas_title">(?:<div class="c_fichas_episode">([^<]+)</div>|)([^<]+)</div>' matches = scrapertools.find_multiple_matches(data, patron) for scrapedurl, scrapedthumbnail, marca, serie, episodio, scrapedtitle in matches: tipo = "movie" scrapedurl = host + scrapedurl.rsplit("-dc=")[0] if not "-dc=" in scrapedurl: scrapedurl += "-dc=" scrapedthumbnail = host + scrapedthumbnail action = "findvideos" if __menu_info__: action = "menu_info" if serie: tipo = "tvshow" if episodio: title = "%s - %s" % (episodio.replace("X", "x"), scrapedtitle) else: title = scrapedtitle if marca: title += " [COLOR %s][%s][/COLOR]" % (color4, fichas_marca[marca]) new_item = Item(channel=item.channel, action=action, title=title, url=scrapedurl, thumbnail=scrapedthumbnail, contentTitle=scrapedtitle, contentType=tipo, text_color=color2) if new_item.contentType == "tvshow": new_item.show = scrapedtitle if not __menu_info__: new_item.action = "episodios" itemlist.append(new_item) if itemlist and (item.extra == "listas_plus" or item.extra == "sigo"): follow = scrapertools.find_single_match(data, '<div onclick="seguir_lista.*?>(.*?)<') title = "Seguir Lista" if follow == "Siguiendo": title = "Dejar de seguir lista" item.extra = "" url = host + "/data.php?mode=seguir_lista&apikey=%s&sid=%s&lista=%s" % ( apikey, sid, item.url.rsplit("/l", 1)[1]) itemlist.insert(0, item.clone(action="acciones_cuenta", title=title, url=url, text_color=color4, lista=item.title, folder=False)) next_page = scrapertools.find_single_match(data, 'href="([^"]+)" class="next"') if next_page: next_page = host + next_page.replace("&", "&") itemlist.append(Item(channel=item.channel, action="fichas", title=">> Página Siguiente", url=next_page)) try: total = int(scrapertools.find_single_match(data, '<span class="page-dots">.*href.*?>(\d+)')) except: total = 0 if not config.get_setting("last_page", item.channel) and config.is_xbmc() and total > 2 \ and item.extra != "newest": itemlist.append(item.clone(action="select_page", title="Ir a página... (Total:%s)" % total, url=next_page, text_color=color5)) return itemlist
def episodios(item): logger.info("tvalacarta.channels.clantv episodios") itemlist = [] # Descarga la página url = item.url + "/videos.json" data = scrapertools.cache_page(url) json_object = jsontools.load_json(data) #logger.info("json_object="+json_object) json_items = json_object["page"]["items"] for json_item in json_items: title = json_item["longTitle"] url = json_item["uri"] thumbnail = json_item["imageSEO"] if json_item["description"] is not None: plot = scrapertools.htmlclean(json_item["description"]) else: plot = "" fanart = item.fanart page = json_item["htmlUrl"] aired_date = scrapertools.parse_date(json_item["publicationDate"]) ms = json_item["duration"] if ms is None: duration = "" else: x = ms / 1000 seconds = x % 60 x /= 60 minutes = x % 60 x /= 60 hours = x % 24 if hours > 0: duration = str(hours) + ":" + str(minutes) + ":" + str(seconds) else: duration = str(minutes) + ":" + str(seconds) if (DEBUG): logger.info(" title=[" + repr(title) + "], url=[" + repr(url) + "], thumbnail=[" + repr(thumbnail) + "] plot=[" + repr(plot) + "]") itemlist.append( Item(channel="rtve", title=title, action="play", server="rtve", page=page, url=url, thumbnail=thumbnail, fanart=thumbnail, show=item.show, plot=plot, duration=duration, aired_date=aired_date, viewmode="movie_with_plot", folder=False)) from core import config if config.is_xbmc() and len(itemlist) > 0: itemlist.append( Item(channel=item.channel, title=">> Opciones para esta serie", url=item.url, action="serie_options##episodios", thumbnail=item.thumbnail, show=item.show, folder=False)) return itemlist
def findvideos(item): logger.info() itemlist = [] item.text_color = color3 data = scrapertools.downloadpage(item.url) data = scrapertools.decodeHtmlentities(data) #Busca en la seccion descarga/torrent data_download = scrapertools.find_single_match( data, '<th>Episodio - Enlaces de Descarga</th>(.*?)</table>') patron = '<p class="item_name".*?<a href="([^"]+)".*?>([^"]+)</a>' matches = scrapertools.find_multiple_matches(data_download, patron) for scrapedurl, scrapedepi in matches: new_item = item.clone() if "Episodio" not in scrapedepi: scrapedtitle = "[Torrent] Episodio " + scrapedepi else: scrapedtitle = "[Torrent] " + scrapedepi scrapedtitle = scrapertools.htmlclean(scrapedtitle) new_item.infoLabels['episode'] = scrapertools.find_single_match( scrapedtitle, "Episodio (\d+)") logger.debug("title=[" + scrapedtitle + "], url=[" + scrapedurl + "]") itemlist.append( new_item.clone(action="play", title=scrapedtitle, url=scrapedurl, server="torrent", contentType="episode")) #Busca en la seccion online data_online = scrapertools.find_single_match( data, "<th>Enlaces de Visionado Online</th>(.*?)</table>") patron = '<a href="([^"]+)\\n.*?src="([^"]+)".*?' \ 'title="Enlace de Visionado Online">([^"]+)</a>' matches = scrapertools.find_multiple_matches(data_online, patron) for scrapedurl, scrapedthumb, scrapedtitle in matches: #Deshecha enlaces de trailers scrapedtitle = scrapertools.htmlclean(scrapedtitle) if (scrapedthumb != "images/series/youtube.png") & (scrapedtitle != "Trailer"): new_item = item.clone() server = scrapertools.find_single_match(scrapedthumb, "images/series/(.*?).png") title = "[" + server.capitalize() + "]" + " " + scrapedtitle new_item.infoLabels['episode'] = scrapertools.find_single_match( scrapedtitle, "Episodio (\d+)") itemlist.append( new_item.clone(action="play", title=title, url=scrapedurl, contentType="episode")) #Comprueba si hay otras temporadas if not "No hay disponible ninguna Temporada adicional" in data: data_temp = scrapertools.find_single_match( data, '<div class="panel panel-success">(.*?)</table>') data_temp = re.sub(r"\n|\r|\t|\s{2}| ", "", data_temp) patron = '<tr><td><p class="item_name"><a href="([^"]+)".*?' \ '<p class="text-success"><strong>([^"]+)</strong>' matches = scrapertools.find_multiple_matches(data_temp, patron) for scrapedurl, scrapedtitle in matches: new_item = item.clone() url = urlparse.urljoin(URL_BASE, scrapedurl) scrapedtitle = scrapedtitle.capitalize() temporada = scrapertools.find_single_match(scrapedtitle, "Temporada (\d+)") if temporada != "": new_item.infoLabels['season'] = temporada new_item.infoLabels['episode'] = "" itemlist.append( new_item.clone(action="findvideos", title=scrapedtitle, url=url, text_color="red", contentType="season")) try: from core import tmdb tmdb.set_infoLabels_itemlist(itemlist, __modo_grafico__) except: pass new_item = item.clone() if config.is_xbmc(): new_item.contextual = True itemlist.append( new_item.clone(channel="trailertools", title="Buscar Tráiler", action="buscartrailer", context="", text_color="magenta")) return itemlist
def do_search(item): logger.info("pelisalacarta.channels.buscador do_search") tecleado = item.extra itemlist = [] import os import glob import imp channels_path = os.path.join(config.get_runtime_path(), "channels", '*.xml') logger.info("pelisalacarta.channels.buscador channels_path=" + channels_path) channel_language = config.get_setting("channel_language") logger.info("pelisalacarta.channels.buscador channel_language=" + channel_language) if channel_language == "": channel_language = "all" logger.info("pelisalacarta.channels.buscador channel_language=" + channel_language) show_dialog = False progreso = None if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create("Buscando " + tecleado.title()) except ImportError: xbmcgui = None show_dialog = False channel_files = glob.glob(channels_path) number_of_channels = len(channel_files) for index, infile in enumerate(channel_files): percentage = index * 100 / number_of_channels basename = os.path.basename(infile) basename_without_extension = basename[:-4] channel_parameters = channeltools.get_channel_parameters( basename_without_extension) # No busca si es un canal inactivo if channel_parameters["active"] != "true": continue # No busca si es un canal excluido de la busqueda global if channel_parameters["include_in_global_search"] != "true": continue # No busca si es un canal para adultos, y el modo adulto está desactivado if channel_parameters["adult"] == "true" and config.get_setting( "adult_mode") == "false": continue # No busca si el canal es en un idioma filtrado if channel_language != "all" and channel_parameters[ "language"] != channel_language: continue if show_dialog: progreso.update(percentage, ' Buscando "' + tecleado + '"', basename_without_extension) logger.info("pelisalacarta.channels.buscador Intentado busqueda en " + basename_without_extension + " de " + tecleado) try: # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile[:-4] + ".py") logger.info("pelisalacarta.channels.buscador cargado " + basename_without_extension + " de " + infile) channel_result_itemlist = obj.search(Item(), tecleado) for item in channel_result_itemlist: item.title = item.title + "[" + basename_without_extension + "]" item.viewmode = "list" itemlist.extend(channel_result_itemlist) except: import traceback logger.error(traceback.format_exc()) itemlist = sorted(itemlist, key=lambda Item: Item.title) if show_dialog: progreso.close() return itemlist
def do_channels_search(item): logger.info("streamondemand-pureita-master.channels.biblioteca do_channels_search") try: title_year = int(item.extra[0:4]) except: title_year = 0 mostra = item.extra[4:] tecleado = urllib.quote_plus(mostra) itemlist = [] channels_path = os.path.join(config.get_runtime_path(), "channels", '*.xml') logger.info("streamondemand-pureita-master.channels.buscador channels_path=" + channels_path) channel_language = config.get_setting("channel_language") logger.info("streamondemand-pureita-master.channels.buscador channel_language=" + channel_language) if channel_language == "": channel_language = "all" logger.info("streamondemand-pureita-master.channels.buscador channel_language=" + channel_language) if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create(NLS_Looking_For % mostra) except: show_dialog = False def worker(infile, queue): channel_result_itemlist = [] try: basename_without_extension = os.path.basename(infile)[:-4] # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile[:-4]+".py") logger.info("streamondemand-pureita-master.channels.buscador cargado " + basename_without_extension + " de " + infile) # item.url contains search type: serie, anime, etc... channel_result_itemlist.extend(obj.search(Item(extra=item.url), tecleado)) for local_item in channel_result_itemlist: local_item.title = " [COLOR azure] " + local_item.title + " [/COLOR] [COLOR orange]su[/COLOR] [COLOR green]" + basename_without_extension + "[/COLOR]" local_item.viewmode = "list" except: import traceback logger.error(traceback.format_exc()) queue.put(channel_result_itemlist) channel_files = glob.glob(channels_path) channel_files_tmp = [] for infile in channel_files: basename_without_extension = os.path.basename(infile)[:-4] channel_parameters = channeltools.get_channel_parameters(basename_without_extension) # No busca si es un canal inactivo if channel_parameters["active"] != "true": continue # No busca si es un canal excluido de la busqueda global if channel_parameters["include_in_global_search"] != "true": continue # No busca si es un canal para adultos, y el modo adulto está desactivado if channel_parameters["adult"] == "true" and config.get_setting("adult_mode") == "false": continue # No busca si el canal es en un idioma filtrado if channel_language != "all" and channel_parameters["language"] != channel_language: continue channel_files_tmp.append(infile) channel_files = channel_files_tmp result = Queue.Queue() threads = [threading.Thread(target=worker, args=(infile, result)) for infile in channel_files] start_time = int(time.time()) for t in threads: t.daemon = True # NOTE: setting dameon to True allows the main thread to exit even if there are threads still running t.start() number_of_channels = len(channel_files) completed_channels = 0 while completed_channels < number_of_channels: delta_time = int(time.time()) - start_time if len(itemlist) <= 0: timeout = None # No result so far,lets the thread to continue working until a result is returned elif delta_time >= TIMEOUT_TOTAL: break # At least a result matching the searched title has been found, lets stop the search else: timeout = TIMEOUT_TOTAL - delta_time # Still time to gather other results if show_dialog: progreso.update(completed_channels * 100 / number_of_channels) try: result_itemlist = result.get(timeout=timeout) completed_channels += 1 except: # Expired timeout raise an exception break for item in result_itemlist: title = item.fulltitle # If the release year is known, check if it matches the year found in the title if title_year > 0: year_match = re.search('\(.*(\d{4}).*\)', title) if year_match and abs(int(year_match.group(1)) - title_year) > 1: continue # Clean up a bit the returned title to improve the fuzzy matching title = re.sub(r'\(.*\)', '', title) # Anything within () title = re.sub(r'\[.*\]', '', title) # Anything within [] # Check if the found title fuzzy matches the searched one if fuzz.token_sort_ratio(mostra, title) > 85: itemlist.append(item) if show_dialog: progreso.close() itemlist = sorted(itemlist, key=lambda item: item.fulltitle) return itemlist
def check_for_update(overwrite=True): logger.info("Aggiornamento series...") p_dialog = None serie_actualizada = False update_when_finished = False hoy = datetime.date.today() try: if config.get_setting("updatelibrary", "biblioteca") != 0 or overwrite: config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "biblioteca") heading = 'Aggiornamento della libreria...' p_dialog = platformtools.dialog_progress_bg('streamondemand', heading) p_dialog.update(0, '') import glob show_list = glob.glob(filetools.join(library.TVSHOWS_PATH, u'/*/tvshow.nfo')) if show_list: t = float(100) / len(show_list) for i, tvshow_file in enumerate(show_list): head_nfo, serie = library.read_nfo(tvshow_file) path = filetools.dirname(tvshow_file) logger.info("serie=" + serie.contentSerieName) p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName) interval = int(serie.active) # Can be bool type if not serie.active: # Unload if the Serie is not active continue # Update next update_next = serie.update_next if update_next: y, m, d = update_next.split('-') update_next = datetime.date(int(y), int(m), int(d)) else: update_next = hoy update_last = serie.update_last if update_last: y, m, d = update_last.split('-') update_last = datetime.date(int(y), int(m), int(d)) else: update_last = hoy # if the Serie is active ... if overwrite or config.get_setting("updatetvshows_interval", "biblioteca") == 0: # ... force autonomus update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) elif interval == 1 and update_next <= hoy: # ...weekly update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada and update_last <= hoy - datetime.timedelta(days=7): # raise the interval interval = 7 update_next = hoy + datetime.timedelta(days=interval) elif interval == 7 and update_next <= hoy: # ...14days update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: if update_last <= hoy - datetime.timedelta(days=14): # raise the interval interval = 30 update_next += datetime.timedelta(days=interval) elif interval == 30 and update_next <= hoy: # ...monthly update serie_actualizada = update(path, p_dialog, i, t, serie, overwrite) if not serie_actualizada: update_next += datetime.timedelta(days=interval) if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next: serie.active = interval serie.update_next = update_next.strftime('%Y-%m-%d') serie.channel = "biblioteca" serie.action = "get_temporadas" filetools.write(tvshow_file, head_nfo + serie.tojson()) if serie_actualizada: if config.get_setting("search_new_content", "biblioteca") == 0: # Update Kodi library: Search contents in the Serie directory if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(folder=filetools.basename(path)) else: update_when_finished = True if config.get_setting("search_new_content", "biblioteca") == 1 and update_when_finished: # Update Kodi library: Search contents for every Serie if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update() p_dialog.close() else: logger.info("Libreria non aggiornata, opzione disattiva nella configurazione di streamondemand") except Exception as ex: logger.error("Si è verificato un errore nell'aggiornamento") 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()
# Lista de vídeos favoritos # ------------------------------------------------------------ import os import time from core import scrapertools from core import config from core import filetools from core import logger from core.item import Item from platformcode import platformtools # Fijamos la ruta a favourites.xml if config.is_xbmc(): import xbmc FAVOURITES_PATH = xbmc.translatePath( "special://home/userdata/favourites.xml") else: FAVOURITES_PATH = os.path.join(config.get_data_path(), "favourites.xml") def mainlist(item): logger.info("streamondemand.channels.favoritos mainlist") itemlist = [] #bookmarkpath = config.get_setting("bookmarkpath") #TODO si solo se usa para esto podriamos eliminarlo for name, thumb, data in read_favourites(): if "plugin://plugin.video.%s/?" % config.PLUGIN_NAME in data: url = scrapertools.find_single_match(data, 'plugin://plugin.video.%s/\?([^;]*)' % config.PLUGIN_NAME)\
def convert_old_to_v4(): logger.info() path_series_xml = filetools.join(config.get_data_path(), "series.xml") path_series_json = filetools.join(config.get_data_path(), "series.json") series_insertadas = 0 series_fallidas = 0 version = 'v?' # Rename and create Series directory import time new_name = str(time.time()) path_series_old = filetools.join(library.LIBRARY_PATH, "SERIES_OLD_" + new_name) if filetools.rename(library.TVSHOWS_PATH, "SERIES_OLD_" + new_name): if not filetools.mkdir(library.TVSHOWS_PATH): logger.error("ERROR, impossibile creare la directory SERIES") return False else: logger.error("ERROR,impossibile rinominare la directory SERIES") return False path_cine_old = filetools.join(library.LIBRARY_PATH, "CINE_OLD_" + new_name) if filetools.rename(library.MOVIES_PATH, "CINE_OLD_" + new_name): if not filetools.mkdir(library.MOVIES_PATH): logger.error("ERROR, impossibile creare la directory CINE") return False else: logger.error("ERROR, impossibile rinominare la directory CINE") return False # Convert library from v1 to v4 (xml) if filetools.exists(path_series_xml): try: data = filetools.read(path_series_xml) for line in data.splitlines(): try: aux = line.rstrip('\n').split(",") tvshow = aux[0].strip() url = aux[1].strip() channel = aux[2].strip() serie = Item(contentSerieName=tvshow, url=url, channel=channel, action="episodios", title=tvshow, active=True) patron = "^(.+)[\s]\((\d{4})\)$" matches = re.compile(patron, re.DOTALL).findall(serie.contentSerieName) if matches: serie.infoLabels['title'] = matches[0][0] serie.infoLabels['year'] = matches[0][1] else: serie.infoLabels['title'] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie aggiornata", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_xml, "series.xml.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_xml) return False # Convert library from v2 to v4 (json) if filetools.exists(path_series_json): try: data = jsontools.load_json(filetools.read(path_series_json)) for tvshow in data: for channel in data[tvshow]["channels"]: try: serie = Item(contentSerieName=data[tvshow]["channels"][channel]["tvshow"], url=data[tvshow]["channels"][channel]["url"], channel=channel, action="episodios", title=data[tvshow]["name"], active=True) if not tvshow.startswith("t_"): serie.infoLabels["tmdb_id"] = tvshow insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie aggiornata", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 filetools.rename(path_series_json, "series.json.old") version = 'v4' except EnvironmentError: logger.error("ERROR al leer el archivo: %s" % path_series_json) return False # Convert library from v2 to v4 if version != 'v4': # Get old Series recursively for raiz, subcarpetas, ficheros in filetools.walk(path_series_old): for f in ficheros: if f == "tvshow.json": try: serie = Item().fromjson(filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_tvshow(serie, list()) if fallidos == 0: series_insertadas += 1 platformtools.dialog_notification("Serie aggiornata", serie.infoLabels['title']) else: series_fallidas += 1 except: series_fallidas += 1 movies_insertadas = 0 movies_fallidas = 0 for raiz, subcarpetas, ficheros in filetools.walk(path_cine_old): for f in ficheros: if f.endswith(".strm.json"): try: movie = Item().fromjson(filetools.read(filetools.join(raiz, f))) insertados, sobreescritos, fallidos = library.save_library_movie(movie) if fallidos == 0: movies_insertadas += 1 platformtools.dialog_notification("Film aggiornato", movie.infoLabels['title']) else: movies_fallidas += 1 except: movies_fallidas += 1 config.set_setting("library_version", 'v4') platformtools.dialog_notification("Libreria aggiornata con il nuovo formato", "%s serie convertite e %s serie scaricate. Continuare per" "ottenere le info sugli episodi" % (series_insertadas, series_fallidas), time=12000) # Cleanup library of empty records if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.clean() return True
from core import logger from core import scrapertools from core import servertools from core.item import Item from channels import filtertools HOST = 'http://seriesdanko.com/' IDIOMAS = {'es': 'Español', 'la': 'Latino', 'vos': 'VOS', 'vo': 'VO'} list_idiomas = [v for v in IDIOMAS.values()] CALIDADES = ['SD', 'MicroHD', 'HD/MKV'] ''' configuración para mostrar la opción de filtro, actualmente sólo se permite en xbmc, se cambiará cuando 'platformtools.show_channel_settings' esté disponible para las distintas plataformas ''' OPCION_FILTRO = config.is_xbmc() CONTEXT = ("", "menu filtro")[OPCION_FILTRO] DEBUG = config.get_setting("debug") def mainlist(item): logger.info("pelisalacarta.seriesdanko mainlist") itemlist = list() itemlist.append( Item(channel=item.channel, title="Novedades", action="novedades", url=HOST)) itemlist.append( Item(channel=item.channel,
def do_search(item): logger.info("streamondemand.channels.buscador do_search") tecleado = item.extra mostra = tecleado.replace("+", " ") itemlist = [] import os import glob import imp from lib.fuzzywuzzy import fuzz import threading import Queue import time import re master_exclude_data_file = os.path.join(config.get_runtime_path(), "resources", "sodsearch.txt") logger.info("streamondemand.channels.buscador master_exclude_data_file=" + master_exclude_data_file) channels_path = os.path.join(config.get_runtime_path(), "channels", '*.py') logger.info("streamondemand.channels.buscador channels_path=" + channels_path) excluir = "" if os.path.exists(master_exclude_data_file): logger.info( "streamondemand.channels.buscador Encontrado fichero exclusiones") fileexclude = open(master_exclude_data_file, "r") excluir = fileexclude.read() fileexclude.close() else: logger.info( "streamondemand.channels.buscador No encontrado fichero exclusiones" ) excluir = "seriesly\nbuscador\ntengourl\n__init__" if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create("Ricerca di " + mostra.title()) except: show_dialog = False def worker(infile, queue): channel_result_itemlist = [] try: basename_without_extension = os.path.basename(infile)[:-3] # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile) logger.info("streamondemand.channels.buscador cargado " + basename_without_extension + " de " + infile) channel_result_itemlist.extend( obj.search(Item(extra=item.category), tecleado)) for local_item in channel_result_itemlist: local_item.title = " [COLOR azure] " + local_item.title + " [/COLOR] [COLOR orange]su[/COLOR] [COLOR green]" + basename_without_extension + "[/COLOR]" local_item.viewmode = "list" except: import traceback logger.error(traceback.format_exc()) queue.put(channel_result_itemlist) channel_files = [ infile for infile in glob.glob(channels_path) if os.path.basename(infile)[:-3] not in excluir ] result = Queue.Queue() threads = [ threading.Thread(target=worker, args=(infile, result)) for infile in channel_files ] start_time = int(time.time()) for t in threads: t.daemon = True # NOTE: setting dameon to True allows the main thread to exit even if there are threads still running t.start() number_of_channels = len(channel_files) completed_channels = 0 while completed_channels < number_of_channels: delta_time = int(time.time()) - start_time if len(itemlist) <= 0: timeout = None # No result so far,lets the thread to continue working until a result is returned elif delta_time >= TIMEOUT_TOTAL: break # At least a result matching the searched title has been found, lets stop the search else: timeout = TIMEOUT_TOTAL - delta_time # Still time to gather other results if show_dialog: progreso.update(completed_channels * 100 / number_of_channels) try: result_itemlist = result.get(timeout=timeout) completed_channels += 1 except: # Expired timeout raise an exception break for item in result_itemlist: title = item.fulltitle # Clean up a bit the returned title to improve the fuzzy matching title = re.sub(r'\(.*\)', '', title) # Anything within () title = re.sub(r'\[.*\]', '', title) # Anything within [] # Check if the found title fuzzy matches the searched one if fuzz.WRatio(mostra, title) > 85: itemlist.append(item) if show_dialog: progreso.close() itemlist = sorted(itemlist, key=lambda item: item.fulltitle) return itemlist
def get_video_url(page_url, premium=False, user="", password="", video_password=""): logger.info("(page_url='%s' , video_password=%s)" % (page_url, video_password)) # Se comprueba si existe un token guardado y sino se ejecuta el proceso de autentificación token_auth = config.get_setting("token", server="realdebrid") if token_auth is None or token_auth == "": if config.is_xbmc(): token_auth = authentication() if token_auth == "": return [[ "REAL-DEBRID: No se ha completado el proceso de autentificación", "" ]] else: return [[ "Es necesario activar la cuenta. Accede al menú de ayuda", "" ]] post_link = urllib.urlencode([("link", page_url), ("password", video_password)]) headers["Authorization"] = "Bearer %s" % token_auth url = "https://api.real-debrid.com/rest/1.0/unrestrict/link" data = scrapertools.downloadpage(url, post=post_link, headers=headers.items()) data = jsontools.load_json(data) # Si el token es erróneo o ha caducado, se solicita uno nuevo if "error" in data and data["error"] == "bad_token": debrid_id = config.get_setting("id", server="realdebrid") secret = config.get_setting("secret", server="realdebrid") refresh = config.get_setting("refresh", server="realdebrid") post_token = urllib.urlencode({ "client_id": debrid_id, "client_secret": secret, "code": refresh, "grant_type": "http://oauth.net/grant_type/device/1.0" }) renew_token = scrapertools.downloadpage( "https://api.real-debrid.com/oauth/v2/token", post=post_token, headers=headers.items()) renew_token = jsontools.load_json(renew_token) if not "error" in renew_token: token_auth = renew_token["access_token"] config.set_setting("token", token_auth, server="realdebrid") headers["Authorization"] = "Bearer %s" % token_auth data = scrapertools.downloadpage(url, post=post_link, headers=headers.items()) data = jsontools.load_json(data) if "download" in data: return get_enlaces(data) else: if "error" in data: msg = data["error"].decode("utf-8", "ignore") msg = msg.replace("hoster_unavailable", "Servidor no disponible") \ .replace("unavailable_file", "Archivo no disponible") \ .replace("hoster_not_free", "Servidor no gratuito") \ .replace("bad_token", "Error en el token") return [["REAL-DEBRID: " + msg, ""]] else: return [["REAL-DEBRID: No se ha generado ningún enlace", ""]]
def extract_videos(video_id): fmt_value = { 5: "240p h263 flv", 6: "240p h263 flv", 18: "360p h264 mp4", 22: "720p h264 mp4", 26: "???", 33: "???", 34: "360p h264 flv", 35: "480p h264 flv", 36: "3gpp", 37: "1080p h264 mp4", 38: "4K h264 mp4", 43: "360p vp8 webm", 44: "480p vp8 webm", 45: "720p vp8 webm", 46: "1080p vp8 webm", 59: "480p h264 mp4", 78: "480p h264 mp4", 82: "360p h264 3D", 83: "480p h264 3D", 84: "720p h264 3D", 85: "1080p h264 3D", 100: "360p vp8 3D", 101: "480p vp8 3D", 102: "720p vp8 3D" } url = 'http://www.youtube.com/get_video_info?video_id=%s&eurl=https://youtube.googleapis.com/v/%s&ssl_stream=1' % \ (video_id, video_id) data = httptools.downloadpage(url).data video_urls = [] params = dict(urlparse.parse_qsl(data)) if params.get('hlsvp'): video_urls.append(["(LIVE .m3u8) [youtube]", params['hlsvp']]) return video_urls if config.is_xbmc(): import xbmc xbmc_version = int( xbmc.getInfoLabel("System.BuildVersion").split(".", 1)[0]) if xbmc_version > 16 and xbmc.getCondVisibility('System.HasAddon(inputstream.adaptive)') \ and params.get('dashmpd'): if params.get('use_cipher_signature', '') != 'True': video_urls.append( ['mpd HD [youtube]', params['dashmpd'], 0, '', True]) js_signature = "" youtube_page_data = httptools.downloadpage( "http://www.youtube.com/watch?v=%s" % video_id).data params = extract_flashvars(youtube_page_data) if params.get('url_encoded_fmt_stream_map'): data_flashvars = params["url_encoded_fmt_stream_map"].split(",") for url_desc in data_flashvars: url_desc_map = dict(urlparse.parse_qsl(url_desc)) if not url_desc_map.get("url") and not url_desc_map.get("stream"): continue try: key = int(url_desc_map["itag"]) if not fmt_value.get(key): continue if url_desc_map.get("url"): url = urllib.unquote(url_desc_map["url"]) elif url_desc_map.get("conn") and url_desc_map.get("stream"): url = urllib.unquote(url_desc_map["conn"]) if url.rfind("/") < len(url) - 1: url += "/" url += urllib.unquote(url_desc_map["stream"]) elif url_desc_map.get( "stream") and not url_desc_map.get("conn"): url = urllib.unquote(url_desc_map["stream"]) if url_desc_map.get("sig"): url += "&signature=" + url_desc_map["sig"] elif url_desc_map.get("s"): sig = url_desc_map["s"] if not js_signature: urljs = scrapertools.find_single_match( youtube_page_data, '"assets":.*?"js":\s*"([^"]+)"') urljs = urljs.replace("\\", "") if urljs: if not re.search(r'https?://', urljs): urljs = urlparse.urljoin( "https://www.youtube.com", urljs) data_js = httptools.downloadpage(urljs).data from jsinterpreter import JSInterpreter funcname = scrapertools.find_single_match( data_js, '\.sig\|\|([A-z0-9$]+)\(') if not funcname: funcname = scrapertools.find_single_match( data_js, '["\']signature["\']\s*,\s*' '([A-z0-9$]+)\(') jsi = JSInterpreter(data_js) js_signature = jsi.extract_function(funcname) signature = js_signature([sig]) url += "&signature=" + signature url = url.replace(",", "%2C") video_urls.append(["(" + fmt_value[key] + ") [youtube]", url]) except: import traceback logger.info(traceback.format_exc()) return video_urls
def save_library_movie(item): """ guarda en la libreria de peliculas el elemento item, con los valores que contiene. @type item: item @param item: elemento que se va a guardar. @rtype insertados: int @return: el número de elementos insertados @rtype sobreescritos: int @return: el número de elementos sobreescritos @rtype fallidos: int @return: el número de elementos fallidos o -1 si ha fallado todo """ logger.info() # logger.debug(item.tostring('\n')) insertados = 0 sobreescritos = 0 fallidos = 0 path = "" # Itentamos obtener el titulo correcto: # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la biblioteca..." # 2. fulltitle # 3. title if not item.contentTitle: # Colocamos el titulo correcto en su sitio para que scraper lo localize if item.fulltitle: item.contentTitle = item.fulltitle else: item.contentTitle = item.title # Si llegados a este punto no tenemos titulo, salimos if not item.contentTitle or not item.channel: logger.debug("NO ENCONTRADO contentTitle") return 0, 0, -1 # Salimos sin guardar scraper_return = scraper.find_and_set_infoLabels(item) # Llegados a este punto podemos tener: # scraper_return = True: Un item con infoLabels con la información actualizada de la peli # scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana) # item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos if not scraper_return or not item.infoLabels['code']: # TODO de momento si no hay resultado no añadimos nada, # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code") return 0, 0, -1 _id = item.infoLabels['code'][0] # progress dialog p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo película...') base_name = unicode(filetools.validate_path(item.contentTitle), "utf8").lower().encode("utf8") for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH): for c in subcarpetas: code = scrapertools.find_single_match(c, '\[(.*?)\]') if code and code in item.infoLabels['code']: path = filetools.join(raiz, c) _id = code break if not path: # Crear carpeta path = filetools.join(MOVIES_PATH, ("%s [%s]" % (base_name, _id)).strip()) logger.info("Creando directorio pelicula:" + path) if not filetools.mkdir(path): logger.debug("No se ha podido crear el directorio") return 0, 0, -1 nfo_path = filetools.join(path, "%s [%s].nfo" % (base_name, _id)) strm_path = filetools.join(path, "%s.strm" % base_name) json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel.lower()))) nfo_exists = filetools.exists(nfo_path) strm_exists = filetools.exists(strm_path) json_exists = filetools.exists(json_path) if not nfo_exists: # Creamos .nfo si no existe logger.info("Creando .nfo: " + nfo_path) head_nfo = scraper.get_nfo(item) item_nfo = Item(title=item.contentTitle, channel="biblioteca", action='findvideos', library_playcounts={"%s [%s]" % (base_name, _id): 0}, infoLabels=item.infoLabels, library_urls={}) else: # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos head_nfo, item_nfo = read_nfo(nfo_path) if not strm_exists: # Crear base_name.strm si no existe item_strm = item.clone(channel='biblioteca', action='play_from_library', strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie', infoLabels={'title': item.contentTitle}) strm_exists = filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl())) item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "") # Solo si existen item_nfo y .strm continuamos if item_nfo and strm_exists: if json_exists: logger.info("El fichero existe. Se sobreescribe") sobreescritos += 1 else: insertados += 1 if filetools.write(json_path, item.tojson()): p_dialog.update(100, '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 biblioteca de Kodi con la pelicula if config.is_xbmc(): from platformcode import xbmc_library xbmc_library.update(FOLDER_MOVIES, filetools.basename(path) + "/") p_dialog.close() return insertados, sobreescritos, fallidos # Si llegamos a este punto es por q algo ha fallado logger.error("No se ha podido guardar %s en la biblioteca" % item.contentTitle) p_dialog.update(100, 'Fallo al añadir...', item.contentTitle) p_dialog.close() return 0, 0, -1
def do_search(item): logger.info("streamondemand.channels.saghe do_search") tecleado = item.extra mostra = item.fulltitle itemlist = [] import os import glob import imp from lib.fuzzywuzzy import fuzz import threading import Queue master_exclude_data_file = os.path.join(config.get_runtime_path(), "resources", "sodsearch.txt") logger.info("streamondemand.channels.buscador master_exclude_data_file=" + master_exclude_data_file) channels_path = os.path.join(config.get_runtime_path(), "channels", '*.py') logger.info("streamondemand.channels.buscador channels_path=" + channels_path) excluir = "" if os.path.exists(master_exclude_data_file): logger.info( "streamondemand.channels.buscador Encontrado fichero exclusiones") fileexclude = open(master_exclude_data_file, "r") excluir = fileexclude.read() fileexclude.close() else: logger.info( "streamondemand.channels.buscador No encontrado fichero exclusiones" ) excluir = "seriesly\nbuscador\ntengourl\n__init__" if config.is_xbmc(): show_dialog = True try: import xbmcgui progreso = xbmcgui.DialogProgressBG() progreso.create("Ricerca di " + mostra) except: show_dialog = False def worker(infile, queue): channel_result_itemlist = [] try: basename_without_extension = os.path.basename(infile)[:-3] # http://docs.python.org/library/imp.html?highlight=imp#module-imp obj = imp.load_source(basename_without_extension, infile) logger.info("streamondemand.channels.buscador cargado " + basename_without_extension + " de " + infile) channel_result_itemlist.extend(obj.search(Item(), tecleado)) for item in channel_result_itemlist: item.title = " [COLOR azure] " + item.title + " [/COLOR] [COLOR orange]su[/COLOR] [COLOR green]" + basename_without_extension + "[/COLOR]" item.viewmode = "list" except: import traceback logger.error(traceback.format_exc()) queue.put(channel_result_itemlist) channel_files = [ infile for infile in glob.glob(channels_path) if os.path.basename(infile)[:-3] not in excluir ] result = Queue.Queue() threads = [ threading.Thread(target=worker, args=(infile, result)) for infile in channel_files ] for t in threads: t.start() number_of_channels = len(channel_files) for index, t in enumerate(threads): percentage = index * 100 / number_of_channels if show_dialog: progreso.update(percentage, ' Sto cercando "' + mostra + '"') t.join() itemlist.extend(result.get()) itemlist = sorted([ item for item in itemlist if fuzz.WRatio(mostra, item.fulltitle) > 85 ], key=lambda Item: Item.title) if show_dialog: progreso.close() return itemlist