def ver_canales(item): logger.info("pelisalacarta.channels.novedades ver_canales") itemlist = [] for i in item.sub_list: newItem = Item() newItem = newItem.fromurl(i) logger.debug(newItem.tostring()) if 'contentCalidad' in newItem: newItem.title += ' (%s)' % newItem.contentCalidad if newItem.language: newItem.title += ' [%s]' % newItem.language newItem.title += ' (%s)' % newItem.channel itemlist.append(newItem.clone()) return itemlist
def ver_canales(item): logger.info() channels_ID_name = item.extra itemlist = [] for i in item.sub_list: newItem = Item() newItem = newItem.fromurl(i) #logger.debug(newItem.tostring()) if newItem.contentQuality: newItem.title += ' (%s)' % newItem.contentQuality if newItem.language: newItem.title += ' [%s]' % newItem.language newItem.title += ' (%s)' % channels_ID_name[newItem.channel] newItem.text_color = color1 itemlist.append(newItem.clone()) return itemlist
def show_channels(item): logger.info() global channels_id_name channels_id_name = item.extra itemlist = [] for i in item.sub_list: new_item = Item() new_item = new_item.fromurl(i) # logger.debug(new_item.tostring()) if new_item.contentQuality: new_item.title += ' (%s)' % new_item.contentQuality if new_item.language: new_item.title += ' [%s]' % new_item.language new_item.title += ' (%s)' % channels_id_name[new_item.channel] new_item.text_color = color1 itemlist.append(new_item.clone()) return itemlist
def find_video_items(item=None, data=None): """ Función genérica para buscar vídeos en una página, devolviendo un itemlist con los items listos para usar. - Si se pasa un Item como argumento, a los items resultantes mantienen los parametros del item pasado - Si no se pasa un Item, se crea uno nuevo, pero no contendra ningun parametro mas que los propios del servidor. @param item: Item al cual se quieren buscar vídeos, este debe contener la url válida @type item: Item @param data: Cadena con el contendio de la página ya descargado (si no se pasa item) @type data: str @return: devuelve el itemlist con los resultados @rtype: list """ logger.info() itemlist = [] # Descarga la página if data is None: data = httptools.downloadpage(item.url).data data = zcrypt.get_video_url(data) # Crea un item si no hay item if item is None: item = Item() # Pasa los campos thumbnail y title a contentThumbnail y contentTitle else: if not item.contentThumbnail: item.contentThumbnail = item.thumbnail if not item.contentTitle: item.contentTitle = item.title # Busca los enlaces a los videos for label, url, server, thumbnail in findvideos(data): title = config.get_localized_string(70206) % label itemlist.append( item.clone(title=title, action="play", url=url, thumbnail=thumbnail, server=server, folder=False)) return itemlist
def find_video_items(item=None, data=None): """ Generic function to search for videos on a page, returning an itemlist with the ready-to-use items. - If an Item is passed as an argument, the resulting items keep the parameters of the last item - If an Item is not passed, a new one is created, but it will not contain any parameters other than those of the server. @param item: Item to which you want to search for videos, this must contain the valid url @type item: Item @param data: String with the page content already downloaded (if item is not passed) @type data: str @return: returns the itemlist with the results @rtype: list """ logger.debug() itemlist = [] # Download the page if data is None: data = httptools.downloadpage(item.url).data data = unshortenit.findlinks(data) # Create an item if there is no item if item is None: item = Item() # Pass the thumbnail and title fields to contentThumbnail and contentTitle else: if not item.contentThumbnail: item.contentThumbnail = item.thumbnail if not item.contentTitle: item.contentTitle = item.title # Find the links to the videos for label, url, server, thumbnail in findvideos(data): title = label itemlist.append( item.clone(title=title, action="play", url=url, thumbnail=thumbnail, server=server, folder=False)) return itemlist
def add_download_items(item, itemlist): if config.get_setting('downloadenabled'): localOnly = True for i in itemlist: if i.contentChannel != 'local': localOnly = False break if not item.fromLibrary and not localOnly: downloadItem = Item(channel='downloads', from_channel=item.channel, title=typo(config.get_localized_string(60355), "color kod bold"), fulltitle=item.fulltitle, show=item.fulltitle, contentType=item.contentType, contentSerieName=item.contentSerieName, url=item.url, action='save_download', from_action="findvideos", contentTitle=item.contentTitle, path=item.path, thumbnail=thumb('downloads'), parent=item.tourl()) if item.action == 'findvideos': if item.contentType == 'episode': downloadItem.title = typo(config.get_localized_string(60356), "color kod bold") else: # film downloadItem.title = typo(config.get_localized_string(60354), "color kod bold") downloadItem.downloadItemlist = [i.tourl() for i in itemlist] itemlist.append(downloadItem) else: if item.contentSeason: # season downloadItem.title = typo(config.get_localized_string(60357), "color kod bold") itemlist.append(downloadItem) else: # tvshow + not seen itemlist.append(downloadItem) itemlist.append(downloadItem.clone(title=typo(config.get_localized_string(60003), "color kod bold"), unseen=True))
def run(item=None): # from core.support import dbg;dbg() logger.debug() if not item: # Extract item from sys.argv if sys.argv[2]: sp = sys.argv[2].split('&') url = sp[0] item = Item().fromurl(url) if len(sp) > 1: for e in sp[1:]: key, val = e.split('=') item.__setattr__(key, val) # If no item, this is mainlist else: item = Item(channel="channelselector", action="getmainlist", viewmode="movie") if not config.get_setting('show_once'): if not config.get_all_settings_addon(): logger.error('corrupted settings.xml!!') settings_xml = os.path.join(config.get_data_path(), "settings.xml") settings_bak = os.path.join(config.get_data_path(), "settings.bak") if filetools.exists(settings_bak): filetools.copy(settings_bak, settings_xml, True) logger.info('restored settings.xml from backup') else: filetools.write(settings_xml, '<settings version="2">\n</settings>' ) # resetted settings else: from platformcode import xbmc_videolibrary xbmc_videolibrary.ask_set_content(silent=False) config.set_setting('show_once', True) logger.info(item.tostring()) try: if not config.get_setting('tmdb_active'): config.set_setting('tmdb_active', True) # If item has no action, stops here if item.action == "": logger.debug("Item without action") return # Action for main menu in channelselector elif item.action == "getmainlist": import channelselector itemlist = channelselector.getmainlist() platformtools.render_items(itemlist, item) # Action for channel types on channelselector: movies, series, etc. elif item.action == "getchanneltypes": import channelselector itemlist = channelselector.getchanneltypes() platformtools.render_items(itemlist, item) # Action for channel listing on channelselector elif item.action == "filterchannels": import channelselector itemlist = channelselector.filterchannels(item.channel_type) platformtools.render_items(itemlist, item) # Special action for playing a video from the library elif item.action == "play_from_library": play_from_library(item) return elif item.action == "keymap": from platformcode import keymaptools if item.open: return keymaptools.open_shortcut_menu() else: return keymaptools.set_key() elif item.channel == "infoplus": from platformcode import infoplus return infoplus.Main(item) elif item.channel == "backup": from platformcode import backup return getattr(backup, item.action)(item) elif item.channel == "elementum_download": from platformcode import elementum_download return getattr(elementum_download, item.action)(item) elif item.channel == "shortcuts": from platformcode import shortcuts return getattr(shortcuts, item.action)(item) elif item.channel == "autorenumber": from platformcode import autorenumber return getattr(autorenumber, item.action)(item) elif item.action == "delete_key": from platformcode import keymaptools return keymaptools.delete_key() elif item.action == "script": from core import tmdb if tmdb.drop_bd(): platformtools.dialog_notification( config.get_localized_string(20000), config.get_localized_string(60011), time=2000, sound=False) elif item.action == "itemInfo": platformtools.dialog_textviewer('Item info', item.parent) elif item.action == "open_browser": import webbrowser if not webbrowser.open(item.url): import xbmc if xbmc.getCondVisibility( 'system.platform.linux') and xbmc.getCondVisibility( 'system.platform.android'): # android xbmc.executebuiltin( 'StartAndroidActivity("", "android.intent.action.VIEW", "", "%s")' % (item.url)) else: try: import urllib.request as urllib except ImportError: import urllib short = urllib.urlopen( 'https://u.nu/api.php?action=shorturl&format=simple&url=' + item.url).read().decode('utf-8') platformtools.dialog_ok( config.get_localized_string(20000), config.get_localized_string(70740) % short) # Action in certain channel specified in "action" and "channel" parameters elif item.action == "check_channels": from platformcode import checkhost checkhost.check_channels() else: # Checks if channel exists if os.path.isfile( os.path.join(config.get_runtime_path(), 'channels', item.channel + ".py")): CHANNELS = 'channels' else: CHANNELS = 'specials' channel_file = os.path.join(config.get_runtime_path(), CHANNELS, item.channel + ".py") logger.debug("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel) channel = None if os.path.exists(channel_file): try: channel = __import__('%s.%s' % (CHANNELS, item.channel), None, None, ['%s.%s' % (CHANNELS, item.channel)]) except ImportError: exec("import " + CHANNELS + "." + item.channel + " as channel") logger.info("Running channel %s | %s" % (channel.__name__, channel.__file__)) # Special play action if item.action == "play": # define la info para trakt try: from core import trakt_tools trakt_tools.set_trakt_info(item) except: pass logger.debug("item.action=%s" % item.action.upper()) # logger.debug("item_toPlay: " + "\n" + item.tostring('\n')) # First checks if channel has a "play" function if hasattr(channel, 'play'): logger.debug("Executing channel 'play' method") itemlist = channel.play(item) b_favourite = item.isFavourite # Play should return a list of playable URLS if len(itemlist) > 0 and isinstance(itemlist[0], Item): item = itemlist[0] if b_favourite: item.isFavourite = True platformtools.play_video(item) # Permitir varias calidades desde play en el Channel elif len(itemlist) > 0 and isinstance(itemlist[0], list): item.video_urls = itemlist platformtools.play_video(item) # If not, shows user an error message else: platformtools.dialog_ok( config.get_localized_string(20000), config.get_localized_string(60339)) # If player don't have a "play" function, not uses the standard play from platformtools else: logger.debug("Executing core 'play' method") platformtools.play_video(item) # Special action for findvideos, where the plugin looks for known urls elif item.action == "findvideos": from core import servertools # First checks if channel has a "findvideos" function if hasattr(channel, 'findvideos'): itemlist = getattr(channel, item.action)(item) # If not, uses the generic findvideos function else: logger.debug("No channel 'findvideos' method, " "executing core method") itemlist = servertools.find_video_items(item) if config.get_setting("max_links", "videolibrary") != 0: itemlist = limit_itemlist(itemlist) from platformcode import subtitletools subtitletools.saveSubtitleName(item) platformtools.render_items(itemlist, item) # Special action for adding a movie to the library elif item.action == "add_pelicula_to_library": from core import videolibrarytools videolibrarytools.add_movie(item) # Special action for adding a serie to the library elif item.action == "add_serie_to_library": from core import videolibrarytools videolibrarytools.add_tvshow(item, channel) # Special action for downloading all episodes from a serie elif item.action == "download_all_episodes": from specials import downloads item.action = item.extra del item.extra downloads.save_download(item) # Special action for searching, first asks for the words then call the "search" function elif item.action == "search": # from core.support import dbg;dbg() if filetools.isfile(temp_search_file) and config.get_setting( 'videolibrary_kodi'): itemlist = [] f = filetools.read(temp_search_file) strList = f.split(',') if strList[0] == '[V]' and strList[1] == item.channel: for it in strList: if it and it not in ['[V]', item.channel]: itemlist.append(Item().fromurl(it)) filetools.write(temp_search_file, f[4:]) return platformtools.render_items(itemlist, item) else: filetools.remove(temp_search_file) logger.debug("item.action=%s" % item.action.upper()) from core import channeltools if config.get_setting('last_search'): last_search = channeltools.get_channel_setting( 'Last_searched', 'search', '') else: last_search = '' search_text = platformtools.dialog_input(last_search) if search_text is not None: channeltools.set_channel_setting('Last_searched', search_text, 'search') itemlist = new_search(item.clone(text=search_text), channel) else: return platformtools.render_items(itemlist, item) # For all other actions else: # import web_pdb; web_pdb.set_trace() logger.debug("Executing channel '%s' method" % item.action) itemlist = getattr(channel, item.action)(item) if config.get_setting('trakt_sync'): from core import trakt_tools token_auth = config.get_setting("token_trakt", "trakt") if not token_auth: trakt_tools.auth_trakt() else: import xbmc if not xbmc.getCondVisibility( 'System.HasAddon(script.trakt)' ) and config.get_setting('install_trakt'): trakt_tools.ask_install_script() itemlist = trakt_tools.trakt_check(itemlist) else: config.set_setting('install_trakt', True) platformtools.render_items(itemlist, item) except WebErrorException as e: import traceback from core import scrapertools logger.error(traceback.format_exc()) platformtools.dialog_ok( config.get_localized_string(59985) % e.channel, config.get_localized_string(60013) % e.url) except Exception as e: import traceback from core import scrapertools logger.error(traceback.format_exc()) patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"' Channel = scrapertools.find_single_match(traceback.format_exc(), patron) if Channel or e.__class__ == logger.ChannelScraperException: if item.url: if platformtools.dialog_yesno( config.get_localized_string(60087) % Channel, config.get_localized_string(60014), nolabel='ok', yeslabel=config.get_localized_string(70739)): run(Item(action="open_browser", url=item.url)) else: platformtools.dialog_ok( config.get_localized_string(60087) % Channel, config.get_localized_string(60014)) else: if platformtools.dialog_yesno(config.get_localized_string(60038), config.get_localized_string(60015)): run(Item(channel="setting", action="report_menu"))
def findvideos(item): from core import autoplay logger.info() # logger.debug("item:\n" + item.tostring('\n')) videolibrarytools.check_renumber_options(item) itemlist = [] list_canales = {} item_local = None # Disable autoplay # autoplay.set_status(False) if not item.contentTitle or not item.strm_path: logger.debug("Unable to search for videos due to lack of parameters") return [] content_title = str(item.contentSeason) + 'x' + (str(item.contentEpisodeNumber) if item.contentEpisodeNumber > 9 else '0' + str(item.contentEpisodeNumber)) if item.contentType == 'movie': item.strm_path = filetools.join(videolibrarytools.MOVIES_PATH, item.strm_path) path_dir = filetools.dirname(item.strm_path) item.nfo = filetools.join(path_dir, filetools.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(videolibrarytools.TVSHOWS_PATH, item.strm_path) path_dir = filetools.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(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" # Support for relative paths in downloads if filetools.is_relative(item_json.url): item_json.url = filetools.join(videolibrarytools.VIDEOLIBRARY_PATH, item_json.url) del list_canales['downloads'] # Check that the video has not been deleted 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(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(list_canales.items()): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue item_canal = Item() # We import the channel of the selected part try: if nom_canal == 'community': channel = __import__('specials.%s' % nom_canal, fromlist=["channels.%s" % nom_canal]) else: 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 = [] # from core.support import dbg;dbg() try: # FILTERTOOLS # if the channel has a filter, the name it has saved is passed to it so that it filters correctly. if "list_language" in item_json: # if it comes from the addon video library if "library_filter_show" in item: item_json.show = item.library_filter_show.get(nom_canal, "") # We run find_videos, from the channel or common item_json.contentChannel = 'videolibrary' item_json.play_from = item.play_from item_json.nfo = item.nfo item_json.strm_path = item.strm_path if hasattr(channel, 'findvideos'): from core import servertools if item_json.videolibray_emergency_urls: del item_json.videolibray_emergency_urls list_servers = getattr(channel, 'findvideos')(item_json) elif item_json.action == 'play': from platformcode import platformtools # autoplay.set_status(True) item_json.contentChannel = item_json.channel item_json.channel = "videolibrary" platformtools.play_video(item_json) return '' else: from core import servertools list_servers = servertools.find_video_items(item_json) except Exception as ex: logger.error("The findvideos function for the channel %s failed" % 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()) # Change the title to the servers adding the name of the channel in front and the infoLabels and the images of the item if the server does not have for server in list_servers: server.contentChannel = server.channel server.channel = "videolibrary" server.nfo = item.nfo server.strm_path = item.strm_path server.play_from = item.play_from # Kodi 18 Compatibility - Prevents wheel from spinning around in Direct Links if server.action == 'play': server.folder = False # Channel name is added if desired if config.get_setting("quit_channel_name", "videolibrary") == 0: server.title = "%s: %s" % (nom_canal.capitalize(), server.title) if not server.thumbnail: server.thumbnail = item.thumbnail # logger.debug("server:\n%s" % server.tostring('\n')) itemlist.append(server) if autoplay.play_multi_channel(item, itemlist): # hideserver return [] add_download_items(item, itemlist) return itemlist
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(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) # logger.debug(str(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 = [ "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 = 'downloads' 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_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) # 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 = "videolibrary" 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", "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 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 scrap_and_save_tvshow(item, op='add', tvdbinfo=False): # Al añadir una serie se guardan los infolabels de serie + temporadas + episodios, y los enlaces al canal desde dónde se añade. # El item recibido tiene que tener tmdb_id informado y ser 'tvshow', 'season' o 'episode'. # También se requiere el channel+action y los parámetros necesarios para hacer la llamada al canal. # Con tvdbinfo=True, para cada episodio añadido se llama a tvdb para recuperar la info de allí. # # 'tvshow' : Se llama al canal para recuperar todas las temporadas, y para cada una de ellas todos sus capítulos. # 'season' : Se llama al canal para una temporada concreta y se obtienen todos sus capítulos. # 'episode' : Se llama al canal para un episodio concreto. # # Los datos recogidos al llamar a esta rutina dependerán de lo que devuelva el canal y de si se pasa una serie, una temporada o un episodio. # Ej: Si un canal solamente devuelve una temporada para una serie, se añade esa temporada. Si otro canal (o el mismo desde otro enlace) # devuelve dos temporadas para la misma serie, se completan los datos nuevos. # Ej: Si se llama para un episodio suelto desde algún listado de últimos capítulos, y la serie no está trackeada todavía, se añade el # enlace del canal al episodio, pero como no se dispone de la "url" para listar todas las temporadas o una temporada concreta, no # se puede añadir más. En cambio si se llama para la serie entera, se disponen de los enlaces a cada temporada y se pueden guardar. # # Devuelve True si se completa ok y False en caso contrario, más un texto con la información del error o proceso ok # logger.info() tmdb_id = item.infoLabels['tmdb_id'] if not tmdb_id: return False, 'Se requiere id de TMDB' if item.contentType not in ['tvshow', 'season', 'episode']: return False, 'contentType no contemplado!' # Tipo de scrap a realizar # ------------------------ if op == 'add': # Al añadir una serie/temp/epi desde el menú contextual, actualizar siempre urls, infolabels solamente si no existen. update_infolabels = False update_urls = True elif op == 'new_episodes': # Al buscar nuevos episodios, actualizar urls e infolabels solamente si no existen (episodios nuevos). update_infolabels = False update_urls = False else: return False, 'Invalid op!' # Conexión bd # ----------- db = TrackingData() cambios = [] # Para apuntar los cambios hechos en caso de refresco para buscar nuevos episodios # Datos a nivel de la serie # ------------------------- if not db.show_exists(tmdb_id): # Si no existe dar de alta if item.contentType == 'tvshow': # Si proviene de una serie ya se tienen los infolabels db.save_show(tmdb_id, item.infoLabels) else: # Sino buscar en tmdb it = Item( title='', contentType='tvshow', contentSerieName=item.contentSerieName, infoLabels={'tmdb_id': tmdb_id} ) from core import tmdb tmdb.set_infoLabels_item(it) db.save_show(tmdb_id, it.infoLabels) # Datos a nivel de serie+canal # ---------------------------- if item.contentType == 'tvshow': # Si proviene de serie, guardar su url if update_urls or not db.show_channel_exists(tmdb_id, item.channel): db.save_show_channel(tmdb_id, item.channel, item.clone(infoLabels={}).tourl()) # Cargar itemlist a tratar # ------------------------ if item.contentType in ['season', 'episode']: itemlist = [item] elif item.contentType == 'tvshow': try: canal = __import__('channels.' + item.channel, fromlist=['']) except: return False, 'El canal %s ya no existe' % item.channel # Si el canal tiene tracking_all_episodes usarlo para ir más rápido. # Excepción con newpct1, usar sólo tracking_all al añadir para que recorra todos los episodios, pero para actualizar mirar solamente en la primera página de episodios. if item.channel == 'newpct1' and op == 'new_episodes': buscar_tracking_all = False else: buscar_tracking_all = True if buscar_tracking_all and hasattr(canal, 'tracking_all_episodes'): itemlist = getattr(canal, 'tracking_all_episodes')(item) else: if hasattr(canal, item.action): itemlist = getattr(canal, item.action)(item) else: return False, 'En el canal %s ya no existe %s' % (item.channel, item.action) if itemlist is None or len(itemlist) == 0: db.close() return False, 'El canal no devuelve resultados' # Si es una actualización y el canal devuelve temporadas en lugar de episodios, solamente buscar episodios nuevos en la última temporada if op == 'new_episodes' and itemlist[0].contentType == 'season' and len(itemlist) > 1: itemlist = itemlist[-1:] # Datos a nivel de temporadas/episodios # ------------------------------------- # Si el canal devuelve una lista de temporadas if itemlist[0].contentType == 'season': try: canal = __import__('channels.' + item.channel, fromlist=['']) except: return False, 'El canal %s ya no existe' % item.channel for it in itemlist: # ~ logger.debug(it) if it.contentType != 'season': continue if it.infoLabels['tmdb_id'] != tmdb_id: continue # Guardar datos de la temporada if update_infolabels or not db.season_exists(tmdb_id, it.contentSeason): db.save_season(tmdb_id, it.contentSeason, it.infoLabels) # Guardar url para temporada+canal if update_urls or not db.season_channel_exists(tmdb_id, it.contentSeason, it.channel): db.save_season_channel(tmdb_id, it.contentSeason, it.channel, it.clone(infoLabels={}).tourl()) cambios.append('T%d' % it.contentSeason) # Llamar al canal para obtener episodios de la temporada if hasattr(canal, it.action): itemlist_epi = getattr(canal, it.action)(it) else: itemlist_epi = [] for it_epi in itemlist_epi: if it_epi.contentType != 'episode': continue if it_epi.contentSeason != it.contentSeason: continue if it_epi.infoLabels['tmdb_id'] != tmdb_id: continue # Guardar datos del episodio if update_infolabels or not db.episode_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber): if tvdbinfo and it_epi.infoLabels['tvdb_id']: from core import tvdb tvdb.set_infoLabels_item(it_epi) db.save_episode(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.infoLabels) # Guardar url para episodio+canal if update_urls or not db.episode_channel_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel): db.save_episode_channel(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel, it_epi.clone(infoLabels={}).tourl()) cambios.append('%dx%d' % (it_epi.contentSeason, it_epi.contentEpisodeNumber)) # Si el canal devuelve una lista de episodios elif itemlist[0].contentType == 'episode': ant_season = -1 # para no repetir llamadas mientras sea la misma temporada for it_epi in itemlist: # ~ logger.debug(it_epi) if it_epi.contentType != 'episode': continue if not it_epi.contentSeason: continue if it_epi.infoLabels['tmdb_id'] != tmdb_id: continue # Si no hay datos guardados de la temporada, buscarlos en tmdb y darlos de alta if ant_season != it_epi.contentSeason: if not db.season_exists(tmdb_id, it_epi.contentSeason): it = Item( title='', contentType='season', contentSerieName=it_epi.contentSerieName, contentSeason=it_epi.contentSeason, infoLabels={'tmdb_id': tmdb_id} ) from core import tmdb tmdb.set_infoLabels_item(it) db.save_season(tmdb_id, it.contentSeason, it.infoLabels) cambios.append('T%d' % it_epi.contentSeason) ant_season = it_epi.contentSeason # Guardar datos del episodio if update_infolabels or not db.episode_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber): if tvdbinfo and it_epi.infoLabels['tvdb_id']: from core import tvdb tvdb.set_infoLabels_item(it_epi) db.save_episode(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.infoLabels) # Guardar url para episodio+canal if update_urls or not db.episode_channel_exists(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel): db.save_episode_channel(tmdb_id, it_epi.contentSeason, it_epi.contentEpisodeNumber, it_epi.channel, it_epi.clone(infoLabels={}).tourl()) cambios.append('%dx%d' % (it_epi.contentSeason, it_epi.contentEpisodeNumber)) else: db.close() return False, 'El canal no devuelve temporadas ni episodios válidos' # Si es una actualización y ha habido cambios, actualizar updated de la tabla shows para que conste como actualizada if op == 'new_episodes' and len(cambios) > 0: db.cur.execute('UPDATE shows SET updated=? WHERE tmdb_id=?', (datetime.now(), tmdb_id)) # Cerrar conexión bd # ------------------ db.close(commit=True) # Si es una actualización informar de los cambios if op == 'new_episodes': return True, cambios # ~ if len(cambios) == 0: # ~ return False, 'No se detectan temporadas ni episodios nuevos.' # ~ else: # ~ return True, 'Añadidos enlaces para: [COLOR limegreen]%s[/COLOR]' % ', '.join(cambios) return True, 'Seguimiento serie con tmdb_id: %s' % tmdb_id
def findvideos(item): logger.info("pelisalacarta.channels.biblioteca findvideos") # 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") == "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: # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente. if item_json.list_idiomas: # si se viene desde la biblioteca de pelisalacarta if "library_filter_show" in item: item_json.show = item.library_filter_show.get( nom_canal, "") # si se viene desde la biblioteca de Kodi else: item_json.show = item_json.contentSerieName if item_json.show == "": logger.error( "Se ha producido un error al obtener el nombre de la serie a filtrar" ) # 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: logger.error("Ha fallado la funcion findvideos para el canal %s" % nom_canal) # 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 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 = [c for c in item.contentTitle.strip().lower() if c not in ":*?<>|\/"] content_title = "".join(c for c in item.contentTitle.strip().lower() if c not in ":*?<>|\/") if item.contentType == 'movie': item.strm_path = filetools.join(videolibrarytools.MOVIES_PATH, item.strm_path) path_dir = filetools.dirname(item.strm_path) item.nfo = filetools.join(path_dir, filetools.basename(path_dir) + ".nfo") else: item.strm_path = filetools.join(videolibrarytools.TVSHOWS_PATH, item.strm_path) path_dir = filetools.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(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)) ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial try: if item_json: item_json, it, overwrite = generictools.redirect_clone_newpct1( item_json) except: logger.error(traceback.format_exc()) 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(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(list_canales.items()): if filtro_canal and filtro_canal != nom_canal.capitalize(): continue item_canal = Item() item_canal.channel = nom_canal ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial try: item_canal, it, overwrite = generictools.redirect_clone_newpct1( item_canal) except: logger.error(traceback.format_exc()) 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)) item_json.nfo = item.nfo ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial try: if item_json: item_json, it, overwrite = generictools.redirect_clone_newpct1( item_json) except: logger.error(traceback.format_exc()) 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 if item_json.videolibray_emergency_urls: del item_json.videolibray_emergency_urls list_servers = getattr(channel, 'findvideos')(item_json) list_servers = servertools.filter_servers(list_servers) elif item_json.action == 'play': from platformcode import platformtools autoplay.set_status(True) item_json.contentChannel = item_json.channel item_json.channel = "videolibrary" platformtools.play_video(item_json) return '' 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 %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 y = -1 z_torrent_url = '' for x, server in enumerate(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 # Para downloads de Torrents desde ventana flotante (sin context menu) if server.contentChannel == 'downloads' and not server.sub_action: y = x if server.server == 'torrent' and server.contentChannel != 'downloads' and not z_torrent_url: z_torrent_url = server.url if server.contentChannel == 'downloads': server.channel = server.contentChannel #### 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) #Pego la url del primer torrent en el pseudo-context "Descargar" if y >= 0: itemlist[y].url = z_torrent_url # return sorted(itemlist, key=lambda it: it.title.lower()) autoplay.play_multi_channel(item, itemlist) from inspect import stack from channels import nextep if nextep.check(item) and stack()[1][3] == 'run': nextep.videolibrary(item) return itemlist