def eliminar(item): 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() logger.info(item.contentTitle) #logger.debug(item.tostring('\n')) if item.contentType == 'movie': heading = "Eliminar película" else: heading = "Eliminar serie" if item.multicanal: # Obtener listado de canales opciones = ["Eliminar solo los enlaces de %s" % k.capitalize() for k in item.library_urls.keys() if k !="descargas"] opciones.insert(0, heading) index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index == 0: # Seleccionado Eliminar pelicula/serie eliminar_todo(item) elif index > 0: # Seleccionado Eliminar canal X canal = opciones[index].replace("Eliminar solo los enlaces de ", "").lower() num_enlaces= 0 for fd in filetools.listdir(item.path): if fd.endswith(canal + '].json'): if filetools.remove(filetools.join(item.path, fd)): num_enlaces += 1 if num_enlaces > 0: # Actualizar .nfo head_nfo, item_nfo = library.read_nfo(item.nfo) del item_nfo.library_urls[canal] filetools.write(item.nfo, head_nfo + item_nfo.tojson()) msg_txt = "Eliminados %s enlaces del canal %s" % (num_enlaces, canal) logger.info(msg_txt) platformtools.dialog_notification(heading, msg_txt) platformtools.itemlist_refresh() else: if platformtools.dialog_yesno(heading, "¿Realmente desea eliminar '%s' de su biblioteca?" % item.infoLabels['title']): eliminar_todo(item)
def force_creation_advancedsettings(item): # Ruta del advancedsettings advancedsettings = xbmc.translatePath("special://userdata/advancedsettings.xml") itemlist = [] try: risp = platformtools.dialog_select('Scegli settaggio cache', [ram[0], ram[1], ram[2], ram[3]]) logger.info(str(risp)) if risp == 0: valore = opt[0] testo = "\n[COLOR orange]Cache Impostata per 512 Mega di RAM[/COLOR]" if risp == 1: valore = opt[1] testo = "\n[COLOR orange]Cache Impostata per 1 Gb di RAM[/COLOR]" if risp == 2: valore = opt[2] testo = "\n[COLOR orange]Cache Impostata per 2 Gb di RAM[/COLOR]" if risp == 3: valore = opt[3] testo = "\n[COLOR orange]Cache Impostata a superiore di 2 Gb di RAM[/COLOR]" if risp < 0: return itemlist file = '''<advancedsettings> <network> <buffermode>1</buffermode> <cachemembuffersize>''' + valore + '''</cachemembuffersize> <readbufferfactor>10</readbufferfactor> <autodetectpingtime>30</autodetectpingtime> <curlclienttimeout>60</curlclienttimeout> <curllowspeedtime>60</curllowspeedtime> <curlretries>2</curlretries> <disableipv6>true</disableipv6> </network> <gui> <algorithmdirtyregions>0</algorithmdirtyregions> <nofliptimeout>0</nofliptimeout> </gui> <playlistasfolders1>false</playlistasfolders1> <audio> <defaultplayer>dvdplayer</defaultplayer> </audio> <imageres>540</imageres> <fanartres>720</fanartres> <splash>false</splash> <handlemounting>0</handlemounting> <samba> <clienttimeout>30</clienttimeout> </samba> </advancedsettings>''' logger.info(file) salva = open(advancedsettings, "w") salva.write(file) salva.close() except: pass platformtools.dialog_ok("plugin", "E' stato creato un file advancedsettings.xml","con la configurazione ideale per lo streaming.", testo) return itemlist
def menu(item): logger.info() # Opciones disponibles para el menu op = ["Descargar", "Eliminar de la lista", "Reiniciar descarga", "Descargar desde...", "Reproducir"] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar opciones.append(op[3]) # Descargar desde... opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[4]) # Reproducir opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select("Scegliere un'opzione", opciones) # -1 es cancelar if seleccion == -1: return logger.info("opcion=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: start_download(item) # Opcion inicaiar descarga desde... if opciones[seleccion] == op[3]: start_download(item, ask=True) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) update_json(item.path, {"downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0}) # Reproducir if opciones[seleccion] == op[4]: item.url = filetools.join(DOWNLOAD_PATH, item.downloadFilename) return platformtools.play_video(item) platformtools.itemlist_refresh()
def download_from_best_server(item, ask=False): logger.info( "contentAction: %s | contentChannel: %s | url: %s" % (item.contentAction, item.contentChannel, item.url)) result = {"downloadStatus": STATUS_CODES.error} progreso = platformtools.dialog_progress("Download", "Recupero l'elenco dei server disponibili...") channel = __import__('channels.%s' % item.contentChannel, None, None, ["channels.%s" % item.contentChannel]) progreso.update(50, "Recupero l'elenco dei server disponibili.", "Connessione a %s..." % item.contentChannel) if hasattr(channel, item.contentAction): play_items = getattr(channel, item.contentAction)( item.clone(action=item.contentAction, channel=item.contentChannel)) else: play_items = servertools.find_video_items(item.clone(action=item.contentAction, channel=item.contentChannel)) play_items = filter(lambda x: x.action == "play", play_items) progreso.update(100, "Recupero l'elenco dei server disponibili.", "Server disponibili: %s" % len(play_items), "Identifico i server...") for i in play_items: if not i.server: i.server = servertools.get_server_from_url(i.url) if progreso.iscanceled(): return {"downloadStatus": STATUS_CODES.canceled} play_items.sort(key=sort_method) if progreso.iscanceled(): return {"downloadStatus": STATUS_CODES.canceled} progreso.close() if not ask: # Recorremos el listado de servers, hasta encontrar uno que funcione for play_item in play_items: play_item = item.clone(**play_item.__dict__) play_item.contentAction = play_item.action play_item.infoLabels = item.infoLabels result = download_from_server(play_item) if progreso.iscanceled(): result["downloadStatus"] = STATUS_CODES.canceled # Tanto si se cancela la descarga como si se completa dejamos de probar mas opciones if result["downloadStatus"] in [STATUS_CODES.canceled, STATUS_CODES.completed]: break else: seleccion = platformtools.dialog_select("Selezionare il server", [s.title for s in play_items]) if seleccion > -1: play_item = item.clone(**play_items[seleccion].__dict__) play_item.contentAction = play_item.action play_item.infoLabels = item.infoLabels result = download_from_server(play_item) else: result["downloadStatus"] = STATUS_CODES.canceled return result
def play_from_library(item): """ Los .strm al reproducirlos desde kodi, este espera que sea un archivo "reproducible" asi que no puede contener más items, como mucho se puede colocar un dialogo de seleccion. Esto lo solucionamos "engañando a kodi" y haciendole creer que se ha reproducido algo, asi despues mediante "Container.Update()" cargamos el strm como si un item desde dentro de pelisalacarta se tratara, quitando todas las limitaciones y permitiendo reproducir mediante la funcion general sin tener que crear nuevos métodos para la biblioteca. @type item: item @param item: elemento con información """ logger.info("streamondemand.platformcode.launcher play_from_library") # logger.debug("item: \n" + item.tostring('\n')) import xbmcgui import xbmcplugin import xbmc # Intentamos reproducir una imagen (esto no hace nada y ademas no da error) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "icon.png"))) # Por si acaso la imagen hiciera (en futuras versiones) le damos a stop para detener la reproduccion xbmc.Player().stop() # modificamos el action (actualmente la biblioteca necesita "findvideos" ya que es donde se buscan las fuentes item.action = "findvideos" # y volvemos a lanzar kodi if xbmc.getCondVisibility('Window.IsMedia'): xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")") else: from channels import biblioteca from platformcode import xbmc_library p_dialog = platformtools.dialog_progress_bg('streamondemand', 'Caricamento in corso...') p_dialog.update(0, '') itemlist = biblioteca.findvideos(item) p_dialog.update(50, '') if len(itemlist) > 0: # El usuario elige el mirror opciones = [] for item in itemlist: opciones.append(item.title) seleccion = platformtools.dialog_select(config.get_localized_string(30163), opciones) if seleccion == -1: return item = biblioteca.play(itemlist[seleccion])[0] p_dialog.update(100, '') platformtools.play_video(item) p_dialog.close() xbmc_library.mark_auto_as_watched(itemlist[seleccion])
def menu(item): logger.info("pelisalacarta.channels.descargas menu") # Opciones disponibles para el menu op = ["Descargar", "Eliminar de la lista", "Reiniciar descarga"] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select("Elige una opción", opciones) # -1 es cancelar if seleccion == -1: return logger.info("pelisalacarta.channels.descargas menu opcion=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: start_download(item) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) JSONItem = Item().fromjson(filetools.read(item.path)) JSONItem.downloadStatus = 0 JSONItem.downloadComplete = 0 JSONItem.downloadProgress = 0 JSONItem.downloadUrl = "" filetools.write(item.path, JSONItem.tojson()) platformtools.itemlist_refresh()
def play_menu(item): if item.server=="": item.server="directo" if item.video_urls: video_urls,puedes,motivo = item.video_urls, True, "" else: video_urls,puedes,motivo = servertools.resolve_video_urls_for_playing(item.server,item.url,item.password,True) if not "strmfile" in item: item.strmfile=False #TODO: unificar show y Serie ya que se usan indistintamente. if not "Serie" in item: item.Serie = item.show if item.server=="": item.server="directo" opciones = check_video_options(item, video_urls) if not puedes: if item.server!="directo": motivo = motivo.replace("<br/>", "\n") platformtools.dialog_ok("No puedes ver ese vídeo porque...",motivo+"\n"+item.url) else: platformtools.dialog_ok("No puedes ver ese vídeo porque...","El servidor donde está alojado no está\nsoportado en pelisalacarta todavía\n"+item.url) if len(opciones)==0: return default_action = config.get_setting("default_action") logger.info("default_action="+default_action) # Si la accion por defecto es "Preguntar", pregunta if default_action=="0": seleccion = platformtools.dialog_select(config.get_localized_string(30163), [opcion.option for opcion in opciones]) elif default_action=="1": seleccion = 0 elif default_action=="2": seleccion = len(video_urls)-1 elif default_action=="3": seleccion = seleccion else: seleccion=0 if seleccion > -1: logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion].option) selecteditem = opciones[seleccion] del selecteditem.option run(opciones[seleccion]) return
def play_from_library(item, channel, server_white_list, server_black_list): logger.info("streamondemand.platformcode.launcher play_from_library") logger.info("streamondemand.platformcode.launcher play_from_library item.server=#"+item.server+"#") elegido = item # DrZ3r0 if item.action == "findvideos": # Ejecuta find_videos, del canal o común if hasattr(channel, 'findvideos'): itemlist = getattr(channel, item.action)(item) else: from core import servertools itemlist = servertools.find_video_items(item) if config.get_setting('filter_servers') == 'true': itemlist = filtered_servers(itemlist, server_white_list, server_black_list) if len(itemlist) > 0: # El usuario elige el mirror opciones = [] for item in itemlist: opciones.append(item.title) seleccion = platformtools.dialog_select(config.get_localized_string(30163), opciones) elegido = itemlist[seleccion] if seleccion == -1: return # Ejecuta el método play del canal, si lo hay try: itemlist = channel.play(elegido) item = itemlist[0] except AttributeError: item = elegido logger.info("streamondemand.platformcode.launcher play_from_library Elegido %s (sub %s)" % (item.title, item.subtitle)) xbmctools.play_video(item, strmfile=True) library.mark_as_watched(item)
def file(item): itemlist = [] logger.info("[bibiolteca.py] file") logger.info("[biblioteca.py] urlfile--->>>" + item.url) risp = platformtools.dialog_select('Stream On Demand play video', ['Guarda', 'Rinomina', 'Elimina']) try: if risp == 0: xbmc.Player().play(item.url) elif risp == 1: nome = platformtools.dialog_input(item.fulltitle) os.renames(item.url, filetools.join(config.get_library_path(), nome)) xbmc.executebuiltin("Container.Refresh") elif risp == 2: if elimina_file(item): filetools.remove(item.url) xbmc.executebuiltin("Container.Refresh") except: pass return itemlist
def play_from_library(item): """ Los .strm al reproducirlos desde kodi, este espera que sea un archivo "reproducible" asi que no puede contener más items, como mucho se puede colocar un dialogo de seleccion. Esto lo solucionamos "engañando a kodi" y haciendole creer que se ha reproducido algo, asi despues mediante "Container.Update()" cargamos el strm como si un item desde dentro de pelisalacarta se tratara, quitando todas las limitaciones y permitiendo reproducir mediante la funcion general sin tener que crear nuevos métodos para la biblioteca. @type item: item @param item: elemento con información """ logger.info("pelisalacarta.platformcode.launcher play_from_library") # logger.debug("item: \n" + item.tostring('\n')) import xbmcgui import xbmcplugin import xbmc # Intentamos reproducir una imagen (esto no hace nada y ademas no da error) xbmcplugin.setResolvedUrl( int(sys.argv[1]), True, xbmcgui.ListItem( path=os.path.join(config.get_runtime_path(), "icon.png"))) # Por si acaso la imagen hiciera (en futuras versiones) le damos a stop para detener la reproduccion xbmc.Player().stop() # modificamos el action (actualmente la biblioteca necesita "findvideos" ya que es donde se buscan las fuentes item.action = "findvideos" # y volvemos a lanzar kodi if xbmc.getCondVisibility('Window.IsMedia'): xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")") else: from channels import biblioteca from platformcode import xbmc_library p_dialog = platformtools.dialog_progress_bg('pelisalacarta', 'Cargando...') p_dialog.update(0, '') itemlist = biblioteca.findvideos(item) p_dialog.update(50, '') if len(itemlist) > 0: # El usuario elige el mirror opciones = [] for item in itemlist: opciones.append(item.title) seleccion = platformtools.dialog_select( config.get_localized_string(30163), opciones) if seleccion == -1: return item = biblioteca.play(itemlist[seleccion])[0] p_dialog.update(100, '') platformtools.play_video(item) p_dialog.close() xbmc_library.mark_auto_as_watched(itemlist[seleccion])
def play_from_library(item): """ The .strm files when played from kodi, this expects it to be a "playable" file so it cannot contain more items, at most a selection dialog can be placed. We solve this by "cheating kodi" and making him believe that something has been reproduced, so later by "Container.Update ()" we load the strm as if an item from inside the addon were treated, removing all the limitations and allowing to reproduce through the general function without having to create new methods to the video library. @type item: item @param item: item with information """ import xbmcgui, xbmcplugin, xbmc from time import sleep itemlist = [] item.fromLibrary = True logger.info() # logger.debug("item: \n" + item.tostring('\n')) # Try to reproduce an image (this does nothing and also does not give an error) xbmcplugin.setResolvedUrl( int(sys.argv[1]), True, xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "resources", "kod.mp4"))) xbmc.Player().stop() # Modify the action (currently the video library needs "findvideos" since this is where the sources are searched item.action = "findvideos" window_type = config.get_setting("window_type", "videolibrary") # and launch kodi again if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1: # Conventional window xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")") else: # Pop-up window from specials import videolibrary p_dialog = platformtools.dialog_progress_bg( config.get_localized_string(20000), config.get_localized_string(60683)) p_dialog.update(0, '') item.play_from = 'window' itemlist = videolibrary.findvideos(item) p_dialog.update(100, '') sleep(0.5) p_dialog.close() while platformtools.is_playing(): # Conventional window sleep(1) play_time = platformtools.resume_playback(item, True) if not play_time and config.get_setting('autoplay'): return # The number of links to show is limited if config.get_setting("max_links", "videolibrary") != 0: itemlist = limit_itemlist(itemlist) # The list of links is slightly "cleaned" if config.get_setting("replace_VD", "videolibrary") == 1: itemlist = reorder_itemlist(itemlist) if len(itemlist) > 0: while not xbmc.Monitor().abortRequested(): # The user chooses the mirror options = [] selection_implementation = 0 for item in itemlist: item.thumbnail = config.get_online_server_thumb( item.server) quality = '[B][' + item.quality + '][/B]' if item.quality else '' if item.server: it = xbmcgui.ListItem( '\n[B]%s[/B] %s - %s' % (item.server, quality, item.contentTitle)) it.setArt({'thumb': item.thumbnail}) options.append(it) else: selection_implementation += 1 # The selection window opens if (item.contentSerieName and item.contentSeason and item.contentEpisodeNumber): head = ("%s - %sx%s | %s" % (item.contentSerieName, item.contentSeason, item.contentEpisodeNumber, config.get_localized_string(30163))) else: head = config.get_localized_string(30163) selection = platformtools.dialog_select(head, options, preselect=-1, useDetails=True) if selection == -1: return else: item = videolibrary.play( itemlist[selection + selection_implementation])[0] platformtools.play_video(item) if (platformtools.is_playing() and item.action ) or item.server == 'torrent' or config.get_setting( 'autoplay'): break
def play_from_library(item): """ Los .strm al reproducirlos desde kodi, este espera que sea un archivo "reproducible" asi que no puede contener más items, como mucho se puede colocar un dialogo de seleccion. Esto lo solucionamos "engañando a kodi" y haciendole creer que se ha reproducido algo, asi despues mediante "Container.Update()" cargamos el strm como si un item desde dentro del addon se tratara, quitando todas las limitaciones y permitiendo reproducir mediante la funcion general sin tener que crear nuevos métodos para la videoteca. @type item: item @param item: elemento con información """ logger.info() # logger.debug("item: \n" + item.tostring('\n')) import xbmcgui import xbmcplugin import xbmc # Intentamos reproducir una imagen (esto no hace nada y ademas no da error) xbmcplugin.setResolvedUrl( int(sys.argv[1]), True, xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "resources", "subtitle.mp4"))) # Por si acaso la imagen hiciera (en futuras versiones) le damos a stop para detener la reproduccion xbmc.Player().stop() # modificamos el action (actualmente la videoteca necesita "findvideos" ya que es donde se buscan las fuentes item.action = "findvideos" window_type = config.get_setting("window_type", "videolibrary") # y volvemos a lanzar kodi if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1: # Ventana convencional xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")") else: # Ventana emergente from channels import videolibrary p_dialog = platformtools.dialog_progress_bg('alfa', 'Cargando...') p_dialog.update(0, '') itemlist = videolibrary.findvideos(item) while platformtools.is_playing(): # Ventana convencional from time import sleep sleep(5) p_dialog.update(50, '') '''# Se filtran los enlaces segun la lista negra if config.get_setting('filter_servers', "servers"): itemlist = servertools.filter_servers(itemlist)''' # Se limita la cantidad de enlaces a mostrar if config.get_setting("max_links", "videolibrary") != 0: itemlist = limit_itemlist(itemlist) # Se "limpia" ligeramente la lista de enlaces if config.get_setting("replace_VD", "videolibrary") == 1: itemlist = reorder_itemlist(itemlist) p_dialog.update(100, '') xbmc.sleep(500) p_dialog.close() if len(itemlist) > 0: # El usuario elige el mirror opciones = [] for item in itemlist: opciones.append(item.title) # Se abre la ventana de seleccion if (item.contentSerieName != "" and item.contentSeason != "" and item.contentEpisodeNumber != ""): cabecera = ("%s - %sx%s -- %s" % (item.contentSerieName, item.contentSeason, item.contentEpisodeNumber, config.get_localized_string(30163))) else: cabecera = config.get_localized_string(30163) seleccion = platformtools.dialog_select(cabecera, opciones) if seleccion == -1: return else: item = videolibrary.play(itemlist[seleccion])[0] platformtools.play_video(item)
def delete(item): def delete_all(_item): for file in filetools.listdir(_item.path): if file.endswith(".strm") or file.endswith( ".nfo") or file.endswith(".json") or file.endswith( ".torrent"): filetools.remove(filetools.join(_item.path, file)) raiz, carpeta_serie, ficheros = filetools.walk(_item.path).next() if ficheros == []: filetools.rmdir(_item.path) if config.is_xbmc(): import xbmc # esperamos 3 segundos para dar tiempo a borrar los ficheros xbmc.sleep(3000) # TODO mirar por qué no funciona al limpiar en la videoteca de Kodi al añadirle un path # limpiamos la videoteca de Kodi from platformcode import xbmc_videolibrary xbmc_videolibrary.clean() logger.info("Eliminados todos los enlaces") platformtools.itemlist_refresh() # logger.info(item.contentTitle) # logger.debug(item.tostring('\n')) if item.contentType == 'movie': heading = config.get_localized_string(70084) else: heading = config.get_localized_string(70085) if item.multicanal: # Obtener listado de canales if item.dead == '': opciones = [ config.get_localized_string(70086) % k.capitalize() for k in item.library_urls.keys() if k != "downloads" ] opciones.insert(0, heading) index = platformtools.dialog_select( config.get_localized_string(30163), opciones) if index == 0: # Seleccionado Eliminar pelicula/serie delete_all(item) elif index > 0: # Seleccionado Eliminar canal X canal = opciones[index].replace( config.get_localized_string(70079), "").lower() else: return else: canal = item.dead num_enlaces = 0 for fd in filetools.listdir(item.path): if fd.endswith(canal + '].json') or scrapertools.find_single_match( fd, '%s]_\d+.torrent' % canal): if filetools.remove(filetools.join(item.path, fd)): num_enlaces += 1 if num_enlaces > 0: # Actualizar .nfo head_nfo, item_nfo = videolibrarytools.read_nfo(item.nfo) del item_nfo.library_urls[canal] if item_nfo.emergency_urls and item_nfo.emergency_urls.get( canal, False): del item_nfo.emergency_urls[canal] filetools.write(item.nfo, head_nfo + item_nfo.tojson()) msg_txt = config.get_localized_string(70087) % (num_enlaces, canal) logger.info(msg_txt) platformtools.dialog_notification(heading, msg_txt) platformtools.itemlist_refresh() else: if platformtools.dialog_yesno( heading, config.get_localized_string(70088) % item.infoLabels['title']): delete_all(item)
def abandomoviez_search(item): logger.info("streamondemand.channels.trailertools abandomoviez_search") # Comprueba si es una búsqueda de cero o viene de la opción Siguiente if item.page != "": data = scrapertools.downloadpage(item.page) else: titulo = item.contentTitle.decode('utf-8').encode('iso-8859-1') post = urllib.urlencode({ 'query': titulo, 'searchby': '1', 'posicion': '1', 'orden': '1', 'anioin': item.year, 'anioout': item.year, 'orderby': '1' }) url = "http://www.abandomoviez.net/db/busca_titulo_advance.php" item.prefix = "db/" data = scrapertools.downloadpage(url, post=post) if "No hemos encontrado ninguna" in data: url = "http://www.abandomoviez.net/indie/busca_titulo_advance.php" item.prefix = "indie/" data = scrapertools.downloadpage( url, post=post).decode("iso-8859-1").encode('utf-8') logger.info(data) itemlist = [] devuelve = [] patron = '(?:<td width="85"|<div class="col-md-2 col-sm-2 col-xs-3">).*?<img src="([^"]+)"' \ '.*?href="([^"]+)">(.*?)(?:<\/td>|<\/small>)' matches = scrapertools.find_multiple_matches(data, patron) # Si solo hay un resultado busca directamente los trailers, sino lista todos los resultados if len(matches) == 1: item.url = urlparse.urljoin( "http://www.abandomoviez.net/%s" % item.prefix, matches[0][1]) item.thumbnail = matches[0][0] devuelve = search_links_abando(item) elif len(matches) > 1: for scrapedthumbnail, scrapedurl, scrapedtitle in matches: scrapedurl = urlparse.urljoin( "http://www.abandomoviez.net/%s" % item.prefix, scrapedurl) scrapedtitle = scrapertools.htmlclean(scrapedtitle) itemlist.append( item.clone(title=scrapedtitle, action="search_links_abando", url=scrapedurl, thumbnail=scrapedthumbnail, text_color="white")) next_page = scrapertools.find_single_match( data, '<a href="([^"]+)">Siguiente') if next_page != "": next_page = urlparse.urljoin( "http://www.abandomoviez.net/%s" % item.prefix, next_page) itemlist.append( item.clone(title=">> Siguiente", action="abandomoviez_search", page=next_page, thumbnail="", text_color="")) if item.contextual: opciones = [] for item_abando in itemlist: opciones.append(item_abando.title) seleccion = platformtools.dialog_select( "Buscando: " + item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item_abando = itemlist[seleccion] if item_abando.title == ">> Siguiente": return buscartrailer(item_abando) else: devuelve = search_links_abando(item_abando) else: devuelve = itemlist if not devuelve: devuelve.append( item.clone(title="La búsqueda no ha dado resultados", action="", thumbnail="", text_color="")) if keyboard: title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" devuelve.append( item.clone(title=title % "Búsqueda Manual en Abandomoviez", action="manual_search", thumbnail="", text_color="green", extra="abandomoviez")) return devuelve
def menu(item): logger.info() # Opciones disponibles para el menu op = [ "Descargar", "Eliminar de la lista", "Reiniciar descarga", "Descargar desde..." ] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar opciones.append(op[3]) # Descargar desde... opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select("Elige una opción", opciones) # -1 es cancelar if seleccion == -1: return logger.info("opcion=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: start_download(item) # Opcion inicaiar descarga desde... if opciones[seleccion] == op[3]: start_download(item, ask=True) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) update_json( item.path, { "downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0 }) platformtools.itemlist_refresh()
def set_content(content_type, silent=False): """ Procedimiento para auto-configurar la videoteca de kodi con los valores por defecto @type content_type: str ('movie' o 'tvshow') @param content_type: tipo de contenido para configurar, series o peliculas """ continuar = True msg_text = "" videolibrarypath = config.get_setting("videolibrarypath") if content_type == 'movie': scraper = [ config.get_localized_string(70093), config.get_localized_string(70096) ] seleccion = platformtools.dialog_select( config.get_localized_string(70094), scraper) # Instalar The Movie Database if seleccion == -1 or seleccion == 0: if not xbmc.getCondVisibility( 'System.HasAddon(metadata.themoviedb.org)'): if not silent: # Preguntar si queremos instalar metadata.themoviedb.org install = platformtools.dialog_yesno( config.get_localized_string(60046)) 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 = config.get_localized_string(60047) if continuar: xbmc.executebuiltin( 'xbmc.addon.opensettings(metadata.themoviedb.org)', True) # Instalar Universal Movie Scraper elif seleccion == 1: if continuar and not xbmc.getCondVisibility( 'System.HasAddon(metadata.universal)'): continuar = False if not silent: # Preguntar si queremos instalar metadata.universal install = platformtools.dialog_yesno( config.get_localized_string(70095)) else: install = True if install: try: xbmc.executebuiltin( 'xbmc.installaddon(metadata.universal)', True) if xbmc.getCondVisibility( 'System.HasAddon(metadata.universal)'): continuar = True except: pass continuar = (install and continuar) if not continuar: msg_text = config.get_localized_string(70097) if continuar: xbmc.executebuiltin( 'xbmc.addon.opensettings(metadata.universal)', True) else: # SERIES scraper = [ config.get_localized_string(70098), config.get_localized_string(70093) ] seleccion = platformtools.dialog_select( config.get_localized_string(70107), scraper) # Instalar The TVDB if seleccion == -1 or seleccion == 0: if not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvdb.com)'): if not silent: # Preguntar si queremos instalar metadata.tvdb.com install = platformtools.dialog_yesno( config.get_localized_string(60048)) 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 = config.get_localized_string(70099) if continuar: xbmc.executebuiltin( 'xbmc.addon.opensettings(metadata.tvdb.com)', True) # Instalar The Movie Database elif seleccion == 1: 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( config.get_localized_string(70100)) else: install = True if install: try: # Instalar metadata.tvshows.themoviedb.org xbmc.executebuiltin( 'xbmc.installaddon(metadata.tvshows.themoviedb.org)', True) if xbmc.getCondVisibility( 'System.HasAddon(metadata.tvshows.themoviedb.org)' ): continuar = True except: pass continuar = (install and continuar) if not continuar: msg_text = config.get_localized_string(60047) if continuar: xbmc.executebuiltin( 'xbmc.addon.opensettings(metadata.tvshows.themoviedb.org)', True) 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_videolibrarypath = videolibrarypath if sql_videolibrarypath.startswith("special://"): sql_videolibrarypath = sql_videolibrarypath.replace( '/profile/', '/%/').replace('/home/userdata/', '/%/') sep = '/' elif scrapertools.find_single_match(sql_videolibrarypath, '(^\w+:\/\/)'): sep = '/' else: sep = os.sep if not sql_videolibrarypath.endswith(sep): sql_videolibrarypath += sep # Buscamos el idParentPath sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_videolibrarypath nun_records, records = execute_sql_kodi(sql) if nun_records == 1: idParentPath = records[0][0] videolibrarypath = records[0][1][:-1] continuar = True else: # No existe videolibrarypath en la BD: la insertamos sql_videolibrarypath = videolibrarypath if not sql_videolibrarypath.endswith(sep): sql_videolibrarypath += sep sql = 'INSERT INTO path (idPath, strPath, scanRecursive, useFolderNames, noUpdate, exclude) VALUES ' \ '(%s, "%s", 0, 0, 0, 0)' % (idPath, sql_videolibrarypath) nun_records, records = execute_sql_kodi(sql) if nun_records == 1: continuar = True idParentPath = idPath idPath += 1 else: msg_text = config.get_localized_string(70101) if continuar: continuar = False # Fijamos strContent, strScraper, scanRecursive y strSettings if content_type == 'movie': strContent = 'movies' scanRecursive = 2147483647 if seleccion == -1 or seleccion == 0: strScraper = 'metadata.themoviedb.org' path_settings = xbmc.translatePath( "special://profile/addon_data/metadata.themoviedb.org/settings.xml" ) elif seleccion == 1: strScraper = 'metadata.universal' path_settings = xbmc.translatePath( "special://profile/addon_data/metadata.universal/settings.xml" ) settings_data = filetools.read(path_settings) strSettings = ' '.join(settings_data.split()).replace("> <", "><") strSettings = strSettings.replace("\"", "\'") strActualizar = "¿Desea configurar este Scraper en español como opción por defecto para películas?" if not videolibrarypath.endswith(sep): videolibrarypath += sep strPath = videolibrarypath + config.get_setting( "folder_movies") + sep else: strContent = 'tvshows' scanRecursive = 0 if seleccion == -1 or seleccion == 0: strScraper = 'metadata.tvdb.com' path_settings = xbmc.translatePath( "special://profile/addon_data/metadata.tvdb.com/settings.xml" ) elif seleccion == 1: strScraper = 'metadata.tvshows.themoviedb.org' path_settings = xbmc.translatePath( "special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml" ) settings_data = filetools.read(path_settings) strSettings = ' '.join(settings_data.split()).replace("> <", "><") strSettings = strSettings.replace("\"", "\'") strActualizar = "¿Desea configurar este Scraper en español como opción por defecto para series?" if not videolibrarypath.endswith(sep): videolibrarypath += sep strPath = videolibrarypath + 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( config.get_localized_string(70098), 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 = config.get_localized_string(60055) if not continuar: heading = config.get_localized_string(70102) % content_type elif content_type == 'SERIES' and not xbmc.getCondVisibility( 'System.HasAddon(metadata.tvshows.themoviedb.org)'): heading = config.get_localized_string(70103) % content_type msg_text = config.get_localized_string(60058) else: heading = config.get_localized_string(70103) % content_type msg_text = config.get_localized_string(70104) platformtools.dialog_notification(heading, msg_text, icon=1, time=3000) logger.info("%s: %s" % (heading, msg_text))
def find_and_set_infoLabels(item): """ función que se llama para buscar y setear los infolabels :param item: :return: """ global scraper_global logger.debug("item:\n" + item.tostring('\n')) params = {} if item.contentType == "movie": tipo_contenido = "pelicula" title = item.contentTitle # get scraper pelis scraper = Tmdb() # para tmdb tipo_busqueda = "movie" else: tipo_contenido = "serie" title = item.contentSerieName # get scraper series scraper = Tmdb() # para tmdb tipo_busqueda = "tv" # esto ya está en el scraper tmdb # title = re.sub('\[\\\?(B|I|COLOR)\s?[^\]]*\]', '', title) # Si el titulo incluye el (año) se lo quitamos year = scrapertools.find_single_match(title, "^.+?\s*(\(\d{4}\))$") if year: title = title.replace(year, "").strip() item.infoLabels['year'] = year[1:-1] scraper_result = None results = [] while not scraper_result: # para tmdb if isinstance(scraper, Tmdb): logger.debug("scraper es Tmbdb") params["texto_buscado"] = title params["tipo"] = tipo_busqueda params["year"] = item.infoLabels['year'] if not results: if not item.infoLabels.get("tmdb_id"): if not item.infoLabels.get("imdb_id"): scraper_global = scraper(**params) else: logger.info("tiene imdb") # para tmdb if isinstance(scraper, Tmdb): params["external_id"] = item.infoLabels.get("imdb_id") params["external_source"] = "imdb_id" scraper_global = scraper(**params) elif not scraper_global or scraper_global.result.get("id") != item.infoLabels['tmdb_id']: # para tmdb if isinstance(scraper, Tmdb): params["id_Tmdb"] = item.infoLabels['tmdb_id'] params["idioma_busqueda"] = "es" scraper_global = scraper(**params) results = scraper_global.get_list_resultados() if len(results) > 1: scraper_result = platformtools.show_video_info(results, item=item, scraper=scraper, caption="[%s]: Selecciona la %s correcta" % (title, tipo_contenido)) elif len(results) > 0: scraper_result = results[0] if scraper_result is None: index = -1 if tipo_contenido == "serie": # Si no lo encuentra la serie por si solo, presentamos una lista de opciones opciones = ["Introducir otro nombre", "Buscar en TheTvDB.com"] index = platformtools.dialog_select("%s no encontrada" % tipo_contenido.capitalize(), opciones) elif platformtools.dialog_yesno("Película no encontrada", "No se ha encontrado la película:", title, '¿Desea introducir otro nombre?'): index = 0 if index < 0: logger.debug("he pulsado 'cancelar' en la ventana '%s no encontrada'" % tipo_contenido.capitalize()) break if index == 0: # "Introducir otro nombre" # Pregunta el titulo it = platformtools.dialog_input(title, "Introduzca el nombre de la %s a buscar" % tipo_contenido) if it is not None: title = it item.infoLabels['year'] = "" # reseteamos los resultados results = [] else: logger.debug("he pulsado 'cancelar' en la ventana 'introduzca el nombre correcto'") break if index == 1: # "Buscar en TheTvDB.com" results = tvdb_series_by_title(title) if isinstance(item.infoLabels, InfoLabels): infoLabels = item.infoLabels else: infoLabels = InfoLabels() if scraper_result: if 'id' in scraper_result: # resultados obtenidos de tmdb infoLabels['tmdb_id'] = scraper_result['id'] infoLabels['url_scraper'] = "https://www.themoviedb.org/tv/%s" % infoLabels['tmdb_id'] item.infoLabels = infoLabels tmdb.set_infoLabels_item(item) elif 'tvdb_id' in scraper_result: # resultados obtenidos de tvdb infoLabels.update(scraper_result) item.infoLabels = infoLabels # logger.debug("item:\n" + item.tostring('\n')) return True else: item.infoLabels = infoLabels return False
def buscartrailer(item): logger.info("streamondemand.channels.trailertools buscartrailer") # Se elimina la opciçon de Buscar Trailer del menú contextual para evitar redundancias item.context = item.context.replace("5", "") item.text_color = "" # Si no se indica el parámetro contextual se entiende que no se ejecuta desde este mení if item.contextual == "": item.contextual = False itemlist = [] if item.contentTitle != "": item.contentTitle = item.contentTitle.strip() elif keyboard: item.contentTitle = platformtools.dialog_input( heading="Introduce el título a buscar") if item.contentTitle is None: item.contentTitle = item.fulltitle.strip() else: item.contentTitle = item.contentTitle.strip() else: item.contentTitle = item.fulltitle.strip() item.year = item.infoLabels['year'] if "year" in item.infoLabels else "" logger.info("streamondemand.channels.trailertools Búsqueda: %s" % item.contentTitle) logger.info("streamondemand.channels.trailertools Año: %s" % item.year) # Lista de acciones si se ejecuta desde el menú contextual if item.action == "manual_search": itemlist = manual_search(item) item.contentTitle = itemlist[0].contentTitle elif item.action == "youtube_search": itemlist = youtube_search(item) elif item.action == "filmaffinity_search": itemlist = filmaffinity_search(item) elif item.action == "abandomoviez_search": itemlist = abandomoviez_search(item) elif item.action == "jayhap_search": itemlist = jayhap_search(item) else: if "trailer" in item.infoLabels and item.infoLabels['trailer'] != "": url = item.infoLabels['trailer'] if "youtube" in url: url = url.replace("embed/", "watch?v=") titulo, url, server = servertools.findvideos(url)[0] title = "Trailer por defecto [" + server + "]" itemlist.append( item.clone(title=title, url=url, server=server, action="play")) if item.show != "" or ("tvshowtitle" in item.infoLabels and item.infoLabels['tvshowtitle'] != ""): type = "tv" else: type = "movie" try: itemlist.extend(tmdb_trailers(item, type)) except: import traceback logger.error(traceback.format_exc()) title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" itemlist.append( item.clone(title=title % "Búsqueda en Youtube", action="youtube_search", text_color="green")) itemlist.append( item.clone(title=title % "Búsqueda en Filmaffinity", action="filmaffinity_search", text_color="green")) # Si se trata de una serie, no se incluye la opción de buscar en Abandomoviez if item.show == "" and ("tvshowtitle" not in item.infoLabels or item.infoLabels['tvshowtitle'] == ""): itemlist.append( item.clone(title=title % "Búsqueda en Abandomoviez", action="abandomoviez_search", text_color="green")) itemlist.append( item.clone(title=title % "Búsqueda en Jayhap (Youtube, Vimeo & Dailymotion)", action="jayhap_search", text_color="green")) if item.contextual: opciones = [] if itemlist: for video_url in itemlist: opciones.append(video_url.title) seleccion = platformtools.dialog_select( "Buscando: " + item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item = itemlist[seleccion] if "search" in item.action: buscartrailer(item) else: if item.action == "play": from platformcode import xbmctools xbmctools.play_video(item) return else: return itemlist
def acciones_cuenta(item): logger.info() itemlist = [] if "Tus fichas" in item.title: itemlist.append(item.clone(title="Capítulos", url="tf_block_c a", contentType="tvshow")) itemlist.append(item.clone(title="Series", url="tf_block_s", contentType="tvshow")) itemlist.append(item.clone(title="Películas", url="tf_block_p")) itemlist.append(item.clone(title="Documentales", url="tf_block_d")) return itemlist elif "Añadir a una lista" in item.title: data = httptools.downloadpage(host + "/c_listas.php?apikey=%s&sid=%s" % (apikey, sid)).data data = json.Xml2Json(data).result itemlist.append(item.clone(title="Crear nueva lista", folder=False)) if data["Data"]["TusListas"] != "\t": import random data = data["Data"]["TusListas"]["Item"] if type(data) is not list: data = [data] for child in data: image = "" title = "%s (%s fichas)" % (child["Title"], child["FichasInList"]) images = [] for i in range(1, 5): if "sinimagen.png" not in child["Poster%s" % i]: images.append(child["Poster%s" % i].replace("/100/", "/400/")) if images: image = images[random.randint(0, len(images) - 1)] url = host + "/data.php?mode=add_listas&apikey=%s&sid=%s&ficha_id=%s" % (apikey, sid, item.ficha) post = "lista_id[]=%s" % child["Id"] itemlist.append(item.clone(title=title, url=url, post=post, thumbnail=image, folder=False)) return itemlist elif "Crear nueva lista" in item.title: from platformcode import platformtools nombre = platformtools.dialog_input("", "Introduce un nombre para la lista") if nombre: dict_priv = {0: 'Pública', 1: 'Privada'} priv = platformtools.dialog_select("Privacidad de la lista", ['Pública', 'Privada']) if priv != -1: url = host + "/data.php?mode=create_list&apikey=%s&sid=%s" % (apikey, sid) post = "name=%s&private=%s" % (nombre, priv) data = httptools.downloadpage(url, post) platformtools.dialog_notification("Lista creada correctamente", "Nombre: %s - %s" % (nombre, dict_priv[priv])) platformtools.itemlist_refresh() return elif re.search(r"(?i)Seguir Lista", item.title): from platformcode import platformtools data = httptools.downloadpage(item.url) platformtools.dialog_notification("Operación realizada con éxito", "Lista: %s" % item.lista) return elif item.post: from platformcode import platformtools data = httptools.downloadpage(item.url, item.post).data platformtools.dialog_notification("Ficha añadida a la lista", "Lista: %s" % item.title) platformtools.itemlist_refresh() return data = httptools.downloadpage("https://playmax.mx/tusfichas.php").data data = re.sub(r"\n|\r|\t|\s{2}| |<br>", "", data) bloque = scrapertools.find_single_match(data, item.url + '">(.*?)(?:<div class="tf_blocks|<div class="tf_o_move">)') matches = scrapertools.find_multiple_matches(bloque, '<div class="tf_menu_mini">([^<]+)<(.*?)<cb></cb></div>') for category, contenido in matches: itemlist.append(item.clone(action="", title=category, text_color=color3)) patron = '<div class="c_fichas_image">.*?href="\.([^"]+)".*?src="\.([^"]+)".*?serie="([^"]*)".*?' \ '<div class="c_fichas_title">(?:<div class="c_fichas_episode">([^<]+)</div>|)([^<]+)</div>' entradas = scrapertools.find_multiple_matches(contenido, patron) for scrapedurl, scrapedthumbnail, serie, episodio, scrapedtitle in entradas: tipo = "movie" scrapedurl = host + scrapedurl 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 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) return itemlist
def play_menu(item): if type(item) ==list and len(item)==1: item = item[0] #Modo Normal if type(item) == Item: if item.server=="": item.server="directo" video_urls,puedes,motivo = servertools.resolve_video_urls_for_playing(item.server,item.url,item.password,True) #Modo "Play" en canal, puede devolver varias url elif type(item) ==list and len(item)>1: itemlist = item #En este caso en el argumento item, en realidad hay un itemlist item = itemlist[0] #Se asigna al item, el item primero del itemlist video_urls = [] for videoitem in itemlist: if videoitem.server=="": videoitem.server="directo" opcion_urls,puedes,motivo = servertools.resolve_video_urls_for_playing(videoitem.server,videoitem.url) opcion_urls[0][0] = opcion_urls[0][0] + " [" + videoitem.fulltitle + "]" video_urls.extend(opcion_urls) item = itemlist[0] puedes = True motivo = "" if not "strmfile" in item: item.strmfile=False #TODO: unificar show y Serie ya que se usan indistintamente. if not "Serie" in item: item.Serie = item.show if item.server=="": item.server="directo" opciones = check_video_options(item, video_urls) if not puedes: if item.server!="directo": motivo = motivo.replace("<br/>", "\n") platformtools.dialog_ok("No puedes ver ese vídeo porque...",motivo+"\n"+item.url) else: platformtools.dialog_ok("No puedes ver ese vídeo porque...","El servidor donde está alojado no está\nsoportado en pelisalacarta todavía\n"+item.url) if len(opciones)==0: return default_action = config.get_setting("default_action") logger.info("default_action="+default_action) # Si la accion por defecto es "Preguntar", pregunta if default_action=="0": seleccion = platformtools.dialog_select(config.get_localized_string(30163), [opcion.option for opcion in opciones]) elif default_action=="1": seleccion = 0 elif default_action=="2": seleccion = len(video_urls)-1 elif default_action=="3": seleccion = seleccion else: seleccion=0 if seleccion > -1: logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion].option) selecteditem = opciones[seleccion] del selecteditem.option run(opciones[seleccion]) return
def manual_renumeration(item, modify=False): log() _list = [] if item.from_channel: item.channel = item.from_channel title = item.fulltitle.rstrip() dict_series = load(item) if title not in dict_series: dict_series[title] = {} if TAG_EPISODE in dict_series[title] and dict_series[title][TAG_EPISODE]: EpisodeDict = json.loads( base64.b64decode(dict_series[title][TAG_EPISODE])) del dict_series[title][TAG_EPISODE] else: EpisodeDict = {} if TAG_EPLIST in dict_series[title]: del dict_series[title][TAG_EPLIST] if TAG_MODE in dict_series[title]: del dict_series[title][TAG_MODE] if TAG_CHECK in dict_series[title]: del dict_series[title][TAG_CHECK] if TAG_SEASON in dict_series[title]: del dict_series[title][TAG_SEASON] if TAG_SPECIAL in dict_series[title]: del dict_series[title][TAG_SPECIAL] dict_series[title][TAG_TYPE] = 'manual' write(item, dict_series) if TAG_ID not in dict_series[title] or (TAG_ID in dict_series[title] and not dict_series[title][TAG_ID]): tvdb.find_and_set_infoLabels(item) # Trova l'ID della serie while not item.infoLabels['tvdb_id']: try: item.show = platformtools.dialog_input( default=item.show, heading=config.get_localized_string( 30112)) # <- Enter title to search tvdb.find_and_set_infoLabels(item) except: heading = config.get_localized_string( 70704) # <- TMDB ID (0 to cancel) info = platformtools.dialog_numeric(0, heading) item.infoLabels['tvdb_id'] = '0' if info == '' else info if item.infoLabels['tvdb_id']: ID = item.infoLabels['tvdb_id'] dict_renumerate = {TAG_ID: ID} dict_series[title] = dict_renumerate itemlist = find_episodes(item) for item in itemlist: Title = re.sub(r'\d+x\d+ - ', '', item.title) if modify == True: ep = int(scrapertools.find_single_match(Title, r'(\d+)')) if item.action == 'findvideos' and str(ep) not in EpisodeDict: _list.append(Title) else: if item.action == 'findvideos': _list.append(Title) count = 1 preselect = platformtools.dialog_select( config.get_localized_string(70732), [ typo(config.get_localized_string(70518), 'bold'), typo(config.get_localized_string(70519), 'bold') ]) selection = [] if preselect == 0: for i in _list: selection.append(_list.index(i)) while len(_list) > 0: selected = platformtools.dialog_multiselect( config.get_localized_string(70734), _list, preselect=selection) if selected == None: break season = '' while not season: season = platformtools.dialog_numeric( 0, config.get_localized_string(70733)) for select in selected: ep = int(scrapertools.find_single_match(_list[select], r'(\d+)')) if season == '0': episode = '' while not episode: episode = platformtools.dialog_numeric( 0, config.get_localized_string(70735) % _list[select]) EpisodeDict[str(ep)] = '%sx%s' % (season, episode.zfill(2)) else: EpisodeDict[str(ep)] = '%sx%s' % (season, str(count).zfill(2)) count += 1 for select in reversed(selected): del _list[select] dict_series[title][TAG_TYPE] = 'manual' EpisodeDict = base64.b64encode(json.dumps(EpisodeDict).encode()) dict_series[title][TAG_EPISODE] = EpisodeDict.decode() write(item, dict_series) # xbmc.executebuiltin("Container.Refresh") if modify == True: return json.loads(base64.b64decode(EpisodeDict))
def add_channel(item): support.log() channel_to_add = {} json_file = '' result = platformtools.dialog_select(config.get_localized_string(70676), [ config.get_localized_string(70678), config.get_localized_string(70679) ]) if result == -1: return if result == 0: file_path = xbmcgui.Dialog().browseSingle( 1, config.get_localized_string(70680), 'files') try: channel_to_add['path'] = file_path json_file = jsontools.load(open(file_path, "r").read()) channel_to_add['channel_name'] = json_file['channel_name'] except: pass elif result == 1: url = platformtools.dialog_input("", config.get_localized_string(70681), False) try: if url[:4] != 'http': url = 'http://' + url channel_to_add['path'] = url json_file = jsontools.load(httptools.downloadpage(url).data) except: pass if len(json_file) == 0: return if "episodes_list" in json_file: platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(70682)) return channel_to_add['channel_name'] = json_file['channel_name'] if 'thumbnail' in json_file: channel_to_add['thumbnail'] = json_file['thumbnail'] if 'fanart' in json_file: channel_to_add['fanart'] = json_file['fanart'] path = filetools.join(config.get_data_path(), 'community_channels.json') community_json = open(path, "r") community_json = jsontools.load(community_json.read()) id = 1 while str(id) in community_json['channels']: id += 1 community_json['channels'][str(id)] = (channel_to_add) with open(path, "w") as file: file.write(jsontools.dump(community_json)) file.close() platformtools.dialog_notification( config.get_localized_string(20000), config.get_localized_string(70683) % json_file['channel_name']) import xbmc xbmc.sleep(1000) platformtools.itemlist_refresh() return
def menu(item): logger.info() if item.downloadServer: servidor = item.downloadServer.get("server", "Auto") else: servidor = "Auto" # Opciones disponibles para el menu op = [ "Download", "Elimina dalla lista", "Reiniziallizza download", "Scarica da..." ] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar opciones.append(op[3]) # Descargar desde... opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar if not item.server: opciones.append(op[3]) # Elegir Servidor opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select("Scegli un'opzione", opciones) # -1 es cancelar if seleccion == -1: return logger.info("opcion=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: start_download(item) # Elegir Servidor if opciones[seleccion] == op[3]: select_server(item) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) update_json( item.path, { "downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0, "downloadServer": {} }) platformtools.itemlist_refresh()
def addchannel(item): from platformcode import platformtools import time, os logger.info("pelisalacarta.channels.configuracion addchannel") tecleado = platformtools.dialog_input("", "Introduzca la URL") if not tecleado: return logger.info("pelisalacarta.channels.configuracion url=%s" % tecleado) local_folder = config.get_runtime_path() if "canal" in item.title: local_folder = filetools.join(local_folder, "channels") folder_to_extract = "channels" info_accion = "canal" else: local_folder = filetools.join(local_folder, "servers") folder_to_extract = "servers" info_accion = "conector" # Detecta si es un enlace a un .py o .xml (pensado sobre todo para enlaces de github) try: extension = tecleado.rsplit(".", 1)[1] except: extension = "" files = [] zip = False if extension == "py" or extension == "xml": filename = tecleado.rsplit("/", 1)[1] localfilename = filetools.join(local_folder, filename) files.append([tecleado, localfilename, filename]) else: import re from core import scrapertools # Comprueba si la url apunta a una carpeta completa (channels o servers) de github if re.search(r"https://github.com/[^\s]+/" + folder_to_extract, tecleado): try: data = scrapertools.downloadpage(tecleado) matches = scrapertools.find_multiple_matches( data, '<td class="content">.*?href="([^"]+)".*?title="([^"]+)"' ) for url, filename in matches: url = "https://raw.githubusercontent.com" + url.replace("/blob/", "/") localfilename = filetools.join(local_folder, filename) files.append([url, localfilename, filename]) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) platformtools.dialog_ok("Error", "La url no es correcta o no está disponible") return else: filename = "new%s.zip" % info_accion localfilename = filetools.join(config.get_data_path(), filename) files.append([tecleado, localfilename, filename]) zip = True logger.info("pelisalacarta.channels.configuracion localfilename=%s" % localfilename) logger.info("pelisalacarta.channels.configuracion descarga fichero...") try: if len(files) > 1: lista_opciones = ["No", "Sí", "Sí (Sobrescribir todos)"] overwrite_all = False from core import downloadtools for url, localfilename, filename in files: result = downloadtools.downloadfile(url, localfilename, continuar=False) if result == -3: if len(files) == 1: dyesno = platformtools.dialog_yesno( "El archivo ya existe", "Ya existe el %s %s." " ¿Desea sobrescribirlo?" % (info_accion, filename), ) else: if not overwrite_all: dyesno = platformtools.dialog_select( "El archivo %s ya existe, ¿desea sobrescribirlo?" % filename, lista_opciones ) else: dyesno = 1 # Diálogo cancelado if dyesno == -1: return # Caso de carpeta github, opción sobrescribir todos elif dyesno == 2: overwrite_all = True elif dyesno: hora_folder = "Copia seguridad [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), "backups", hora_folder, folder_to_extract) if not filetools.exists(backup): os.makedirs(backup) import shutil shutil.copy2(localfilename, filetools.join(backup, filename)) result = downloadtools.downloadfile(url, localfilename, continuar=True) else: if len(files) == 1: return else: continue except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) return if zip: try: # Lo descomprime logger.info("pelisalacarta.channels.configuracion descomprime fichero...") from core import ziptools unzipper = ziptools.ziptools() logger.info("pelisalacarta.channels.configuracion destpathname=%s" % local_folder) unzipper.extract(localfilename, local_folder, folder_to_extract, True, True) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) # Borra el zip descargado filetools.remove(localfilename) platformtools.dialog_ok("Error", "Se ha producido un error extrayendo el archivo") return # Borra el zip descargado logger.info("pelisalacarta.channels.configuracion borra fichero...") filetools.remove(localfilename) logger.info("pelisalacarta.channels.configuracion ...fichero borrado") platformtools.dialog_ok("Éxito", "Actualización/Instalación realizada correctamente")
def filmaffinity_search(item): logger.info("fusionse.channels.trailertools filmaffinity_search") # Comprueba si es una búsqueda de cero o viene de la opción Siguiente if item.page != "": data = scrapertools.downloadpage(item.page) else: params = urllib.urlencode([('stext', item.contentTitle), ('stype%5B%5D', 'title'), ('country', ''), ('genre', ''), ('fromyear', item.year), ('toyear', item.year)]) url = "http://www.filmaffinity.com/es/advsearch.php?%s" % params data = scrapertools.downloadpage(url) devuelve = [] itemlist = [] patron = '<div class="mc-poster">.*?<img.*?src="([^"]+)".*?' \ '<div class="mc-title"><a href="/es/film(\d+).html"[^>]+>(.*?)<img' matches = scrapertools.find_multiple_matches(data, patron) # Si solo hay un resultado, busca directamente los trailers, sino lista todos los resultados if len(matches) == 1: item.url = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % matches[0][1] item.thumbnail = matches[0][0] if not item.thumbnail.startswith("http"): item.thumbnail = "http://www.filmaffinity.com" + item.thumbnail devuelve = search_links_filmaff(item) elif len(matches) > 1: for scrapedthumbnail, id, scrapedtitle in matches: if not scrapedthumbnail.startswith("http"): scrapedthumbnail = "http://www.filmaffinity.com" + scrapedthumbnail scrapedurl = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % id scrapedtitle = unicode(scrapedtitle, encoding="utf-8", errors="ignore") scrapedtitle = scrapertools.htmlclean(scrapedtitle) itemlist.append(item.clone(title=scrapedtitle, url=scrapedurl, action="search_links_filmaff", thumbnail=scrapedthumbnail, text_color="white")) next_page = scrapertools.find_single_match(data, '<a href="([^"]+)">>></a>') if next_page != "": next_page = urlparse.urljoin("http://www.filmaffinity.com/es/", next_page) itemlist.append(item.clone(title=">> Siguiente", page=next_page, action="filmaffinity_search", thumbnail="", text_color="")) if item.contextual: opciones = [] for item_film in itemlist: opciones.append(item_film.title) seleccion = platformtools.dialog_select("Buscando: "+item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item_film = itemlist[seleccion] if item_film.title == ">> Siguiente": return buscartrailer(item_film) else: devuelve = search_links_filmaff(item_film) else: devuelve = itemlist if not devuelve: devuelve.append(item.clone(title="La búsqueda no ha dado resultados (%s)" % item.contentTitle, action="", thumbnail="", text_color="")) if keyboard: title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" devuelve.append(item.clone(title=title % "Búsqueda Manual en Filmaffinity", action="manual_search", text_color="green", thumbnail="", extra="filmaffinity")) return devuelve
def addchannel(item): from platformcode import platformtools import os import time logger.info() tecleado = platformtools.dialog_input("", "Inserire l'URL") if not tecleado: return logger.info("url=%s" % tecleado) local_folder = config.get_runtime_path() if "canal" in item.title: local_folder = filetools.join(local_folder, 'channels') folder_to_extract = "channels" info_accion = "canal" else: local_folder = filetools.join(local_folder, 'servers') folder_to_extract = "servers" info_accion = "conector" # Detecta si es un enlace a un .py o .xml (pensado sobre todo para enlaces de github) try: extension = tecleado.rsplit(".", 1)[1] except: extension = "" files = [] zip = False if extension == "py" or extension == "xml": filename = tecleado.rsplit("/", 1)[1] localfilename = filetools.join(local_folder, filename) files.append([tecleado, localfilename, filename]) else: import re from core import scrapertools # Comprueba si la url apunta a una carpeta completa (channels o servers) de github if re.search(r'https://github.com/[^\s]+/'+folder_to_extract, tecleado): try: data = scrapertools.downloadpage(tecleado) matches = scrapertools.find_multiple_matches(data, '<td class="content">.*?href="([^"]+)".*?title="([^"]+)"') for url, filename in matches: url = "https://raw.githubusercontent.com" + url.replace("/blob/", "/") localfilename = filetools.join(local_folder, filename) files.append([url, localfilename, filename]) except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) platformtools.dialog_ok("Errore", "L'URL non è corretto o non disponibile") return else: filename = 'new%s.zip' % info_accion localfilename = filetools.join(config.get_data_path(), filename) files.append([tecleado, localfilename, filename]) zip = True logger.info("localfilename=%s" % localfilename) logger.info("descarga fichero...") try: if len(files) > 1: lista_opciones = ["No", "Si", "Si (Sovrascrivere tutto)"] overwrite_all = False from core import downloadtools for url, localfilename, filename in files: result = downloadtools.downloadfile(url, localfilename, continuar=False) if result == -3: if len(files) == 1: dyesno = platformtools.dialog_yesno("Il file esiste già", "%s %s esiste già. " "Vuoi sovrascrivere?" % (info_accion, filename)) else: if not overwrite_all: dyesno = platformtools.dialog_select("Il file %s esiste già, vuoi sovrascrivere?" % filename, lista_opciones) else: dyesno = 1 # Diálogo cancelado if dyesno == -1: return # Caso de carpeta github, opción sobrescribir todos elif dyesno == 2: overwrite_all = True elif dyesno: hora_folder = "Backup [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), 'backups', hora_folder, folder_to_extract) if not filetools.exists(backup): os.makedirs(backup) import shutil shutil.copy2(localfilename, filetools.join(backup, filename)) downloadtools.downloadfile(url, localfilename, continuar=True) else: if len(files) == 1: return else: continue except: import traceback logger.info("Detalle del error: %s" % traceback.format_exc()) return if zip: try: # Lo descomprime logger.info("descomprime fichero...") from core import ziptools unzipper = ziptools.ziptools() logger.info("destpathname=%s" % local_folder) unzipper.extract(localfilename, local_folder, folder_to_extract, True, True) except: import traceback logger.error("Detalle del error: %s" % traceback.format_exc()) # Borra el zip descargado filetools.remove(localfilename) platformtools.dialog_ok("Errore", "C'è stato un errore nell'estrazione del file") return # Borra el zip descargado logger.info("borra fichero...") filetools.remove(localfilename) logger.info("...fichero borrado") platformtools.dialog_ok("Successo", "Aggiornamento/installazione eseguita correttamente")
def setting_channel_new(item): import xbmcgui # Cargar lista de opciones (canales activos del usuario y que permitan búsqueda global) # ------------------------ lista = [] ids = [] lista_lang = [] lista_ctgs = [] channels_list = channelselector.filterchannels('all') for channel in channels_list: if channel.action == '': continue channel_parameters = channeltools.get_channel_parameters( channel.channel) # No incluir si en la configuracion del canal no existe "include_in_global_search" if not channel_parameters['include_in_global_search']: continue lbl = '%s' % channel_parameters['language'] lbl += ' %s' % ', '.join( config.get_localized_category(categ) for categ in channel_parameters['categories']) it = xbmcgui.ListItem(channel.title, lbl) it.setArt({'thumb': channel.thumbnail, 'fanart': channel.fanart}) lista.append(it) ids.append(channel.channel) lista_lang.append(channel_parameters['language']) lista_ctgs.append(channel_parameters['categories']) # Diálogo para pre-seleccionar # ---------------------------- preselecciones = [ 'Buscar con la selección actual', 'Modificar selección actual', 'Modificar partiendo de Recomendados', 'Modificar partiendo de Frecuentes', 'Modificar partiendo de Todos', 'Modificar partiendo de Ninguno', 'Modificar partiendo de Castellano', 'Modificar partiendo de Latino' ] presel_values = [ 'skip', 'actual', 'recom', 'freq', 'all', 'none', 'cast', 'lat' ] categs = [ 'movie', 'tvshow', 'documentary', 'anime', 'vos', 'direct', 'torrent' ] if config.get_setting('adult_mode') > 0: categs.append('adult') for c in categs: preselecciones.append('Modificar partiendo de %s' % config.get_localized_category(c)) presel_values.append(c) if item.action == 'setting_channel': # Configuración de los canales incluídos en la búsqueda del preselecciones[0] del presel_values[0] # else: # Llamada desde "buscar en otros canales" (se puede saltar la selección e ir directo a la búsqueda) ret = platformtools.dialog_select(config.get_localized_string(59994), preselecciones) if ret == -1: return False # pedido cancel if presel_values[ret] == 'skip': return True # continuar sin modificar elif presel_values[ret] == 'none': preselect = [] elif presel_values[ret] == 'all': preselect = range(len(ids)) elif presel_values[ret] in ['cast', 'lat']: preselect = [] for i, lg in enumerate(lista_lang): if presel_values[ret] in lg or '*' in lg: preselect.append(i) elif presel_values[ret] == 'actual': preselect = [] for i, canal in enumerate(ids): channel_status = config.get_setting('include_in_global_search', canal) if channel_status: preselect.append(i) elif presel_values[ret] == 'recom': preselect = [] for i, canal in enumerate(ids): _not, set_canal_list = channeltools.get_channel_controls_settings( canal) if set_canal_list.get('include_in_global_search', False): preselect.append(i) elif presel_values[ret] == 'freq': preselect = [] for i, canal in enumerate(ids): frequency = channeltools.get_channel_setting('frequency', canal, 0) if frequency > 0: preselect.append(i) else: preselect = [] for i, ctgs in enumerate(lista_ctgs): if presel_values[ret] in ctgs: preselect.append(i) # Diálogo para seleccionar # ------------------------ ret = xbmcgui.Dialog().multiselect(config.get_localized_string(59994), lista, preselect=preselect, useDetails=True) if not ret: return False # pedido cancel seleccionados = [ids[i] for i in ret] # Guardar cambios en canales para la búsqueda # ------------------------------------------- for canal in ids: channel_status = config.get_setting('include_in_global_search', canal) # if not channel_status: # channel_status = True if channel_status and canal not in seleccionados: config.set_setting('include_in_global_search', False, canal) elif not channel_status and canal in seleccionados: config.set_setting('include_in_global_search', True, canal) return True
def download_from_best_server(item, ask=False): logger.info("contentAction: %s | contentChannel: %s | url: %s" % (item.contentAction, item.contentChannel, item.url)) result = {"downloadStatus": STATUS_CODES.error} progreso = platformtools.dialog_progress( "Descargas", "Obteniendo lista de servidores disponibles...") channel = __import__('channels.%s' % item.contentChannel, None, None, ["channels.%s" % item.contentChannel]) progreso.update(50, "Obteniendo lista de servidores disponibles.", "Conectando con %s..." % item.contentChannel) if hasattr(channel, item.contentAction): play_items = getattr(channel, item.contentAction)(item.clone( action=item.contentAction, channel=item.contentChannel)) else: play_items = servertools.find_video_items( item.clone(action=item.contentAction, channel=item.contentChannel)) play_items = filter(lambda x: x.action == "play", play_items) progreso.update(100, "Obteniendo lista de servidores disponibles.", "Servidores disponibles: %s" % len(play_items), "Identificando servidores...") for i in play_items: if not i.server: i.server = servertools.get_server_from_url(i.url) if progreso.iscanceled(): return {"downloadStatus": STATUS_CODES.canceled} play_items.sort(key=sort_method) if progreso.iscanceled(): return {"downloadStatus": STATUS_CODES.canceled} progreso.close() if not ask: # Recorremos el listado de servers, hasta encontrar uno que funcione for play_item in play_items: play_item = item.clone(**play_item.__dict__) play_item.contentAction = play_item.action play_item.infoLabels = item.infoLabels result = download_from_server(play_item) if progreso.iscanceled(): result["downloadStatus"] = STATUS_CODES.canceled # Tanto si se cancela la descarga como si se completa dejamos de probar mas opciones if result["downloadStatus"] in [ STATUS_CODES.canceled, STATUS_CODES.completed ]: break else: seleccion = platformtools.dialog_select("Selecciona el servidor", [s.title for s in play_items]) if seleccion > -1: play_item = item.clone(**play_items[seleccion].__dict__) play_item.contentAction = play_item.action play_item.infoLabels = item.infoLabels result = download_from_server(play_item) else: result["downloadStatus"] = STATUS_CODES.canceled return result
def eliminar(item): 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 from platformcode import xbmc_library xbmc_library.clean() logger.info("Eliminados todos los enlaces") platformtools.itemlist_refresh() # logger.info(item.contentTitle) # logger.debug(item.tostring('\n')) if item.contentType == 'movie': heading = "Rimuovere film" else: heading = "Rimuovere serie" if item.multicanal: # Obtener listado de canales opciones = ["Rimuovere solo i link dei %s" % k.capitalize() for k in item.library_urls.keys() if k !="descargas"] opciones.insert(0, heading) index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index == 0: # Seleccionado Eliminar pelicula/serie eliminar_todo(item) elif index > 0: # Seleccionado Eliminar canal X canal = opciones[index].replace("Rimuovere solo i link dei ", "").lower() num_enlaces = 0 for fd in filetools.listdir(item.path): if fd.endswith(canal + '].json'): if filetools.remove(filetools.join(item.path, fd)): num_enlaces += 1 if num_enlaces > 0: # Actualizar .nfo head_nfo, item_nfo = library.read_nfo(item.nfo) del item_nfo.library_urls[canal] filetools.write(item.nfo, head_nfo + item_nfo.tojson()) msg_txt = "Cancellati %s collegamenti del canale %s" % (num_enlaces, canal) logger.info(msg_txt) platformtools.dialog_notification(heading, msg_txt) platformtools.itemlist_refresh() else: if platformtools.dialog_yesno(heading, "Vuoi davvero eliminare '%s' dalla tua libreria?" % item.infoLabels['title']): eliminar_todo(item)
def findvideos(item): from channels import autoplay logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] list_canales = {} item_local = None # Desactiva autoplay autoplay.set_status(False) if not item.contentTitle or not item.strm_path: logger.debug("No se pueden buscar videos por falta de parametros") return [] content_title = filter(lambda c: c not in ":*?<>|\/", item.contentTitle.strip().lower()) if item.contentType == 'movie': item.strm_path = filetools.join(videolibrarytools.MOVIES_PATH, item.strm_path) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, os.path.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(videolibrarytools.TVSHOWS_PATH, item.strm_path) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, 'tvshow.nfo') for fd in filetools.listdir(path_dir): if fd.endswith('.json'): contenido, nom_canal = fd[:-6].split('[') if (contenido.startswith(content_title) or item.contentType == 'movie') and nom_canal not in \ list_canales.keys(): list_canales[nom_canal] = filetools.join(path_dir, fd) num_canales = len(list_canales) if 'downloads' in list_canales: json_path = list_canales['downloads'] item_json = Item().fromjson(filetools.read(json_path)) item_json.contentChannel = "local" # Soporte para rutas relativas en descargas if filetools.is_relative(item_json.url): item_json.url = filetools.join(videolibrarytools.VIDEOLIBRARY_PATH, item_json.url) del list_canales['downloads'] # Comprobar q el video no haya sido borrado if filetools.exists(item_json.url): item_local = item_json.clone(action='play') itemlist.append(item_local) else: num_canales -= 1 filtro_canal = '' if num_canales > 1 and config.get_setting("ask_channel", "videolibrary"): opciones = [ config.get_localized_string(70089) % k.capitalize() for k in list_canales.keys() ] opciones.insert(0, config.get_localized_string(70083)) if item_local: opciones.append(item_local.title) from platformcode import platformtools index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index < 0: return [] elif item_local and index == len(opciones) - 1: filtro_canal = 'downloads' platformtools.play_video(item_local) elif index > 0: filtro_canal = opciones[index].replace( config.get_localized_string(70078), "").strip() itemlist = [] for nom_canal, json_path in list_canales.items(): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue item_canal = Item() item_canal.channel = nom_canal nom_canal = item_canal.channel # Importamos el canal de la parte seleccionada try: channel = __import__('channels.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) except ImportError: exec "import channels." + nom_canal + " as channel" item_json = Item().fromjson(filetools.read(json_path)) list_servers = [] try: # FILTERTOOLS # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente. if "list_language" in item_json: # si se viene desde la videoteca del addon if "library_filter_show" in item: item_json.show = item.library_filter_show.get( nom_canal, "") # Ejecutamos find_videos, del canal o común item_json.contentChannel = 'videolibrary' if hasattr(channel, 'findvideos'): from core import servertools list_servers = getattr(channel, 'findvideos')(item_json) list_servers = servertools.filter_servers(list_servers) else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception, ex: logger.error("Ha fallado la funcion findvideos para el canal %s" % nom_canal) template = "An exception of type %s occured. Arguments:\n%r" message = template % (type(ex).__name__, ex.args) logger.error(message) logger.error(traceback.format_exc()) # Cambiarle el titulo a los servers añadiendoles el nombre del canal delante y # las infoLabels y las imagenes del item si el server no tiene for server in list_servers: #if not server.action: # Ignorar/PERMITIR las etiquetas # continue server.contentChannel = server.channel server.channel = "videolibrary" server.nfo = item.nfo server.strm_path = item.strm_path #### Compatibilidad con Kodi 18: evita que se quede la ruedecedita dando vueltas en enlaces Directos if server.action == 'play': server.folder = False # Se añade el nombre del canal si se desea if config.get_setting("quit_channel_name", "videolibrary") == 0: server.title = "%s: %s" % (nom_canal.capitalize(), server.title) #server.infoLabels = item_json.infoLabels if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server)
def menu(item): logger.info() if item.downloadServer: servidor = item.downloadServer.get("server", "Auto") else: servidor = "Auto" # Opciones disponibles para el menu op = [ config.get_localized_string(70225), config.get_localized_string(70226), config.get_localized_string(70227), config.get_localized_string(30165) % (servidor.capitalize()) ] opciones = [] # Opciones para el menu if item.downloadStatus == 0: # Sin descargar opciones.append(op[0]) # Descargar if not item.server: opciones.append(op[3]) # Elegir Servidor opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 1: # descarga parcial opciones.append(op[0]) # Descargar if not item.server: opciones.append(op[3]) # Elegir Servidor opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista if item.downloadStatus == 2: # descarga completada opciones.append(op[1]) # Eliminar de la lista opciones.append(op[2]) # Reiniciar descarga if item.downloadStatus == 3: # descarga con error opciones.append(op[2]) # Reiniciar descarga opciones.append(op[1]) # Eliminar de la lista # Mostramos el dialogo seleccion = platformtools.dialog_select(config.get_localized_string(30163), opciones) # -1 es cancelar if seleccion == -1: return logger.info("option=%s" % (opciones[seleccion])) # Opcion Eliminar if opciones[seleccion] == op[1]: filetools.remove(item.path) # Opcion inicaiar descarga if opciones[seleccion] == op[0]: th = Thread(target=start_download, args=(item, )) th.start() # Elegir Servidor if opciones[seleccion] == op[3]: select_server(item) # Reiniciar descarga if opciones[seleccion] == op[2]: if filetools.isfile( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)): filetools.remove( os.path.join(config.get_setting("downloadpath"), item.downloadFilename)) update_json( item.path, { "downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0, "downloadServer": {} }) platformtools.itemlist_refresh()
def find_and_set_infoLabels(item): """ función que se llama para buscar y setear los infolabels :param item: :return: boleano que indica si se ha podido encontrar el 'code' """ global scraper scraper = None logger.debug("item:\n" + item.tostring('\n')) list_opciones_cuadro = ["Immettere un altro nome", "Informazioni complete"] # Si se añaden más scrapers hay q declararlos aqui-> "modulo_scraper": "Texto_en_cuadro" scrapers_disponibles = {'tmdb': "Cerca su TheMovieDB.org", 'tvdb': "Cerca su TheTvDB.com"} # Obtener el Scraper por defecto de la configuracion segun el tipo de contenido if item.contentType == "movie": scraper_actual = ['tmdb'][config.get_setting("scraper_movies", "biblioteca")] tipo_contenido = "película" title = item.contentTitle # Completar lista de opciones para este tipo de contenido list_opciones_cuadro.append(scrapers_disponibles['tmdb']) else: scraper_actual = ['tmdb', 'tvdb'][config.get_setting("scraper_tvshows", "biblioteca")] tipo_contenido = "serie" title = item.contentSerieName # Completar lista de opciones para este tipo de contenido list_opciones_cuadro.append(scrapers_disponibles['tmdb']) list_opciones_cuadro.append(scrapers_disponibles['tvdb']) # Importamos el scraper try: scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual]) except ImportError: exec "import core." + scraper_actual + " as scraper" while scraper: # Llamamos a la funcion find_and_set_infoLabels del scraper seleccionado scraper_result = scraper.find_and_set_infoLabels(item) # Verificar si existe 'code' if scraper_result and item.infoLabels['code']: # code correcto logger.info("Identificador encontrado: %s" % item.infoLabels['code']) scraper.completar_codigos(item) return True elif scraper_result: # Contenido encontrado pero no hay 'code' msg = "ID Non trovato per: %s" % title else: # Contenido no encontrado msg = "Nessuna informazione trovata per: %s" % title logger.info(msg) # Mostrar cuadro con otras opciones: if scrapers_disponibles[scraper_actual] in list_opciones_cuadro: list_opciones_cuadro.remove(scrapers_disponibles[scraper_actual]) index = platformtools.dialog_select(msg, list_opciones_cuadro) if index < 0: logger.debug("Se ha pulsado 'cancelar' en la ventana '%s'" % msg) return False elif index == 0: # Pregunta el titulo title = platformtools.dialog_input(title, "Introduzca el nombre de la %s a buscar" % tipo_contenido) if title: if item.contentType == "movie": item.contentTitle = title else: item.contentSerieName = title else: logger.debug("he pulsado 'cancelar' en la ventana 'Introduzca el nombre correcto'") return False elif index == 1: # Hay q crear un cuadro de dialogo para introducir los datos logger.info("Completar información") if cuadro_completar(item): # code correcto logger.info("Identificador encontrado: %s" % str(item.infoLabels['code'])) return True # raise elif list_opciones_cuadro[index] in scrapers_disponibles.values(): # Obtener el nombre del modulo del scraper for k, v in scrapers_disponibles.items(): if list_opciones_cuadro[index] == v: if scrapers_disponibles[scraper_actual] not in list_opciones_cuadro: list_opciones_cuadro.append(scrapers_disponibles[scraper_actual]) # Importamos el scraper k scraper_actual = k try: scraper = None scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual]) except ImportError: exec "import core." + scraper_actual + " as scraper_module" break logger.error("Error al importar el modulo scraper %s" % scraper_actual)
def abandomoviez_search(item): logger.info("fusionse.channels.trailertools abandomoviez_search") # Comprueba si es una búsqueda de cero o viene de la opción Siguiente if item.page != "": data = scrapertools.downloadpage(item.page) else: titulo = item.contentTitle.decode('utf-8').encode('iso-8859-1') post = urllib.urlencode({'query': titulo, 'searchby': '1', 'posicion': '1', 'orden': '1', 'anioin': item.year, 'anioout': item.year, 'orderby': '1'}) url = "http://www.abandomoviez.net/db/busca_titulo_advance.php" item.prefix = "db/" data = scrapertools.downloadpage(url, post=post) if "No hemos encontrado ninguna" in data: url = "http://www.abandomoviez.net/indie/busca_titulo_advance.php" item.prefix = "indie/" data = scrapertools.downloadpage(url, post=post).decode("iso-8859-1").encode('utf-8') logger.info(data) itemlist = [] devuelve = [] patron = '(?:<td width="85"|<div class="col-md-2 col-sm-2 col-xs-3">).*?<img src="([^"]+)"' \ '.*?href="([^"]+)">(.*?)(?:<\/td>|<\/small>)' matches = scrapertools.find_multiple_matches(data, patron) # Si solo hay un resultado busca directamente los trailers, sino lista todos los resultados if len(matches) == 1: item.url = urlparse.urljoin("http://www.abandomoviez.net/%s" % item.prefix, matches[0][1]) item.thumbnail = matches[0][0] devuelve = search_links_abando(item) elif len(matches) > 1: for scrapedthumbnail, scrapedurl, scrapedtitle in matches: scrapedurl = urlparse.urljoin("http://www.abandomoviez.net/%s" % item.prefix, scrapedurl) scrapedtitle = scrapertools.htmlclean(scrapedtitle) itemlist.append(item.clone(title=scrapedtitle, action="search_links_abando", url=scrapedurl, thumbnail=scrapedthumbnail, text_color="white")) next_page = scrapertools.find_single_match(data, '<a href="([^"]+)">Siguiente') if next_page != "": next_page = urlparse.urljoin("http://www.abandomoviez.net/%s" % item.prefix, next_page) itemlist.append(item.clone(title=">> Siguiente", action="abandomoviez_search", page=next_page, thumbnail="", text_color="")) if item.contextual: opciones = [] for item_abando in itemlist: opciones.append(item_abando.title) seleccion = platformtools.dialog_select("Buscando: "+item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item_abando = itemlist[seleccion] if item_abando.title == ">> Siguiente": return buscartrailer(item_abando) else: devuelve = search_links_abando(item_abando) else: devuelve = itemlist if not devuelve: devuelve.append(item.clone(title="La búsqueda no ha dado resultados", action="", thumbnail="", text_color="")) if keyboard: title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" devuelve.append(item.clone(title=title % "Búsqueda Manual en Abandomoviez", action="manual_search", thumbnail="", text_color="green", extra="abandomoviez")) return devuelve
def filmaffinity_search(item): logger.info("streamondemand.channels.trailertools filmaffinity_search") # Comprueba si es una búsqueda de cero o viene de la opción Siguiente if item.page != "": data = scrapertools.downloadpage(item.page) else: params = urllib.urlencode([('stext', item.contentTitle), ('stype%5B%5D', 'title'), ('country', ''), ('genre', ''), ('fromyear', item.year), ('toyear', item.year)]) url = "http://www.filmaffinity.com/es/advsearch.php?%s" % params data = scrapertools.downloadpage(url) devuelve = [] itemlist = [] patron = '<div class="mc-poster">.*?<img.*?src="([^"]+)".*?' \ '<div class="mc-title"><a href="/es/film(\d+).html"[^>]+>(.*?)<img' matches = scrapertools.find_multiple_matches(data, patron) # Si solo hay un resultado, busca directamente los trailers, sino lista todos los resultados if len(matches) == 1: item.url = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % matches[ 0][1] item.thumbnail = matches[0][0] if not item.thumbnail.startswith("http"): item.thumbnail = "http://www.filmaffinity.com" + item.thumbnail devuelve = search_links_filmaff(item) elif len(matches) > 1: for scrapedthumbnail, id, scrapedtitle in matches: if not scrapedthumbnail.startswith("http"): scrapedthumbnail = "http://www.filmaffinity.com" + scrapedthumbnail scrapedurl = "http://www.filmaffinity.com/es/evideos.php?movie_id=%s" % id scrapedtitle = unicode(scrapedtitle, encoding="utf-8", errors="ignore") scrapedtitle = scrapertools.htmlclean(scrapedtitle) itemlist.append( item.clone(title=scrapedtitle, url=scrapedurl, action="search_links_filmaff", thumbnail=scrapedthumbnail, text_color="white")) next_page = scrapertools.find_single_match( data, '<a href="([^"]+)">>></a>') if next_page != "": next_page = urlparse.urljoin("http://www.filmaffinity.com/es/", next_page) itemlist.append( item.clone(title=">> Siguiente", page=next_page, action="filmaffinity_search", thumbnail="", text_color="")) if item.contextual: opciones = [] for item_film in itemlist: opciones.append(item_film.title) seleccion = platformtools.dialog_select( "Buscando: " + item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item_film = itemlist[seleccion] if item_film.title == ">> Siguiente": return buscartrailer(item_film) else: devuelve = search_links_filmaff(item_film) else: devuelve = itemlist if not devuelve: devuelve.append( item.clone(title="La búsqueda no ha dado resultados (%s)" % item.contentTitle, action="", thumbnail="", text_color="")) if keyboard: title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" devuelve.append( item.clone(title=title % "Búsqueda Manual en Filmaffinity", action="manual_search", text_color="green", thumbnail="", extra="filmaffinity")) return devuelve
def buscartrailer(item): logger.info("fusionse.channels.trailertools buscartrailer") # Se elimina la opciçon de Buscar Trailer del menú contextual para evitar redundancias item.context = item.context.replace("5", "") item.text_color = "" # Si no se indica el parámetro contextual se entiende que no se ejecuta desde este mení if item.contextual == "": item.contextual = False itemlist = [] if item.contentTitle != "": item.contentTitle = item.contentTitle.strip() elif keyboard: item.contentTitle = platformtools.dialog_input(heading="Introduce el título a buscar") if item.contentTitle is None: item.contentTitle = item.fulltitle.strip() else: item.contentTitle = item.contentTitle.strip() else: item.contentTitle = item.fulltitle.strip() item.year = item.infoLabels['year'] if "year" in item.infoLabels else "" logger.info("fusionse.channels.trailertools Búsqueda: %s" % item.contentTitle) logger.info("fusionse.channels.trailertools Año: %s" % item.year) # Lista de acciones si se ejecuta desde el menú contextual if item.action == "manual_search": itemlist = manual_search(item) item.contentTitle = itemlist[0].contentTitle elif item.action == "youtube_search": itemlist = youtube_search(item) elif item.action == "filmaffinity_search": itemlist = filmaffinity_search(item) elif item.action == "abandomoviez_search": itemlist = abandomoviez_search(item) elif item.action == "jayhap_search": itemlist = jayhap_search(item) else: if "trailer" in item.infoLabels and item.infoLabels['trailer'] != "": url = item.infoLabels['trailer'] if "youtube" in url: url = url.replace("embed/", "watch?v=") titulo, url, server = servertools.findvideos(url)[0] title = "Trailer por defecto [" + server + "]" itemlist.append(item.clone(title=title, url=url, server=server, action="play")) if item.show != "" or ("tvshowtitle" in item.infoLabels and item.infoLabels['tvshowtitle'] != ""): type = "tv" else: type = "movie" try: itemlist.extend(tmdb_trailers(item, type)) except: import traceback logger.error(traceback.format_exc()) title = "[COLOR green]%s[/COLOR]" if item.contextual else "%s" itemlist.append(item.clone(title=title % "Búsqueda en Youtube", action="youtube_search", text_color="green")) itemlist.append(item.clone(title=title % "Búsqueda en Filmaffinity", action="filmaffinity_search", text_color="green")) # Si se trata de una serie, no se incluye la opción de buscar en Abandomoviez if item.show == "" and ("tvshowtitle" not in item.infoLabels or item.infoLabels['tvshowtitle'] == ""): itemlist.append(item.clone(title=title % "Búsqueda en Abandomoviez", action="abandomoviez_search", text_color="green")) itemlist.append(item.clone(title=title % "Búsqueda en Jayhap (Youtube, Vimeo & Dailymotion)", action="jayhap_search", text_color="green")) if item.contextual: opciones = [] if itemlist: for video_url in itemlist: opciones.append(video_url.title) seleccion = platformtools.dialog_select("Buscando: "+item.contentTitle, opciones) logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion]) if seleccion < 0: return else: item = itemlist[seleccion] if "search" in item.action: buscartrailer(item) else: if item.action == "play": from platformcode import xbmctools xbmctools.play_video(item) return else: return itemlist
def find_and_set_infoLabels(item): """ función que se llama para buscar y setear los infolabels :param item: :return: boleano que indica si se ha podido encontrar el 'code' """ global scraper scraper = None # logger.debug("item:\n" + item.tostring('\n')) list_opciones_cuadro = ["Immettere un altro nome", "Informazioni complete"] # Si se añaden más scrapers hay q declararlos aqui-> "modulo_scraper": "Texto_en_cuadro" scrapers_disponibles = {'tmdb': "Cerca su TheMovieDB.org", 'tvdb': "Cerca su TheTvDB.com"} # Obtener el Scraper por defecto de la configuracion segun el tipo de contenido if item.contentType == "movie": scraper_actual = ['tmdb'][config.get_setting("scraper_movies", "biblioteca")] tipo_contenido = "película" title = item.contentTitle # Completar lista de opciones para este tipo de contenido list_opciones_cuadro.append(scrapers_disponibles['tmdb']) else: scraper_actual = ['tmdb', 'tvdb'][config.get_setting("scraper_tvshows", "biblioteca")] tipo_contenido = "serie" title = item.contentSerieName # Completar lista de opciones para este tipo de contenido list_opciones_cuadro.append(scrapers_disponibles['tmdb']) list_opciones_cuadro.append(scrapers_disponibles['tvdb']) # Importamos el scraper try: scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual]) except ImportError: exec "import core." + scraper_actual + " as scraper" except: import traceback logger.error(traceback.format_exc()) while scraper: # Llamamos a la funcion find_and_set_infoLabels del scraper seleccionado scraper_result = scraper.find_and_set_infoLabels(item) # Verificar si existe 'code' if scraper_result and item.infoLabels['code']: # code correcto logger.info("Identificador encontrado: %s" % item.infoLabels['code']) scraper.completar_codigos(item) return True elif scraper_result: # Contenido encontrado pero no hay 'code' msg = "ID Non trovato per: %s" % title else: # Contenido no encontrado msg = "Nessuna informazione trovata per: %s" % title logger.info(msg) # Mostrar cuadro con otras opciones: if scrapers_disponibles[scraper_actual] in list_opciones_cuadro: list_opciones_cuadro.remove(scrapers_disponibles[scraper_actual]) index = platformtools.dialog_select(msg, list_opciones_cuadro) if index < 0: logger.debug("Se ha pulsado 'cancelar' en la ventana '%s'" % msg) return False elif index == 0: # Pregunta el titulo title = platformtools.dialog_input(title, "Inserire il nome %s per ricerca" % tipo_contenido) if title: if item.contentType == "movie": item.contentTitle = title else: item.contentSerieName = title else: logger.debug("he pulsado 'cancelar' en la ventana 'Introduzca el nombre correcto'") return False elif index == 1: # Hay q crear un cuadro de dialogo para introducir los datos logger.info("Completar información") if cuadro_completar(item): # code correcto logger.info("Identificador encontrado: %s" % str(item.infoLabels['code'])) return True # raise elif list_opciones_cuadro[index] in scrapers_disponibles.values(): # Obtener el nombre del modulo del scraper for k, v in scrapers_disponibles.items(): if list_opciones_cuadro[index] == v: if scrapers_disponibles[scraper_actual] not in list_opciones_cuadro: list_opciones_cuadro.append(scrapers_disponibles[scraper_actual]) # Importamos el scraper k scraper_actual = k try: scraper = None scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual]) except ImportError: exec "import core." + scraper_actual + " as scraper_module" break logger.error("Error al importar el modulo scraper %s" % scraper_actual)
def play_menu(item): if type(item) == list and len(item) == 1: item = item[0] #Modo Normal if type(item) == Item: if item.server == "": item.server = "directo" video_urls, puedes, motivo = servertools.resolve_video_urls_for_playing( item.server, item.url, item.password, True) #Modo "Play" en canal, puede devolver varias url elif type(item) == list and len(item) > 1: itemlist = item #En este caso en el argumento item, en realidad hay un itemlist item = itemlist[0] #Se asigna al item, el item primero del itemlist video_urls = [] for videoitem in itemlist: if videoitem.server == "": videoitem.server = "directo" opcion_urls, puedes, motivo = servertools.resolve_video_urls_for_playing( videoitem.server, videoitem.url) opcion_urls[0][ 0] = opcion_urls[0][0] + " [" + videoitem.fulltitle + "]" video_urls.extend(opcion_urls) item = itemlist[0] puedes = True motivo = "" if not "strmfile" in item: item.strmfile = False #TODO: unificar show y Serie ya que se usan indistintamente. if not "Serie" in item: item.Serie = item.show if item.server == "": item.server = "directo" opciones = check_video_options(item, video_urls) if not puedes: if item.server != "directo": motivo = motivo.replace("<br/>", "\n") platformtools.dialog_ok("No puedes ver ese vídeo porque...", motivo + "\n" + item.url) else: platformtools.dialog_ok( "No puedes ver ese vídeo porque...", "El servidor donde está alojado no está\nsoportado en pelisalacarta todavía\n" + item.url) if len(opciones) == 0: return default_action = config.get_setting("default_action") logger.info("default_action=" + default_action) # Si la accion por defecto es "Preguntar", pregunta if default_action == "0": seleccion = platformtools.dialog_select( config.get_localized_string(30163), [opcion.option for opcion in opciones]) elif default_action == "1": seleccion = 0 elif default_action == "2": seleccion = len(video_urls) - 1 elif default_action == "3": seleccion = seleccion else: seleccion = 0 if seleccion > -1: logger.info("seleccion=%d" % seleccion) logger.info("seleccion=%s" % opciones[seleccion].option) selecteditem = opciones[seleccion] del selecteditem.option run(opciones[seleccion]) return
def setting_channel_new(item): import xbmcgui # Load list of options (active user channels that allow global search) lista = [] ids = [] lista_lang = [] lista_ctgs = [] channels_list = channelselector.filterchannels('all') for channel in channels_list: if channel.action == '': continue channel_parameters = channeltools.get_channel_parameters(channel.channel) # Do not include if "include_in_global_search" does not exist in the channel configuration if not channel_parameters['include_in_global_search']: continue lbl = '%s' % channel_parameters['language'] lbl += ' %s' % ', '.join(config.get_localized_category(categ) for categ in channel_parameters['categories']) it = xbmcgui.ListItem(channel.title, lbl) it.setArt({'thumb': channel.thumbnail, 'fanart': channel.fanart}) lista.append(it) ids.append(channel.channel) lista_lang.append(channel_parameters['language']) lista_ctgs.append(channel_parameters['categories']) # Pre-select dialog preselecciones = [ config.get_localized_string(70570), config.get_localized_string(70571), # 'Modificar partiendo de Recomendados', # 'Modificar partiendo de Frecuentes', config.get_localized_string(70572), config.get_localized_string(70573), # 'Modificar partiendo de Castellano', # 'Modificar partiendo de Latino' ] # presel_values = ['skip', 'actual', 'recom', 'freq', 'all', 'none', 'cast', 'lat'] presel_values = ['skip', 'actual', 'all', 'none'] categs = ['movie', 'tvshow', 'documentary', 'anime', 'vos', 'direct', 'torrent'] for c in categs: preselecciones.append(config.get_localized_string(70577) + config.get_localized_category(c)) presel_values.append(c) if item.action == 'setting_channel': # Configuración de los canales incluídos en la búsqueda del preselecciones[0] del presel_values[0] # else: # Call from "search on other channels" (you can skip the selection and go directly to the search) ret = platformtools.dialog_select(config.get_localized_string(59994), preselecciones) if ret == -1: return False # order cancel if presel_values[ret] == 'skip': return True # continue unmodified elif presel_values[ret] == 'none': preselect = [] elif presel_values[ret] == 'all': preselect = list(range(len(ids))) elif presel_values[ret] in ['cast', 'lat']: preselect = [] for i, lg in enumerate(lista_lang): if presel_values[ret] in lg or '*' in lg: preselect.append(i) elif presel_values[ret] == 'actual': preselect = [] for i, canal in enumerate(ids): channel_status = config.get_setting('include_in_global_search', canal) if channel_status: preselect.append(i) elif presel_values[ret] == 'recom': preselect = [] for i, canal in enumerate(ids): _not, set_canal_list = channeltools.get_channel_controls_settings(canal) if set_canal_list.get('include_in_global_search', False): preselect.append(i) elif presel_values[ret] == 'freq': preselect = [] for i, canal in enumerate(ids): frequency = channeltools.get_channel_setting('frequency', canal, 0) if frequency > 0: preselect.append(i) else: preselect = [] for i, ctgs in enumerate(lista_ctgs): if presel_values[ret] in ctgs: preselect.append(i) # Dialog to select ret = platformtools.dialog_multiselect(config.get_localized_string(59994), lista, preselect=preselect, useDetails=True) if ret == None: return False # order cancel seleccionados = [ids[i] for i in ret] # Save changes to search channels for canal in ids: channel_status = config.get_setting('include_in_global_search', canal) # if not channel_status: # channel_status = True if channel_status and canal not in seleccionados: config.set_setting('include_in_global_search', False, canal) elif not channel_status and canal in seleccionados: config.set_setting('include_in_global_search', True, canal) return True
def channels_onoff(item): import channelselector from core import channeltools # Cargar lista de opciones # ------------------------ lista = [] ids = [] channels_list = channelselector.filterchannels('allchannelstatus') for channel in channels_list: channel_parameters = channeltools.get_channel_parameters( channel.channel) lbl = '%s' % channel_parameters['language'] # ~ lbl += ' %s' % [config.get_localized_category(categ) for categ in channel_parameters['categories']] lbl += ' %s' % ', '.join( config.get_localized_category(categ) for categ in channel_parameters['categories']) it = Item(fanart=channel.fanart, plot=lbl, thumbnail=channel.thumbnail, title=channel.title) lista.append(it) ids.append(channel.channel) if config.is_xbmc(): import xbmcgui new_list = list() for fake_it in lista: it = xbmcgui.ListItem(fake_it.title, fake_it.plot) it.setArt({'thumb': fake_it.thumbnail, 'fanart': fake_it.fanart}) new_list.append(it) lista = new_list # Diálogo para pre-seleccionar # ---------------------------- preselecciones = [ config.get_localized_string(70517), config.get_localized_string(70518), config.get_localized_string(70519) ] ret = platformtools.dialog_select(config.get_localized_string(60545), preselecciones) if ret == -1: return False # pedido cancel if ret == 2: preselect = [] elif ret == 1: preselect = list(range(len(ids))) else: preselect = [] for i, canal in enumerate(ids): channel_status = config.get_setting('enabled', canal) if channel_status is None: channel_status = True if channel_status: preselect.append(i) # Diálogo para seleccionar # ------------------------ ret = platformtools.dialog_multiselect(config.get_localized_string(60545), lista, preselect=preselect, useDetails=True) if ret == None: return False # pedido cancel seleccionados = [ids[i] for i in ret] # Guardar cambios en canales activados # ------------------------------------ for canal in ids: channel_status = config.get_setting('enabled', canal) if channel_status is None: channel_status = True if channel_status and canal not in seleccionados: config.set_setting('enabled', False, canal) elif not channel_status and canal in seleccionados: config.set_setting('enabled', True, canal) return False
def addchannel(item): import os import time logger.info() tecleado = platformtools.dialog_input("", "Introduzca la URL") if not tecleado: return logger.info("url=%s" % tecleado) local_folder = config.get_runtime_path() if "canal" in item.title: local_folder = filetools.join(local_folder, 'channels') folder_to_extract = "channels" info_accion = "canal" else: local_folder = filetools.join(local_folder, 'servers') folder_to_extract = "servers" info_accion = "conector" # Detecta si es un enlace a un .py o .xml (pensado sobre todo para enlaces de github) try: extension = tecleado.rsplit(".", 1)[1] except: extension = "" files = [] zip = False if extension == "py" or extension == "xml": filename = tecleado.rsplit("/", 1)[1] localfilename = filetools.join(local_folder, filename) files.append([tecleado, localfilename, filename]) else: import re from core import scrapertools # Comprueba si la url apunta a una carpeta completa (channels o servers) de github if re.search(r'https://github.com/[^\s]+/'+folder_to_extract, tecleado): try: data = scrapertools.downloadpage(tecleado) matches = scrapertools.find_multiple_matches(data, '<td class="content">.*?href="([^"]+)".*?title="([^"]+)"') for url, filename in matches: url = "https://raw.githubusercontent.com" + url.replace("/blob/", "/") localfilename = filetools.join(local_folder, filename) files.append([url, localfilename, filename]) except: import traceback logger.error("Detalle del error: %s" % traceback.format_exc()) platformtools.dialog_ok("Error", "La url no es correcta o no está disponible") return else: filename = 'new%s.zip' % info_accion localfilename = filetools.join(config.get_data_path(), filename) files.append([tecleado, localfilename, filename]) zip = True logger.info("localfilename=%s" % localfilename) logger.info("descarga fichero...") try: if len(files) > 1: lista_opciones = ["No", "Sí", "Sí (Sobrescribir todos)"] overwrite_all = False from core import downloadtools for url, localfilename, filename in files: result = downloadtools.downloadfile(url, localfilename, continuar=False, resumir=False) if result == -3: if len(files) == 1: dyesno = platformtools.dialog_yesno("El archivo ya existe", "Ya existe el %s %s. " "¿Desea sobrescribirlo?" % (info_accion, filename)) else: if not overwrite_all: dyesno = platformtools.dialog_select("El archivo %s ya existe, ¿desea sobrescribirlo?" % filename, lista_opciones) else: dyesno = 1 # Diálogo cancelado if dyesno == -1: return # Caso de carpeta github, opción sobrescribir todos elif dyesno == 2: overwrite_all = True elif dyesno: hora_folder = "Copia seguridad [%s]" % time.strftime("%d-%m_%H-%M", time.localtime()) backup = filetools.join(config.get_data_path(), 'backups', hora_folder, folder_to_extract) if not filetools.exists(backup): os.makedirs(backup) import shutil shutil.copy2(localfilename, filetools.join(backup, filename)) downloadtools.downloadfile(url, localfilename, continuar=True, resumir=False) else: if len(files) == 1: return else: continue except: import traceback logger.error("Detalle del error: %s" % traceback.format_exc()) return if zip: try: # Lo descomprime logger.info("descomprime fichero...") from core import ziptools unzipper = ziptools.ziptools() logger.info("destpathname=%s" % local_folder) unzipper.extract(localfilename, local_folder, folder_to_extract, True, True) except: import traceback logger.error("Detalle del error: %s" % traceback.format_exc()) # Borra el zip descargado filetools.remove(localfilename) platformtools.dialog_ok("Error", "Se ha producido un error extrayendo el archivo") return # Borra el zip descargado logger.info("borra fichero...") filetools.remove(localfilename) logger.info("...fichero borrado") platformtools.dialog_ok("Éxito", "Actualización/Instalación realizada correctamente")
def editar_enlace_thumbnail(item): logger.debug() alfav = KodfavouritesData() if not alfav.user_favorites[item.i_perfil]: return False if not alfav.user_favorites[item.i_perfil]['items'][item.i_enlace]: return False it = Item().fromurl( alfav.user_favorites[item.i_perfil]['items'][item.i_enlace]) # Starting with Kodi 17, you can use xbmcgui.Dialog (). Select with thumbnails (ListItem & useDetails = True) is_kodi17 = (config.get_platform(True)['num_version'] >= 17.0) if is_kodi17: import xbmcgui # Dialog to choose thumbnail (the channel or predefined icons) opciones = [] ids = [] try: from core import channeltools channel_parameters = channeltools.get_channel_parameters(it.channel) if channel_parameters['thumbnail'] != '': nombre = 'Canal %s' % it.channel if is_kodi17: it_thumb = xbmcgui.ListItem(nombre) it_thumb.setArt({'thumb': channel_parameters['thumbnail']}) opciones.append(it_thumb) else: opciones.append(nombre) ids.append(channel_parameters['thumbnail']) except: pass resource_path = os.path.join(config.get_runtime_path(), 'resources', 'media', 'themes', 'default') for f in sorted(os.listdir(resource_path)): if f.startswith('thumb_') and not f.startswith( 'thumb_intervenido') and f != 'thumb_back.png': nombre = f.replace('thumb_', '').replace('_', ' ').replace('.png', '') if is_kodi17: it_thumb = xbmcgui.ListItem(nombre) it_thumb.setArt({'thumb': os.path.join(resource_path, f)}) opciones.append(it_thumb) else: opciones.append(nombre) ids.append(os.path.join(resource_path, f)) if is_kodi17: ret = xbmcgui.Dialog().select(config.get_localized_string(70554), opciones, useDetails=True) else: ret = platformtools.dialog_select(config.get_localized_string(70554), opciones) if ret == -1: return False # order cancel it.thumbnail = ids[ret] alfav.user_favorites[item.i_perfil]['items'][item.i_enlace] = it.tourl() alfav.save() platformtools.itemlist_refresh() return True
def editar_enlace_thumbnail(item): logger.info() alfav = AlfavoritesData() if not alfav.user_favorites[item.i_perfil]: return False if not alfav.user_favorites[item.i_perfil]['items'][item.i_enlace]: return False it = Item().fromurl( alfav.user_favorites[item.i_perfil]['items'][item.i_enlace]) # A partir de Kodi 17 se puede usar xbmcgui.Dialog().select con thumbnails (ListItem & useDetails=True) is_kodi17 = (config.get_platform(True)['num_version'] >= 17.0) if is_kodi17: import xbmcgui # Diálogo para escoger thumbnail (el del canal o iconos predefinidos) opciones = [] ids = [] try: from core import channeltools channel_parameters = channeltools.get_channel_parameters(it.channel) if channel_parameters['thumbnail'] != '': nombre = 'Canal %s' % it.channel if is_kodi17: it_thumb = xbmcgui.ListItem(nombre) it_thumb.setArt({'thumb': channel_parameters['thumbnail']}) opciones.append(it_thumb) else: opciones.append(nombre) ids.append(channel_parameters['thumbnail']) except: pass resource_path = os.path.join(config.get_runtime_path(), 'resources', 'media', 'themes', 'default') for f in sorted(os.listdir(resource_path)): if f.startswith('thumb_') and not f.startswith( 'thumb_intervenido') and f != 'thumb_back.png': nombre = f.replace('thumb_', '').replace('_', ' ').replace('.png', '') if is_kodi17: it_thumb = xbmcgui.ListItem(nombre) it_thumb.setArt({'thumb': os.path.join(resource_path, f)}) opciones.append(it_thumb) else: opciones.append(nombre) ids.append(os.path.join(resource_path, f)) if is_kodi17: ret = xbmcgui.Dialog().select('Seleccionar thumbnail:', opciones, useDetails=True) else: ret = platformtools.dialog_select('Seleccionar thumbnail:', opciones) if ret == -1: return False # pedido cancel it.thumbnail = ids[ret] alfav.user_favorites[item.i_perfil]['items'][item.i_enlace] = it.tourl() alfav.save() platformtools.itemlist_refresh() return True
def set_adv_filter(item): logger.info() genreitems = filter_by_selection(Item(param="genre"), clearUrl=True) genres = ['Predeterminado (todos)'] for i in genreitems: genres.append(i.title) result = platformtools.dialog_select('Elige un género', genres, useDetails=False) if result != -1 and result != 0: item.filters['genre'] = genreitems[result - 1] elif result == -1: return True alphaitems = filter_by_selection(Item(param="alphabet"), clearUrl=True) letters = [] letters.append('Predeterminado (todas)') for i in alphaitems: letters.append(i.title) result = platformtools.dialog_select('Elige una letra inicial', letters, useDetails=False) if result != -1 and result != 0: item.filters['alphabet'] = alphaitems[result - 1] elif result == -1: return True censorstates = filter_by_selection(Item(param="censor"), clearUrl=True) censor = [] censor.append('Predeterminado (con y sin censura)') for i in censorstates: censor.append(i.title) result = platformtools.dialog_select('Elige el tipo de censura', censor, useDetails=False) if result != -1 and result != 0: item.filters['censor'] = censorstates[result - 1] elif result == -1: return True statusstates = filter_by_selection(Item(param="status"), clearUrl=True) statuses = [] statuses.append('Predeterminado (ambos)') for i in statusstates: statuses.append(i.title) result = platformtools.dialog_select('Elige el estado de emisión', statuses, useDetails=False) if result != -1 and result != 0: item.filters['status'] = statusstates[result - 1] elif result == -1: return True statusstates = filter_by_selection(Item(param="orderby"), clearUrl=True) statuses = [] statuses.append('Predeterminado (ambos)') for i in statusstates: statuses.append(i.title) result = platformtools.dialog_select('Elige cómo ordenar los resultados', statuses, useDetails=False) if result != -1 and result != 0: item.filters['orderby'] = statusstates[result - 1] if item.filters['genre'] or item.filters['alphabet'] or item.filters[ 'censor'] or item.filters['status'] or item.filters['orderby']: filtered_url = host current_filter = '' if item.filters['genre'] != '': current_filter += "Género: " + item.filters['genre'].title + ". " filtered_url += item.filters['genre'].url else: filtered_url += '/directorio' if item.filters['alphabet'] != '': current_filter += 'Inicial: ' + item.filters[ 'alphabet'].title + '. ' filtered_url += '?' + item.filters['alphabet'].url if item.filters['censor'] != '': current_filter += 'Censura: ' + item.filters['censor'].title + '. ' filtered_url += '&' + item.filters['censor'].url if item.filters['status'] != '': current_filter += 'Estado: ' + item.filters['status'].title + '. ' filtered_url += '&' + item.filters['status'].url if item.filters['orderby'] != '': current_filter += 'Estado: ' + item.filters['orderby'].title + '. ' filtered_url += '&' + item.filters['orderby'].url filteritem = Item(channel=item.channel, fanart=item.fanart, param='', url=filtered_url) return list_all(filteritem) else: return True
def findvideos(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] list_canales = {} item_local = None if not item.contentTitle or not item.strm_path: logger.debug("No se pueden buscar videos por falta de parametros") return [] content_title = filter(lambda c: c not in ":*?<>|\/", item.contentTitle).strip().lower() if item.contentType == 'movie': item.strm_path = filetools.join(library.MOVIES_PATH, item.strm_path.strip('\/')) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, os.path.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(library.TVSHOWS_PATH, item.strm_path.strip('\/')) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, 'tvshow.nfo') for fd in filetools.listdir(path_dir): if fd.endswith('.json'): contenido, nom_canal = fd[:-6].split('[') if (content_title in contenido.strip() or item.contentType == 'movie') and nom_canal not in \ list_canales.keys(): list_canales[nom_canal] = filetools.join(path_dir, fd) num_canales = len(list_canales) if 'descargas' in list_canales: json_path = list_canales['descargas'] item_json = Item().fromjson(filetools.read(json_path)) del list_canales['descargas'] # Comprobar q el video no haya sido borrado if filetools.exists(item_json.url): item_local = item_json.clone(action='play') itemlist.append(item_local) else: num_canales -= 1 filtro_canal = '' if num_canales > 1 and config.get_setting("ask_channel", "biblioteca") == True: opciones = ["Mostrar solo los enlaces de %s" % k.capitalize() for k in list_canales.keys()] opciones.insert(0, "Mostrar todos los enlaces") if item_local: opciones.append(item_local.title) from platformcode import platformtools index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index < 0: return [] elif item_local and index == len(opciones) - 1: filtro_canal = 'descargas' platformtools.play_video(item_local) elif index > 0: filtro_canal = opciones[index].replace("Mostrar solo los enlaces de ", "") itemlist = [] for nom_canal, json_path in list_canales.items(): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue # Importamos el canal de la parte seleccionada try: channel = __import__('channels.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) except ImportError: exec "import channels." + nom_canal + " as channel" item_json = Item().fromjson(filetools.read(json_path)) list_servers = [] try: # FILTERTOOLS # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente. if "list_idiomas" in item_json: # si se viene desde la biblioteca de pelisalacarta if "library_filter_show" in item: item_json.show = item.library_filter_show.get(nom_canal, "") # Ejecutamos find_videos, del canal o común if hasattr(channel, 'findvideos'): list_servers = getattr(channel, 'findvideos')(item_json) else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception as ex: logger.error("Ha fallado la funcion findvideos para el canal %s" % nom_canal) template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.error(message) # Cambiarle el titulo a los servers añadiendoles el nombre del canal delante y # las infoLabels y las imagenes del item si el server no tiene for server in list_servers: if not server.action: # Ignorar las etiquetas continue server.contentChannel = server.channel server.channel = "biblioteca" server.nfo = item.nfo server.strm_path = item.strm_path server.title = "%s: %s" % (nom_canal.capitalize(), server.title) server.infoLabels = item_json.infoLabels if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server) # return sorted(itemlist, key=lambda it: it.title.lower()) return itemlist
def acciones_peli(item): logger.info() tmdb_id = item.infoLabels['tmdb_id'] db = trackingtools.TrackingData() acciones = [] acciones.append('Información de enlaces guardados') acciones.append('Actualizar datos desde TMDB (themoviedb.org)') rows = db.get_movie_channels(tmdb_id) for channel, url in rows: acciones.append('Eliminar enlaces del canal [COLOR blue]%s[/COLOR]' % channel.encode('utf-8')) acciones.append('Eliminar película') acciones.append('Mover película a otra lista') acciones.append('Copiar película a otra lista') if config.get_setting('tracking_order_movies', default=0) == 0: # Si está ordenado por Updated opción para subirla a la primera de la lista modificando su updated. acciones.append('Mostrar película al principio de la lista') # Tratamiento de la acción escogida ret = platformtools.dialog_select(item.contentTitle, acciones) if ret == -1: db.close() return False # pedido cancel elif acciones[ret].startswith('Actualizar datos desde TMDB'): res, msg = trackingtools.update_infolabels_movie(tmdb_id) platformtools.dialog_notification('Actualizar de TMDB', msg) elif acciones[ret] == 'Mostrar película al principio de la lista': db.cur.execute('UPDATE movies SET updated=? WHERE tmdb_id=?', (datetime.now(), tmdb_id)) elif acciones[ret] == 'Eliminar película': if not platformtools.dialog_yesno('Eliminar película', '¿Estás seguro de querer borrar la película [COLOR gold]%s[/COLOR] con tmdb_id: %s ?' % (item.contentTitle, tmdb_id)): return False db.delete_movie(tmdb_id) elif acciones[ret].startswith('Eliminar enlaces del canal '): channel = config.quitar_colores(acciones[ret].replace('Eliminar enlaces del canal ', '')) db.delete_movie_channel(tmdb_id, channel) elif acciones[ret] == 'Información de enlaces guardados': txt = 'Película [B][COLOR gold]%s[/COLOR][/B] con tmdb_id: %s' % (item.contentTitle, tmdb_id) if len(rows) > 0: txt += '[CR][CR]Con enlaces a los canales: [COLOR blue]%s[/COLOR].' % ', '.join([channel.encode('utf-8') for channel, url in rows]) else: txt += '[CR][CR]No hay enlaces guardados a ningún canal.' db.close() platformtools.dialog_textviewer('Información de enlaces guardados', txt) return True elif acciones[ret] == 'Copiar película a otra lista' or acciones[ret] == 'Mover película a otra lista': operacion = 'copiada' if acciones[ret] == 'Copiar película a otra lista' else 'movida' # Diálogo para escoger lista opciones = [] itemlist_listas = mainlist_listas(item) for it in itemlist_listas: if it.lista != '' and '[lista activa]' not in it.title: # descarta item crear y lista activa opciones.append(it.title) if len(opciones) == 0: db.close() platformtools.dialog_ok(config.__addon_name, 'No hay otras listas dónde mover el enlace.', 'Puedes crearlas desde el menú Gestionar listas.') return False ret = platformtools.dialog_select('Seleccionar lista destino', opciones) if ret == -1: db.close() return False # pedido cancel dbname_destino = opciones[ret] filename_destino = filetools.join(trackingtools.get_tracking_path(), dbname_destino + '.sqlite') db.cur.execute('ATTACH DATABASE ? AS db_destino', (filename_destino,)) db.cur.execute('DELETE FROM db_destino.movies WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.channels_movies WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.movies SELECT * FROM movies WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.channels_movies SELECT * FROM channels_movies WHERE tmdb_id=?', (tmdb_id,)) if operacion == 'movida': db.cur.execute('DELETE FROM movies WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM channels_movies WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DETACH DATABASE db_destino') platformtools.dialog_notification(acciones[ret], '[COLOR gold]%s[/COLOR] %s a lista [COLOR blue]%s[/COLOR]' % (item.contentTitle, operacion, dbname_destino) ) if operacion == 'copiada': db.close(commit=True) return True # No necesita itemlist_refresh posterior db.close(commit=True) platformtools.itemlist_refresh() return True
def force_creation_advancedsettings(item): # advancedsettings path advancedsettings = xbmc.translatePath( "special://userdata/advancedsettings.xml") itemlist = [] try: risp = platformtools.dialog_select('Scegli settaggio cache', [ram[0], ram[1], ram[2], ram[3]]) #logger.info(str(risp)) if risp == 0: valore = opt[0] testo = "\n[COLOR orange]Cache Impostata per 512 Mega di RAM[/COLOR]" if risp == 1: valore = opt[1] testo = "\n[COLOR orange]Cache Impostata per 1 Gb di RAM[/COLOR]" if risp == 2: valore = opt[2] testo = "\n[COLOR orange]Cache Impostata per 2 Gb di RAM[/COLOR]" if risp == 3: valore = opt[3] testo = "\n[COLOR orange]Cache Impostata a superiore di 2 Gb di RAM[/COLOR]" if risp < 0: return itemlist file = '''<advancedsettings> <network> <buffermode>1</buffermode> <cachemembuffersize>''' + valore + '''</cachemembuffersize> <readbufferfactor>10</readbufferfactor> <autodetectpingtime>30</autodetectpingtime> <curlclienttimeout>60</curlclienttimeout> <curllowspeedtime>60</curllowspeedtime> <curlretries>2</curlretries> <disableipv6>true</disableipv6> </network> <gui> <algorithmdirtyregions>0</algorithmdirtyregions> <nofliptimeout>0</nofliptimeout> </gui> <playlistasfolders1>false</playlistasfolders1> <audio> <defaultplayer>dvdplayer</defaultplayer> </audio> <imageres>540</imageres> <fanartres>720</fanartres> <splash>false</splash> <handlemounting>0</handlemounting> <samba> <clienttimeout>30</clienttimeout> </samba> </advancedsettings>''' logger.info(file) salva = open(advancedsettings, "w") salva.write(file) salva.close() except: pass platformtools.dialog_ok("plugin", "E' stato creato un file advancedsettings.xml", "con la configurazione ideale per lo streaming.", testo) return platformtools.itemlist_refresh()
def acciones_serie(item): logger.info() tmdb_id = item.infoLabels['tmdb_id'] db = trackingtools.TrackingData() acciones = [] acciones.append('Información de enlaces guardados') acciones.append('Programar búsqueda automática de nuevos episodios') acciones.append('Buscar ahora nuevos episodios') acciones.append('Actualizar datos desde TMDB (themoviedb.org)') acciones.append('Actualizar datos desde TVDB (thetvdb.com)') # TODO? 'Vista/No vista' => bucle para todas las temporadas/episodios y marcarlos en bd_kodi_files !? De momento por temporada. # Diferentes canales con enlaces ya sea en serie, temporadas o episodios sql = 'SELECT DISTINCT channel FROM (' sql += ' SELECT DISTINCT channel FROM channels_shows WHERE tmdb_id=?' sql += ' UNION' sql += ' SELECT DISTINCT channel FROM channels_seasons WHERE tmdb_id=?' sql += ' UNION' sql += ' SELECT DISTINCT channel FROM channels_episodes WHERE tmdb_id=?' sql += ')' db.cur.execute(sql, (tmdb_id,tmdb_id,tmdb_id)) canales = db.cur.fetchall() # Ej: [(u'seriesblanco',), (u'seriespapaya',)] for (channel,) in canales: acciones.append('Eliminar enlaces del canal [COLOR blue]%s[/COLOR]' % channel.encode('utf-8')) acciones.append('Eliminar serie') acciones.append('Mover serie a otra lista') acciones.append('Copiar serie a otra lista') if config.get_setting('tracking_order_tvshows', default=0) == 0: # Si está ordenado por Updated opción para subirla a la primera de la lista modificando su updated. acciones.append('Mostrar serie al principio de la lista') # Tratamiento de la acción escogida ret = platformtools.dialog_select(item.contentSerieName, acciones) if ret == -1: db.close() return False # pedido cancel elif acciones[ret] == 'Mostrar serie al principio de la lista': db.cur.execute('UPDATE shows SET updated=? WHERE tmdb_id=?', (datetime.now(), tmdb_id)) elif acciones[ret] == 'Eliminar serie': if not platformtools.dialog_yesno('Eliminar serie', '¿Estás seguro de querer borrar la serie [COLOR gold]%s[/COLOR] con tmdb_id: %s ?' % (item.contentSerieName, tmdb_id)): return False db.delete_show(tmdb_id) elif acciones[ret].startswith('Eliminar enlaces del canal '): channel = config.quitar_colores(acciones[ret].replace('Eliminar enlaces del canal ', '')) db.delete_show_channel(tmdb_id, channel) elif acciones[ret].startswith('Actualizar datos desde TMDB'): res, msg = trackingtools.update_infolabels_show(tmdb_id) platformtools.dialog_notification('Actualizar de TMDB', msg) elif acciones[ret].startswith('Actualizar datos desde TVDB'): res, msg = trackingtools.update_infolabels_show(tmdb_id, with_tvdb=True) platformtools.dialog_notification('Actualizar de TVDB', msg) elif acciones[ret] == 'Información de enlaces guardados': txt = 'Serie [B][COLOR gold]%s[/COLOR][/B] con tmdb_id: %s' % (item.contentSerieName, tmdb_id) # Mostrar info de tracking db.cur.execute('SELECT periodicity, tvdbinfo, lastscrap FROM tracking_shows WHERE tmdb_id=?', (tmdb_id,)) row = db.cur.fetchone() if row is not None: periodicity = int(row[0]) # ~ txt += ', tiene activada la búsqueda automática de nuevos episodios cada %d horas' % int(row[0]) txt += ', tiene activada la búsqueda automática de nuevos episodios' if row[1] == 1: txt += ' con datos de TVDB' if periodicity == 0: txt += ' cada vez que se ejecute el servicio.' elif periodicity == 24: txt += ' una vez al día.' elif periodicity == 48: txt += ' cada dos días.' elif periodicity == 72: txt += ' cada tres días.' elif periodicity == 24*7: txt += ' una vez por semana.' else: txt += ' cada %d horas.' % periodicity if row[2]: dt_scrap = datetime.fromtimestamp(float(row[2])) txt += ' Última comprobación: %s.' % dt_scrap.strftime('%A %d/%m/%Y a las %H:%M') # Mostrar info de infolabels db.cur.execute('SELECT COUNT(*) FROM episodes WHERE tmdb_id=?', (tmdb_id,)) num_epi = db.cur.fetchone()[0] db.cur.execute('SELECT season FROM seasons WHERE tmdb_id=? ORDER BY season ASC', (tmdb_id,)) seasons = db.cur.fetchall() txt += '[CR][CR]%d episodios en %d temporadas. ' % (num_epi, len(seasons)) for (season,) in seasons: db.cur.execute('SELECT COUNT(*) FROM episodes WHERE tmdb_id=? AND season=?', (tmdb_id, season)) num_epi = db.cur.fetchone()[0] txt += ' [B]T%d[/B] (%d)' % (season, num_epi) # Mostrar info de enlaces txt += '[CR][CR]Enlaces a nivel de serie y temporadas:' for (channel,) in canales: guardados = [] db.cur.execute('SELECT channel FROM channels_shows WHERE tmdb_id=? AND channel=?', (tmdb_id, channel.encode('utf-8'))) if db.cur.fetchone() is not None: guardados.append('Serie') db.cur.execute('SELECT season FROM channels_seasons WHERE tmdb_id=? AND channel=? ORDER BY season ASC', (tmdb_id, channel.encode('utf-8'))) enlaces = db.cur.fetchall() for (season,) in enlaces: guardados.append('T%d' % season) if len(guardados) > 0: if 'Serie' in guardados and len(guardados) == 1: guardados = ['Temporadas y episodios en un mismo enlace'] txt += '[CR][COLOR blue]%s[/COLOR]: %s.' % (channel.encode('utf-8'), ', '.join(guardados)) else: txt += '[CR][COLOR blue]%s[/COLOR]: episodios sueltos.' % channel.encode('utf-8') txt += '[CR][CR]Episodios por canal:' for (channel,) in canales: # ~ db.cur.execute('SELECT season, episode FROM channels_episodes WHERE tmdb_id=? AND channel=? ORDER BY season ASC, episode ASC', (tmdb_id, channel.encode('utf-8'))) # ~ enlaces = db.cur.fetchall() # ~ if len(enlaces) > 0: # ~ txt += '[CR][COLOR blue]%s[/COLOR]:' % channel.encode('utf-8') # ~ for season, episode in enlaces: # ~ txt += ' %dx%d' % (season, episode) db.cur.execute('SELECT season, COUNT() FROM channels_episodes WHERE tmdb_id=? AND channel=? GROUP BY season ORDER BY season ASC', (tmdb_id, channel.encode('utf-8'))) enlaces = db.cur.fetchall() if len(enlaces) > 0: txt += '[CR][COLOR blue]%s[/COLOR]: %s' % (channel.encode('utf-8'), ', '.join(['T%d (%d)' % (season, count) for season, count in enlaces])) db.close() platformtools.dialog_textviewer('Información de enlaces guardados', txt) return True elif acciones[ret] == 'Programar búsqueda automática de nuevos episodios': db.cur.execute('SELECT periodicity, tvdbinfo FROM tracking_shows WHERE tmdb_id=?', (tmdb_id,)) row = db.cur.fetchone() if row is not None: if platformtools.dialog_yesno('Tracking', '¿ Desactivar la búsqueda automática de nuevos episodios para la serie [COLOR gold]%s[/COLOR] con tmdb_id: %s ?' % (item.contentSerieName, tmdb_id)): db.cur.execute('DELETE FROM tracking_shows WHERE tmdb_id=?', (tmdb_id,)) platformtools.dialog_notification(item.contentSerieName, 'Desactivada la búsqueda automática de nuevos episodios.') cambiar_opciones = False else: cambiar_opciones = True else: if not platformtools.dialog_yesno('Tracking', '¿ Activar la búsqueda automática de nuevos episodios para la serie [COLOR gold]%s[/COLOR] con tmdb_id: %s ?' % (item.contentSerieName, tmdb_id)): db.close() return False cambiar_opciones = True if cambiar_opciones: opciones = ['Cada vez que se ejecute el servicio', 'Una vez al día', 'Cada dos días', 'Cada tres días', 'Cada semana'] ret = platformtools.dialog_select('¿ Cada cuanto comprobar si hay nuevos episodios ?', opciones) if ret == -1: db.close() return False periodicity = 0 if ret == 0 else 24 if ret == 1 else 48 if ret == 2 else 72 if ret == 3 else 24*7 tvdbinfo = platformtools.dialog_yesno('Tracking', '¿ Quieres que se acceda a tvdb para recuperar datos de los nuevos episodios ? (bastante más lento pero en algunos casos se obtiene más información)') db.cur.execute('INSERT OR REPLACE INTO tracking_shows (tmdb_id, updated, periodicity, tvdbinfo) VALUES (?, ?, ?, ?)', (tmdb_id, datetime.now(), periodicity, tvdbinfo)) platformtools.dialog_notification(item.contentSerieName, 'Activada la búsqueda automática de nuevos episodios.') elif acciones[ret] == 'Buscar ahora nuevos episodios': db.cur.execute('SELECT tvdbinfo FROM tracking_shows WHERE tmdb_id=?', (tmdb_id,)) row = db.cur.fetchone() tvdbinfo = False if row is None else True if row[0] == 1 else False db.close() done, msg = trackingtools.search_new_episodes(tmdb_id, show_progress=True, tvdbinfo=tvdbinfo) return True elif acciones[ret] == 'Copiar serie a otra lista' or acciones[ret] == 'Mover serie a otra lista': operacion = 'copiada' if acciones[ret] == 'Copiar serie a otra lista' else 'movida' # Diálogo para escoger lista opciones = [] itemlist_listas = mainlist_listas(item) for it in itemlist_listas: if it.lista != '' and '[lista activa]' not in it.title: # descarta item crear y lista activa opciones.append(it.title) if len(opciones) == 0: db.close() platformtools.dialog_ok(config.__addon_name, 'No hay otras listas dónde mover el enlace.', 'Puedes crearlas desde el menú Gestionar listas.') return False ret = platformtools.dialog_select('Seleccionar lista destino', opciones) if ret == -1: db.close() return False # pedido cancel dbname_destino = opciones[ret] filename_destino = filetools.join(trackingtools.get_tracking_path(), dbname_destino + '.sqlite') db.cur.execute('ATTACH DATABASE ? AS db_destino', (filename_destino,)) db.cur.execute('DELETE FROM db_destino.shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.channels_shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.channels_seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.episodes WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM db_destino.channels_episodes WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.shows SELECT * FROM shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.channels_shows SELECT * FROM channels_shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.seasons SELECT * FROM seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.channels_seasons SELECT * FROM channels_seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.episodes SELECT * FROM episodes WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('INSERT INTO db_destino.channels_episodes SELECT * FROM channels_episodes WHERE tmdb_id=?', (tmdb_id,)) if operacion == 'movida': db.cur.execute('DELETE FROM shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM channels_shows WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM channels_seasons WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM episodes WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DELETE FROM channels_episodes WHERE tmdb_id=?', (tmdb_id,)) db.cur.execute('DETACH DATABASE db_destino') platformtools.dialog_notification(acciones[ret], '[COLOR gold]%s[/COLOR] %s a lista [COLOR blue]%s[/COLOR]' % (item.contentSerieName, operacion, dbname_destino) ) if operacion == 'copiada': db.close(commit=True) return True # No necesita itemlist_refresh posterior db.close(commit=True) platformtools.itemlist_refresh() return True
def findvideos(item): logger.info() # logger.debug("item:\n" + item.tostring('\n')) itemlist = [] list_canales = {} item_local = None if not item.contentTitle or not item.strm_path: logger.debug("No se pueden buscar videos por falta de parametros") return [] content_title = filter(lambda c: c not in ":*?<>|\/", item.contentTitle).strip().lower() if item.contentType == 'movie': item.strm_path = filetools.join(library.MOVIES_PATH, item.strm_path) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, os.path.basename(path_dir) + ".sod") else: item.strm_path = filetools.join(library.TVSHOWS_PATH, item.strm_path) path_dir = os.path.dirname(item.strm_path) item.nfo = filetools.join(path_dir, 'tvshow.sod') for fd in filetools.listdir(path_dir): if fd.endswith('.json'): contenido, nom_canal = fd[:-6].split('[') if (contenido.startswith(content_title) or item.contentType == 'movie') and nom_canal not in \ list_canales.keys(): list_canales[nom_canal] = filetools.join(path_dir, fd) num_canales = len(list_canales) # logger.debug(str(list_canales)) if 'descargas' in list_canales: json_path = list_canales['descargas'] item_json = Item().fromjson(filetools.read(json_path)) item_json.contentChannel = "local" # Soporte para rutas relativas en descargas if filetools.is_relative(item_json.url): item_json.url = filetools.join(library.LIBRARY_PATH, item_json.url) del list_canales['descargas'] # Comprobar q el video no haya sido borrado if filetools.exists(item_json.url): item_local = item_json.clone(action='play') itemlist.append(item_local) else: num_canales -= 1 filtro_canal = '' if num_canales > 1 and config.get_setting("ask_channel", "biblioteca") == True: opciones = [ "Mostra solo link %s" % k.capitalize() for k in list_canales.keys() ] opciones.insert(0, "Mosta tutti i collegamenti") if item_local: opciones.append(item_local.title) from platformcode import platformtools index = platformtools.dialog_select(config.get_localized_string(30163), opciones) if index < 0: return [] elif item_local and index == len(opciones) - 1: filtro_canal = 'descargas' platformtools.play_video(item_local) elif index > 0: filtro_canal = opciones[index].replace("Mostra solo link ", "") itemlist = [] for nom_canal, json_path in list_canales.items(): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue # Importamos el canal de la parte seleccionada try: channel = __import__('channels.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) except ImportError: exec "import channels." + nom_canal + " as channel" item_json = Item().fromjson(filetools.read(json_path)) list_servers = [] try: # FILTERTOOLS # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente. if "list_idiomas" in item_json: # si se viene desde la biblioteca de pelisalacarta if "library_filter_show" in item: item_json.show = item.library_filter_show.get( nom_canal, "") # Ejecutamos find_videos, del canal o común if hasattr(channel, 'findvideos'): list_servers = getattr(channel, 'findvideos')(item_json) else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception as ex: logger.error("Ha fallado la funcion findvideos para el canal %s" % nom_canal) template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logger.error(message) # Cambiarle el titulo a los servers añadiendoles el nombre del canal delante y # las infoLabels y las imagenes del item si el server no tiene for server in list_servers: if not server.action: # Ignorar las etiquetas continue server.contentChannel = server.channel server.channel = "biblioteca" server.nfo = item.nfo server.strm_path = item.strm_path # Se añade el nombre del canal si se desea if config.get_setting("quit_channel_name", "biblioteca") == 0: server.title = "%s: %s" % (nom_canal.capitalize(), server.title) server.infoLabels = item_json.infoLabels if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server) # return sorted(itemlist, key=lambda it: it.title.lower()) return itemlist
def play_from_library(item): """ Los .strm al reproducirlos desde kodi, este espera que sea un archivo "reproducible" asi que no puede contener más items, como mucho se puede colocar un dialogo de seleccion. Esto lo solucionamos "engañando a kodi" y haciendole creer que se ha reproducido algo, asi despues mediante "Container.Update()" cargamos el strm como si un item desde dentro de pelisalacarta se tratara, quitando todas las limitaciones y permitiendo reproducir mediante la funcion general sin tener que crear nuevos métodos para la biblioteca. @type item: item @param item: elemento con información """ logger.info() # logger.debug("item: \n" + item.tostring('\n')) import xbmcgui import xbmcplugin import xbmc # Intentamos reproducir una imagen (esto no hace nada y ademas no da error) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "icon.png"))) # Por si acaso la imagen hiciera (en futuras versiones) le damos a stop para detener la reproduccion xbmc.Player().stop() # modificamos el action (actualmente la biblioteca necesita "findvideos" ya que es donde se buscan las fuentes item.action = "findvideos" window_type = config.get_setting("window_type", "biblioteca") # y volvemos a lanzar kodi if xbmc.getCondVisibility('Window.IsMedia') and not window_type == 1: # Ventana convencional xbmc.executebuiltin("Container.Update(" + sys.argv[0] + "?" + item.tourl() + ")") else: # Ventana emergente from channels import biblioteca p_dialog = platformtools.dialog_progress_bg('streamondemand', 'Caricamento in corso...') p_dialog.update(0, '') itemlist = biblioteca.findvideos(item) p_dialog.update(50, '') # Se filtran los enlaces segun la lista blanca y negra if config.get_setting('filter_servers') == 'true': itemlist = filtered_servers(itemlist) # Se limita la cantidad de enlaces a mostrar if config.get_setting("max_links", "biblioteca") != 0: itemlist = limit_itemlist(itemlist) # Se "limpia" ligeramente la lista de enlaces if config.get_setting("replace_VD", "biblioteca") == 1: itemlist = reorder_itemlist(itemlist) p_dialog.update(100, '') xbmc.sleep(500) p_dialog.close() if len(itemlist) > 0: # El usuario elige el mirror opciones = [] for item in itemlist: opciones.append(item.title) # Se abre la ventana de seleccion if (item.contentSerieName != "" and item.contentSeason != "" and item.contentEpisodeNumber != ""): cabecera = ("%s - %sx%s -- %s" % (item.contentSerieName, item.contentSeason, item.contentEpisodeNumber, config.get_localized_string(30163))) else: cabecera = config.get_localized_string(30163) seleccion = platformtools.dialog_select(cabecera, opciones) if seleccion == -1: return else: item = biblioteca.play(itemlist[seleccion])[0] platformtools.play_video(item)