From f7c85c97ddb41b4131f05b4ec15a66798c4e3e0d Mon Sep 17 00:00:00 2001 From: Alhaziel01 Date: Mon, 11 May 2020 19:40:20 +0200 Subject: [PATCH] Fix Download Torrent --- platformcode/platformtools.py | 770 ++++++++++++++++------------------ servers/torrent.py | 378 +++++++++-------- specials/downloads.py | 205 +++++---- 3 files changed, 641 insertions(+), 712 deletions(-) diff --git a/platformcode/platformtools.py b/platformcode/platformtools.py index aef668ab..a9d4aee0 100644 --- a/platformcode/platformtools.py +++ b/platformcode/platformtools.py @@ -2,9 +2,7 @@ # ------------------------------------------------------------ # platformtools # ------------------------------------------------------------ -# Herramientas responsables de adaptar los diferentes -# cuadros de dialogo a una plataforma en concreto, -# en este caso Kodi. +# Tools responsible for adapting the different dialog boxes to a specific platform. # version 2.0 # ------------------------------------------------------------ @@ -114,7 +112,7 @@ def dialog_numeric(_type, heading, default=""): return d -def dialog_textviewer(heading, text): # disponible a partir de kodi 16 +def dialog_textviewer(heading, text): # available from kodi 16 return xbmcgui.Dialog().textviewer(heading, text) @@ -178,7 +176,7 @@ def render_items(itemlist, parent_item): item.category = parent_item.category if not item.title: item.title = '' - # Si no hay action o es findvideos/play, folder=False porque no se va a devolver ningún listado + # If there is no action or it is findvideos / play, folder = False because no listing will be returned if item.action in ['play', '']: item.folder = False if item.fanart == "": @@ -208,8 +206,7 @@ def render_items(itemlist, parent_item): # context menu if parent_item.channel != 'special': - context_commands = def_context_commands + set_context_commands(item, item_url, parent_item, has_extendedinfo=has_extendedinfo, - superfavourites=superfavourites) + context_commands = def_context_commands + set_context_commands(item, item_url, parent_item, has_extendedinfo=has_extendedinfo, superfavourites=superfavourites) else: context_commands = def_context_commands listitem.addContextMenuItems(context_commands) @@ -292,266 +289,265 @@ def set_view_mode(item, parent_item): logger.info('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content) -def render_items_old(itemlist, parent_item): - """ - Función encargada de mostrar el itemlist en kodi, se pasa como parametros el itemlist y el item del que procede - @type itemlist: list - @param itemlist: lista de elementos a mostrar +# def render_items_old(itemlist, parent_item): +# """ +# Function responsible for displaying the itemlist in kodi, the itemlist and the item it comes from are passed as parameters +# @type itemlist: list +# @param itemlist: list of elements to show - @type parent_item: item - @param parent_item: elemento padre - """ - logger.info('INICIO render_items') - from core import httptools +# @type parent_item: item +# @param parent_item: parent element +# """ +# logger.info('START render_items') +# from core import httptools - # Si el itemlist no es un list salimos - if not isinstance(itemlist, list): - return +# # If the itemlist is not a list we leave +# if not isinstance(itemlist, list): +# return - if parent_item.start: - menu_icon = get_thumb('menu.png') - menu = Item(channel="channelselector", action="getmainlist", viewmode="movie", thumbnail=menu_icon, - title='Menu') - itemlist.insert(0, menu) +# if parent_item.start: +# menu_icon = get_thumb('menu.png') +# menu = Item(channel="channelselector", action="getmainlist", viewmode="movie", thumbnail=menu_icon, title='Menu') +# itemlist.insert(0, menu) - # Si no hay ningun item, mostramos un aviso - if not len(itemlist): - itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png'))) +# # If there is no item, we show a notice +# if not len(itemlist): +# itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png'))) - genre = False - if 'nero' in parent_item.title: - genre = True - anime = False - if 'anime' in channeltools.get_channel_parameters(parent_item.channel)['categories']: - anime = True - # try: - # force_unify = channeltools.get_channel_parameters(parent_item.channel)['force_unify'] - # except: - force_unify = False +# genre = False +# if 'nero' in parent_item.title: +# genre = True +# anime = False +# if 'anime' in channeltools.get_channel_parameters(parent_item.channel)['categories']: +# anime = True +# # try: +# # force_unify = channeltools.get_channel_parameters(parent_item.channel)['force_unify'] +# # except: +# force_unify = False - unify_enabled = False +# unify_enabled = False - has_extendedinfo = xbmc.getCondVisibility('System.HasAddon(script.extendedinfo)') +# has_extendedinfo = xbmc.getCondVisibility('System.HasAddon(script.extendedinfo)') - # Añadir SuperFavourites al menu contextual (1.0.53 o superior necesario) - sf_file_path = xbmc.translatePath("special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py") - check_sf = os.path.exists(sf_file_path) - superfavourites = check_sf and xbmc.getCondVisibility('System.HasAddon("plugin.program.super.favourites")') - # try: - # if channeltools.get_channel_parameters(parent_item.channel)['adult']: - # unify_enabled = False - # except: - # pass - # logger.debug('unify_enabled: %s' % unify_enabled) +# # Add SuperFavourites to context menu (1.0.53 or higher required) +# sf_file_path = xbmc.translatePath("special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py") +# check_sf = os.path.exists(sf_file_path) +# superfavourites = check_sf and xbmc.getCondVisibility('System.HasAddon("plugin.program.super.favourites")') +# # try: +# # if channeltools.get_channel_parameters(parent_item.channel)['adult']: +# # unify_enabled = False +# # except: +# # pass +# # logger.debug('unify_enabled: %s' % unify_enabled) - # Recorremos el itemlist - for item in itemlist: - # logger.debug(item) - # Si el item no contiene categoria, le ponemos la del item padre - item_url = item.tourl() - if item.category == "": - item.category = parent_item.category +# # We go through the itemlist +# for item in itemlist: +# # logger.debug(item) +# # If the item does not contain a category, we will add the parent item +# item_url = item.tourl() +# if item.category == "": +# item.category = parent_item.category - # Si title no existe, lo iniciamos como str, para evitar errones "NoType" - if not item.title: - item.title = '' +# # If title does not exist, we start it as str, to avoid "NoType" mistakes +# if not item.title: +# item.title = '' - # Si no hay action o es findvideos/play, folder=False porque no se va a devolver ningún listado - if item.action in ['play', '']: - item.folder = False +# # If there is no action or it is findvideos / play, folder = False because no listing will be returned +# if item.action in ['play', '']: +# item.folder = False - # Si el item no contiene fanart, le ponemos el del item padre - if item.fanart == "": - item.fanart = parent_item.fanart +# # If the item does not contain fanart, we put the one of the parent item +# if item.fanart == "": +# item.fanart = parent_item.fanart - if genre: - valid_genre = True - thumb = get_thumb(item.title, auto=True) - if thumb != '': - item.thumbnail = thumb - valid_genre = True - elif anime: - valid_genre = True - elif (('siguiente' in item.title.lower() and '>' in item.title) or ('pagina:' in item.title.lower())): - item.thumbnail = get_thumb("next.png") - elif 'add' in item.action: - if 'pelicula' in item.action: - item.thumbnail = get_thumb("add_to_videolibrary.png") - elif 'serie' in item.action: - item.thumbnail = get_thumb("add_to_videolibrary.png") +# if genre: +# valid_genre = True +# thumb = get_thumb(item.title, auto=True) +# if thumb != '': +# item.thumbnail = thumb +# valid_genre = True +# elif anime: +# valid_genre = True +# elif (('siguiente' in item.title.lower() and '>' in item.title) or ('pagina:' in item.title.lower())): +# item.thumbnail = get_thumb("next.png") +# elif 'add' in item.action: +# if 'pelicula' in item.action: +# item.thumbnail = get_thumb("add_to_videolibrary.png") +# elif 'serie' in item.action: +# item.thumbnail = get_thumb("add_to_videolibrary.png") - if (unify_enabled or force_unify) and parent_item.channel not in ['kodfavourites']: - # Formatear titulo con unify - item = unify.title_format(item) - else: - # Formatear titulo metodo old school - if item.text_color: - item.title = '[COLOR %s]%s[/COLOR]' % (item.text_color, item.title) - if item.text_bold: - item.title = '[B]%s[/B]' % item.title - if item.text_italic: - item.title = '[I]%s[/I]' % item.title +# if (unify_enabled or force_unify) and parent_item.channel not in ['kodfavourites']: +# # Format title with unify +# item = unify.title_format(item) +# else: +# # Format title method old school +# if item.text_color: +# item.title = '[COLOR %s]%s[/COLOR]' % (item.text_color, item.title) +# if item.text_bold: +# item.title = '[B]%s[/B]' % item.title +# if item.text_italic: +# item.title = '[I]%s[/I]' % item.title - # Añade headers a las imagenes si estan en un servidor con cloudflare - if item.action == 'play': - item.thumbnail = unify.thumbnail_type(item) - else: - item.thumbnail = httptools.get_url_headers(item.thumbnail) - item.fanart = httptools.get_url_headers(item.fanart) +# # Add headers to images if they are on a server with cloudflare +# if item.action == 'play': +# item.thumbnail = unify.thumbnail_type(item) +# else: +# item.thumbnail = httptools.get_url_headers(item.thumbnail) +# item.fanart = httptools.get_url_headers(item.fanart) - # IconImage para folder y video - if item.folder: - icon_image = "DefaultFolder.png" - else: - icon_image = "DefaultVideo.png" +# # Icon Image for folder and video +# if item.folder: +# icon_image = "DefaultFolder.png" +# else: +# icon_image = "DefaultVideo.png" - # Ponemos el fanart - if item.fanart: - fanart = item.fanart - else: - fanart = config.get_fanart() +# # fanart +# if item.fanart: +# fanart = item.fanart +# else: +# fanart = config.get_fanart() - # Creamos el listitem - listitem = xbmcgui.ListItem(item.title) +# # Create listitem +# listitem = xbmcgui.ListItem(item.title) - # values icon, thumb or poster are skin dependent.. so we set all to avoid problems - # if not exists thumb it's used icon value - if config.get_platform(True)['num_version'] >= 16.0: - listitem.setArt({'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail, - 'fanart': fanart}) - else: - listitem.setIconImage(icon_image) - listitem.setThumbnailImage(item.thumbnail) - listitem.setProperty('fanart_image', fanart) +# # values icon, thumb or poster are skin dependent.. so we set all to avoid problems +# # if not exists thumb it's used icon value +# if config.get_platform(True)['num_version'] >= 16.0: +# listitem.setArt({'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail, +# 'fanart': fanart}) +# else: +# listitem.setIconImage(icon_image) +# listitem.setThumbnailImage(item.thumbnail) +# listitem.setProperty('fanart_image', fanart) - # No need it, use fanart instead - # xbmcplugin.setPluginFanart(int(sys.argv[1]), os.path.join(config.get_runtime_path(), "fanart.jpg")) +# # No need it, use fanart instead +# # xbmcplugin.setPluginFanart(int(sys.argv[1]), os.path.join(config.get_runtime_path(), "fanart.jpg")) - # Esta opcion es para poder utilizar el xbmcplugin.setResolvedUrl() - # if item.isPlayable == True or (config.get_setting("player_mode") == 1 and item.action == "play"): - if config.get_setting("player_mode") == 1 and item.action == "play": - listitem.setProperty('IsPlayable', 'true') +# # This option is to be able to use the xbmcplugin.setResolvedUrl() +# # if item.isPlayable == True or (config.get_setting("player_mode") == 1 and item.action == "play"): +# if config.get_setting("player_mode") == 1 and item.action == "play": +# listitem.setProperty('IsPlayable', 'true') - # Añadimos los infoLabels - set_infolabels(listitem, item) +# # Add infoLabels +# set_infolabels(listitem, item) - # No arrastrar plot si no es una peli/serie/temporada/episodio - if item.plot and item.contentType not in ['movie', 'tvshow', 'season', 'episode']: - item.__dict__['infoLabels'].pop('plot') +# # Do not drag plot if it is not a movie / series / season / episode +# if item.plot and item.contentType not in ['movie', 'tvshow', 'season', 'episode']: +# item.__dict__['infoLabels'].pop('plot') - # Montamos el menu contextual - if parent_item.channel != 'special': - context_commands = set_context_commands(item, item_url, parent_item, has_extendedinfo=has_extendedinfo, superfavourites=superfavourites) - else: - context_commands = [] - # Añadimos el menu contextual - if config.get_platform(True)['num_version'] >= 17.0 and parent_item.list_type == '': - listitem.addContextMenuItems(context_commands) - elif parent_item.list_type == '': - listitem.addContextMenuItems(context_commands, replaceItems=True) +# # Mount context menu +# if parent_item.channel != 'special': +# context_commands = set_context_commands(item, item_url, parent_item, has_extendedinfo=has_extendedinfo, superfavourites=superfavourites) +# else: +# context_commands = [] +# # Add context menu +# if config.get_platform(True)['num_version'] >= 17.0 and parent_item.list_type == '': +# listitem.addContextMenuItems(context_commands) +# elif parent_item.list_type == '': +# listitem.addContextMenuItems(context_commands, replaceItems=True) - from specials import shortcuts - context_commands += shortcuts.context() +# from specials import shortcuts +# context_commands += shortcuts.context() - if not item.totalItems: - item.totalItems = 0 - xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url='%s?%s' % (sys.argv[0], item_url), - listitem=listitem, isFolder=item.folder, - totalItems=item.totalItems) +# if not item.totalItems: +# item.totalItems = 0 +# xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url='%s?%s' % (sys.argv[0], item_url), +# listitem=listitem, isFolder=item.folder, +# totalItems=item.totalItems) - # Fijar los tipos de vistas... - if config.get_setting("forceview"): # ...forzamos segun el viewcontent - xbmcplugin.setContent(int(sys.argv[1]), parent_item.viewcontent) +# # Set types of views ... +# if config.get_setting("forceview"): # ...force according to the viewcontent +# xbmcplugin.setContent(int(sys.argv[1]), parent_item.viewcontent) - elif parent_item.channel not in ["channelselector", "", "kodfavourites"]: # ... o segun el canal - xbmcplugin.setContent(int(sys.argv[1]), "movies") +# elif parent_item.channel not in ["channelselector", "", "kodfavourites"]: # ... or according to the channel +# xbmcplugin.setContent(int(sys.argv[1]), "movies") - elif parent_item.channel == "kodfavourites" and parent_item.action == 'mostrar_perfil': - xbmcplugin.setContent(int(sys.argv[1]), "movies") +# elif parent_item.channel == "kodfavourites" and parent_item.action == 'mostrar_perfil': +# xbmcplugin.setContent(int(sys.argv[1]), "movies") - # Fijamos el "breadcrumb" - if parent_item.list_type == '': - breadcrumb = parent_item.category.capitalize() - else: - if 'similar' in parent_item.list_type: - if parent_item.contentTitle != '': - breadcrumb = config.get_localized_string(70693) + parent_item.contentTitle - else: - breadcrumb = config.get_localized_string(70693) + parent_item.contentSerieName - else: - breadcrumb = config.get_localized_string(70693) +# # set "breadcrumb" +# if parent_item.list_type == '': +# breadcrumb = parent_item.category.capitalize() +# else: +# if 'similar' in parent_item.list_type: +# if parent_item.contentTitle != '': +# breadcrumb = config.get_localized_string(70693) + parent_item.contentTitle +# else: +# breadcrumb = config.get_localized_string(70693) + parent_item.contentSerieName +# else: +# breadcrumb = config.get_localized_string(70693) - xbmcplugin.setPluginCategory(handle=int(sys.argv[1]), category=breadcrumb) +# xbmcplugin.setPluginCategory(handle=int(sys.argv[1]), category=breadcrumb) - # No ordenar items - xbmcplugin.addSortMethod(handle=int(sys.argv[1]), sortMethod=xbmcplugin.SORT_METHOD_NONE) +# # Do not sort items +# xbmcplugin.addSortMethod(handle=int(sys.argv[1]), sortMethod=xbmcplugin.SORT_METHOD_NONE) - # Cerramos el directorio - xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) +# # We close the directory +# xbmcplugin.endOfDirectory(handle=int(sys.argv[1]), succeeded=True) - # Fijar la vista - # if config.get_setting("forceview"): - # viewmode_id = get_viewmode_id(parent_item) - # xbmc.executebuiltin("Container.SetViewMode(%s)" % viewmode_id) - # if parent_item.mode in ['silent', 'get_cached', 'set_cache', 'finish']: - # xbmc.executebuiltin("Container.SetViewMode(500)") +# # Fix the view +# # if config.get_setting("forceview"): +# # viewmode_id = get_viewmode_id(parent_item) +# # xbmc.executebuiltin("Container.SetViewMode(%s)" % viewmode_id) +# # if parent_item.mode in ['silent', 'get_cached', 'set_cache', 'finish']: +# # xbmc.executebuiltin("Container.SetViewMode(500)") - logger.info('END render_items') +# logger.info('END render_items') -def get_viewmode_id(parent_item): - # viewmode_json habria q guardarlo en un archivo y crear un metodo para q el user fije sus preferencias en: - # user_files, user_movies, user_tvshows, user_season y user_episodes. - viewmode_json = {'skin.confluence': {'default_files': 50, - 'default_movies': 515, - 'default_tvshows': 508, - 'default_seasons': 503, - 'default_episodes': 504, - 'view_list': 50, - 'view_thumbnails': 500, - 'view_movie_with_plot': 503}, - 'skin.estuary': {'default_files': 50, - 'default_movies': 54, - 'default_tvshows': 502, - 'default_seasons': 500, - 'default_episodes': 53, - 'view_list': 50, - 'view_thumbnails': 500, - 'view_movie_with_plot': 54}} +# def get_viewmode_id(parent_item): +# # viewmode_json would have to save it in a file and create a method for the user to set their preferences in: +# # user_files, user_movies, user_tvshows, user_season and user_episodes. +# viewmode_json = {'skin.confluence': {'default_files': 50, +# 'default_movies': 515, +# 'default_tvshows': 508, +# 'default_seasons': 503, +# 'default_episodes': 504, +# 'view_list': 50, +# 'view_thumbnails': 500, +# 'view_movie_with_plot': 503}, +# 'skin.estuary': {'default_files': 50, +# 'default_movies': 54, +# 'default_tvshows': 502, +# 'default_seasons': 500, +# 'default_episodes': 53, +# 'view_list': 50, +# 'view_thumbnails': 500, +# 'view_movie_with_plot': 54}} - # Si el parent_item tenia fijado un viewmode usamos esa vista... - if parent_item.viewmode == 'movie': - # Remplazamos el antiguo viewmode 'movie' por 'thumbnails' - parent_item.viewmode = 'thumbnails' +# # If the parent_item had a viewmode set we use that view ... +# if parent_item.viewmode == 'movie': +# # We replace the old viewmode 'movie' with 'thumbnails' +# parent_item.viewmode = 'thumbnails' - if parent_item.viewmode in ["list", "movie_with_plot", "thumbnails"]: - view_name = "view_" + parent_item.viewmode +# if parent_item.viewmode in ["list", "movie_with_plot", "thumbnails"]: +# view_name = "view_" + parent_item.viewmode - '''elif isinstance(parent_item.viewmode, int): - # only for debug - viewName = parent_item.viewmode''' +# '''elif isinstance(parent_item.viewmode, int): +# # only for debug +# viewName = parent_item.viewmode''' - # ...sino ponemos la vista por defecto en funcion del viewcontent - else: - view_name = "default_" + parent_item.viewcontent +# # ...otherwise we put the default view according to the viewcontent +# else: +# view_name = "default_" + parent_item.viewcontent - skin_name = xbmc.getSkinDir() - if skin_name not in viewmode_json: - skin_name = 'skin.confluence' - view_skin = viewmode_json[skin_name] - return view_skin.get(view_name, 50) +# skin_name = xbmc.getSkinDir() +# if skin_name not in viewmode_json: +# skin_name = 'skin.confluence' +# view_skin = viewmode_json[skin_name] +# return view_skin.get(view_name, 50) def set_infolabels(listitem, item, player=False): """ - Metodo para pasar la informacion al listitem (ver tmdb.set_InfoLabels() ) - item.infoLabels es un dicionario con los pares de clave/valor descritos en: - http://mirrors.xbmc.org/docs/python-docs/14.x-helix/xbmcgui.html#ListItem-setInfo - https://kodi.wiki/view/InfoLabels - @param listitem: objeto xbmcgui.ListItem - @type listitem: xbmcgui.ListItem - @param item: objeto Item que representa a una pelicula, serie o capitulo - @type item: item + Method to pass the information to the listitem (see tmdb.set_InfoLabels()) +    item.infoLabels is a dictionary with the key / value pairs described in: +    http://mirrors.xbmc.org/docs/python-docs/14.x-helix/xbmcgui.html#ListItem-setInfo +    https://kodi.wiki/view/InfoLabels +    @param listitem: xbmcgui.ListItem object +    @type listitem: xbmcgui.ListItem +    @param item: Item object that represents a movie, series or chapter +    @type item: item """ infoLabels_dict = {'aired': 'aired', 'album': 'album', 'artist': 'artist', 'cast': 'cast', @@ -611,38 +607,37 @@ def set_infolabels(listitem, item, player=False): def set_context_commands(item, item_url, parent_item, **kwargs): """ - Función para generar los menus contextuales. - 1. Partiendo de los datos de item.context - a. Metodo antiguo item.context tipo str separando las opciones por "|" (ejemplo: item.context = "1|2|3") - (solo predefinidos) - b. Metodo list: item.context es un list con las diferentes opciones del menu: - - Predefinidos: Se cargara una opcion predefinida con un nombre. - item.context = ["1","2","3"] + Function to generate context menus. +        1. Based on the data in item.context +            a. Old method item.context type str separating options by "|" (example: item.context = "1 | 2 | 3") +                (only predefined) +            b. List method: item.context is a list with the different menu options: +                - Predefined: A predefined option will be loaded with a name. +                    item.context = ["1", "2", "3"] - - dict(): Se cargara el item actual modificando los campos que se incluyan en el dict() en caso de - modificar los campos channel y action estos serán guardados en from_channel y from_action. - item.context = [{"title":"Nombre del menu", "action": "action del menu", - "channel":"channel del menu"}, {...}] +                - dict (): The current item will be loaded modifying the fields included in the dict () in case of +                    modify the channel and action fields these will be saved in from_channel and from_action. +                    item.context = [{"title": "Name of the menu", "action": "action of the menu", "channel": "menu channel"}, {...}] - 2. Añadiendo opciones segun criterios - Se pueden añadir opciones al menu contextual a items que cumplan ciertas condiciones. +        2. Adding options according to criteria +            Options can be added to the context menu to items that meet certain conditions. - 3. Añadiendo opciones a todos los items - Se pueden añadir opciones al menu contextual para todos los items +        3. Adding options to all items +            Options can be added to the context menu for all items - 4. Se pueden deshabilitar las opciones del menu contextual añadiendo un comando 'no_context' al item.context. - Las opciones que Kodi, el skin u otro añadido añada al menu contextual no se pueden deshabilitar. +        4. You can disable the context menu options by adding a command 'no_context' to the item.context. +            The options that Kodi, the skin or another added add to the contextual menu cannot be disabled. - @param item: elemento que contiene los menu contextuales - @type item: item - @param parent_item: - @type parent_item: item +    @param item: element that contains the contextual menus +    @type item: item +    @param parent_item: +    @type parent_item: item """ context_commands = [] # num_version_xbmc = config.get_platform(True)['num_version'] - # Creamos un list con las diferentes opciones incluidas en item.context + # Create a list with the different options included in item.context if isinstance(item.context, str): context = item.context.split("|") elif isinstance(item.context, list): @@ -650,43 +645,41 @@ def set_context_commands(item, item_url, parent_item, **kwargs): else: context = [] - # Opciones segun item.context + # Options according to item.context for command in context: - # Predefinidos + # Predefined if isinstance(command, str): if command == "no_context": return [] - # Formato dict + # Dict format if isinstance(command, dict): - # Los parametros del dict, se sobreescriben al nuevo context_item en caso de sobreescribir "action" y - # "channel", los datos originales se guardan en "from_action" y "from_channel" + # The dict parameters are overwritten to the new context_item in case of overwriting "action" and + # "channel", the original data is saved in "from_action" and "from_channel" if "action" in command: command["from_action"] = item.action if "channel" in command: command["from_channel"] = item.channel - # Si no se está dentro de Alfavoritos y hay los contextos de alfavoritos, descartarlos. - # (pasa al ir a un enlace de alfavoritos, si este se clona en el canal) + # If you are not inside Alphavorites and there are the contexts for Alphavorites, discard them. + # (it happens when going to a link of alfavoritos, if this is cloned in the channel) if parent_item.channel != 'kodfavorites' and 'i_perfil' in command and 'i_enlace' in command: continue if "goto" in command: - context_commands.append((command["title"], "XBMC.Container.Refresh (%s?%s)" % - (sys.argv[0], item.clone(**command).tourl()))) + context_commands.append((command["title"], "XBMC.Container.Refresh (%s?%s)" % (sys.argv[0], item.clone(**command).tourl()))) else: - context_commands.append( - (command["title"], "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(**command).tourl()))) - # No añadir más opciones predefinidas si se está dentro de Alfavoritos + context_commands.append((command["title"], "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(**command).tourl()))) + # Do not add more predefined options if you are inside kodfavoritos if parent_item.channel == 'kodfavorites': return context_commands - # Opciones segun criterios, solo si el item no es un tag (etiqueta), ni es "Añadir a la videoteca", etc... + # Options according to criteria, only if the item is not a tag, nor is it "Add to the video library", etc... if item.action and item.action not in ["add_pelicula_to_library", "add_serie_to_library", "buscartrailer", "actualizar_titulos"]: - # Mostrar informacion: si el item tiene plot suponemos q es una serie, temporada, capitulo o pelicula + # Show information: if the item has a plot, we assume that it is a series, season, chapter or movie # if item.infoLabels['plot'] and (num_version_xbmc < 17.0 or item.contentType == 'season'): # context_commands.append((config.get_localized_string(60348), "XBMC.Action(Info)")) - # ExtendedInfo: Si está instalado el addon y se cumplen una serie de condiciones + # ExtendedInfo: If the addon is installed and a series of conditions are met if kwargs.get('has_extendedinfo') \ and config.get_setting("extended_info") == True: if item.contentType == "episode" and item.contentEpisodeNumber and item.contentSeason \ @@ -694,31 +687,22 @@ def set_context_commands(item, item_url, parent_item, **kwargs): param = "tvshow_id =%s, tvshow=%s, season=%s, episode=%s" \ % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason, item.contentEpisodeNumber) - context_commands.append(("ExtendedInfo", - "XBMC.RunScript(script.extendedinfo,info=extendedepisodeinfo,%s)" % param)) + context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedepisodeinfo,%s)" % param)) elif item.contentType == "season" and item.contentSeason \ and (item.infoLabels['tmdb_id'] or item.contentSerieName): param = "tvshow_id =%s,tvshow=%s, season=%s" \ % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason) - context_commands.append(("ExtendedInfo", - "XBMC.RunScript(script.extendedinfo,info=seasoninfo,%s)" % param)) + context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=seasoninfo,%s)" % param)) - elif item.contentType == "tvshow" and (item.infoLabels['tmdb_id'] or item.infoLabels['tvdb_id'] or - item.infoLabels['imdb_id'] or item.contentSerieName): - param = "id =%s,tvdb_id=%s,imdb_id=%s,name=%s" \ - % (item.infoLabels['tmdb_id'], item.infoLabels['tvdb_id'], item.infoLabels['imdb_id'], - item.contentSerieName) - context_commands.append(("ExtendedInfo", - "XBMC.RunScript(script.extendedinfo,info=extendedtvinfo,%s)" % param)) + elif item.contentType == "tvshow" and (item.infoLabels['tmdb_id'] or item.infoLabels['tvdb_id'] or item.infoLabels['imdb_id'] or item.contentSerieName): + param = "id =%s,tvdb_id=%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['tvdb_id'], item.infoLabels['imdb_id'], item.contentSerieName) + context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedtvinfo,%s)" % param)) - elif item.contentType == "movie" and (item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or - item.contentTitle): - param = "id =%s,imdb_id=%s,name=%s" \ - % (item.infoLabels['tmdb_id'], item.infoLabels['imdb_id'], item.contentTitle) + elif item.contentType == "movie" and (item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.contentTitle): + param = "id =%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['imdb_id'], item.contentTitle) - context_commands.append(("ExtendedInfo", - "XBMC.RunScript(script.extendedinfo,info=extendedinfo,%s)" % param)) + context_commands.append(("ExtendedInfo", "XBMC.RunScript(script.extendedinfo,info=extendedinfo,%s)" % param)) # InfoPlus if config.get_setting("infoplus"): #if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id'] or \ @@ -727,33 +711,25 @@ def set_context_commands(item, item_url, parent_item, **kwargs): context_commands.append(("InfoPlus", "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=infoplus&action=start&from_channel=' + item.channel))) - # Ir al Menu Principal (channel.mainlist) - if parent_item.channel not in ["news", "channelselector", "downloads"] and item.action != "mainlist" \ - and parent_item.action != "mainlist": - context_commands.insert(0, (config.get_localized_string(60349), "XBMC.Container.Refresh (%s?%s)" % - (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl()))) - context_commands.insert(1, (config.get_localized_string(70739), - "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", - url=item.url).tourl()))) + # Go to the Main Menu (channel.mainlist) + if parent_item.channel not in ["news", "channelselector", "downloads"] and item.action != "mainlist" and parent_item.action != "mainlist": + context_commands.insert(0, (config.get_localized_string(60349), "XBMC.Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl()))) + context_commands.insert(1, (config.get_localized_string(70739), "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))) - # Añadir a Favoritos + # Add to Favorites # if num_version_xbmc < 17.0 and \ # ((item.channel not in ["favorites", "videolibrary", "help", ""] # or item.action in ["update_videolibrary"]) and parent_item.channel != "favorites"): # context_commands.append((config.get_localized_string(30155), "XBMC.RunPlugin(%s?%s&%s)" % # (sys.argv[0], item_url, 'channel=favorites&action=addFavourite&from_channel=' + item.channel + '&from_action=' + item.action))) - # Añadir a Alfavoritos (Mis enlaces) + # Add to kodfavoritos (My links) if item.channel not in ["favorites", "videolibrary", "help", ""] and parent_item.channel != "favorites": - context_commands.append( - (config.get_localized_string(70557), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavourites", 'action': "addFavourite", - 'from_channel': item.channel, - 'from_action': item.action})))) - # Buscar en otros canales + context_commands.append( (config.get_localized_string(70557), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': "kodfavourites", 'action': "addFavourite", 'from_channel': item.channel, 'from_action': item.action})))) + # Search in other channels if item.contentType in ['movie', 'tvshow'] and item.channel != 'search' and item.action not in ['play'] and parent_item.action != 'mainlist': - # Buscar en otros canales + # Search in other channels if item.contentSerieName != '': item.wanted = item.contentSerieName else: @@ -764,88 +740,63 @@ def set_context_commands(item, item_url, parent_item, **kwargs): else: mediatype = item.contentType - context_commands.append((config.get_localized_string(60350), - "XBMC.Container.Update (%s?%s&%s)" % (sys.argv[0], - item_url, urllib.urlencode({'channel': 'search', - 'action': "from_context", - 'from_channel': item.channel, - 'contextual': True, - 'text': item.wanted})))) + context_commands.append((config.get_localized_string(60350), "XBMC.Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({'channel': 'search', 'action': "from_context", 'from_channel': item.channel, 'contextual': True, 'text': item.wanted})))) - context_commands.append( - (config.get_localized_string(70561), "XBMC.Container.Update (%s?%s&%s)" % ( - sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id'])))) - # Definir como Pagina de inicio + context_commands.append( (config.get_localized_string(70561), "XBMC.Container.Update (%s?%s&%s)" % (sys.argv[0], item_url, 'channel=search&action=from_context&search_type=list&page=1&list_type=%s/%s/similar' % (mediatype, item.infoLabels['tmdb_id'])))) + # Set as Home Page if config.get_setting('start_page'): if item.action not in ['episodios', 'seasons', 'findvideos', 'play']: - context_commands.insert(0, (config.get_localized_string(60351), - "XBMC.RunPlugin(%s?%s)" % ( - sys.argv[0], Item(channel='side_menu', - action="set_custom_start", - parent=item.tourl()).tourl()))) + context_commands.insert(0, (config.get_localized_string(60351), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], Item(channel='side_menu', action="set_custom_start", parent=item.tourl()).tourl()))) if item.channel != "videolibrary": - # Añadir Serie a la videoteca + # Add Series to the video library if item.action in ["episodios", "get_episodios", "get_seasons"] and item.contentSerieName: - context_commands.append((config.get_localized_string(60352), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action))) - # Añadir Pelicula a videoteca + context_commands.append((config.get_localized_string(60352), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action))) + # Add Movie to Video Library elif item.action in ["detail", "findvideos"] and item.contentType == 'movie' and item.contentTitle: - context_commands.append((config.get_localized_string(60353), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action))) + context_commands.append((config.get_localized_string(60353), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action))) if not item.local and item.channel not in ["downloads"] and item.server != 'torrent' and parent_item.action != 'mainlist' and config.get_setting('downloadenabled'): - # Descargar pelicula + # Download movie if item.contentType == "movie": - context_commands.append((config.get_localized_string(60354), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) + context_commands.append((config.get_localized_string(60354), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) elif item.contentSerieName: - # Descargar serie + # Descargar series if item.contentType == "tvshow" and item.action not in ['findvideos']: if item.channel == 'videolibrary': - context_commands.append((config.get_localized_string(60003), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, - 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action))) - context_commands.append((config.get_localized_string(60355), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) - context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))) - # Descargar episodio + context_commands.append((config.get_localized_string(60003), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action))) + context_commands.append((config.get_localized_string(60355), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) + context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))) + # Download episode elif item.contentType == "episode" or item.action in ['findvideos']: - context_commands.append((config.get_localized_string(60356), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) - # Descargar temporada + context_commands.append((config.get_localized_string(60356), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))) + # Download season elif item.contentType == "season": - context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % - (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))) + context_commands.append((config.get_localized_string(60357), "XBMC.RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))) - # # Abrir configuración + # # Open settings # if parent_item.channel not in ["setting", "news", "search"] and item.action == "play": # context_commands.append((config.get_localized_string(60358), "XBMC.Container.Update(%s?%s)" % # (sys.argv[0], Item(channel="setting", action="mainlist").tourl()))) - # Buscar Trailer + # Open settings... if item.action in ["findvideos", 'episodios', 'check'] or "buscar_trailer" in context: - context_commands.append( - (config.get_localized_string(60359), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], urllib.urlencode({ - 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.fulltitle if item.fulltitle else item.contentTitle, 'contextual': True})))) + context_commands.append((config.get_localized_string(60359), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.fulltitle if item.fulltitle else item.contentTitle, 'contextual': True})))) if kwargs.get('superfavourites'): - context_commands.append((config.get_localized_string(60361), - "XBMC.RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)")) + context_commands.append((config.get_localized_string(60361), "XBMC.RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)")) # context_commands = sorted(context_commands, key=lambda comand: comand[0]) - # Menu Rapido + # Quick Menu # context_commands.insert(0, (config.get_localized_string(60360), # "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(channel='side_menu', # action="open_menu", # parent=parent_item.tourl()).tourl( # )))) if config.dev_mode(): - context_commands.insert(0, ("item info", - "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl()))) + context_commands.insert(0, ("item info", "XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl()))) return context_commands @@ -874,32 +825,32 @@ def play_video(item, strm=False, force_direct=False, autoplay=False): default_action = config.get_setting("default_action") logger.info("default_action=%s" % default_action) - # Abre el diálogo de selección para ver las opciones disponibles + # Open the selection dialog to see the available options opciones, video_urls, seleccion, salir = get_dialogo_opciones(item, default_action, strm, autoplay) if salir: return - # se obtienen la opción predeterminada de la configuración del addon + # get default option of addon configuration seleccion = get_seleccion(default_action, opciones, seleccion, video_urls) - if seleccion < 0: # Cuadro cancelado + if seleccion < 0: # Canceled box return - logger.info("seleccion=%d" % seleccion) - logger.info("seleccion=%s" % opciones[seleccion]) + logger.info("selection=%d" % seleccion) + logger.info("selection=%s" % opciones[seleccion]) - # se ejecuta la opcion disponible, jdwonloader, descarga, favoritos, añadir a la videoteca... SI NO ES PLAY + # run the available option, jdwonloader, download, favorites, add to the video library ... IF IT IS NOT PLAY salir = set_opcion(item, seleccion, opciones, video_urls) if salir: return - # obtenemos el video seleccionado + # we get the selected video mediaurl, view, mpd = get_video_seleccionado(item, seleccion, video_urls) if mediaurl == "": return # # no certificate verification # mediaurl = mediaurl.replace('https://', 'http://') - # se obtiene la información del video. + # video information is obtained. if not item.contentThumbnail: thumb = item.thumbnail else: @@ -913,15 +864,15 @@ def play_video(item, strm=False, force_direct=False, autoplay=False): set_infolabels(xlistitem, item, True) - # si se trata de un vídeo en formato mpd, se configura el listitem para reproducirlo - # con el addon inpustreamaddon implementado en Kodi 17 + # if it is a video in mpd format, the listitem is configured to play it + # with the inpustreamaddon addon implemented in Kodi 17 if mpd: xlistitem.setProperty('inputstreamaddon', 'inputstream.adaptive') xlistitem.setProperty('inputstream.adaptive.manifest_type', 'mpd') - # se lanza el reproductor - if force_direct: # cuando viene de una ventana y no directamente de la base del addon - # Añadimos el listitem a una lista de reproducción (playlist) + # player launches + if force_direct: # when it comes from a window and not directly from the addon base + # We add the listitem to a playlist playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(mediaurl, xlistitem) @@ -938,18 +889,18 @@ def stop_video(): def get_seleccion(default_action, opciones, seleccion, video_urls): fixpri = False - # para conocer en que prioridad se trabaja + # to know what priority you work on priority = int(config.get_setting("resolve_priority")) - # se usara para comprobar si hay links premium o de debriders + # will be used to check for premium or debrider links check = [] - # Comprueba si resolve stop esta desactivado + # Check if resolve stop is disabled if config.get_setting("resolve_stop") == False: fixpri = True - # preguntar + # ask if default_action == 0: - # "Elige una opción" + # "Choose an option" seleccion = dialog_select(config.get_localized_string(30163), opciones) - # Ver en calidad baja + # View in low quality elif default_action == 1: resolutions = [] for url in video_urls: @@ -967,7 +918,7 @@ def get_seleccion(default_action, opciones, seleccion, video_urls): seleccion = resolutions.index(min(resolutions)) else: seleccion = 0 - # Ver en alta calidad + # See in high quality elif default_action == 2: resolutions = [] for url in video_urls: @@ -1018,11 +969,10 @@ def calcResolution(option): def show_channel_settings(**kwargs): """ - Muestra un cuadro de configuracion personalizado para cada canal y guarda los datos al cerrarlo. + It shows a customized configuration box for each channel and saves the data when closing it. + The parameters passed to it can be seen in the method that is called - Los parámetros que se le pasan se puede ver en la el método al que se llama - - @return: devuelve la ventana con los elementos + @return: returns the window with the elements @rtype: SettingsWindow """ from platformcode.xbmc_config_menu import SettingsWindow @@ -1031,11 +981,10 @@ def show_channel_settings(**kwargs): def show_video_info(*args, **kwargs): """ - Muestra una ventana con la info del vídeo. + It shows a window with the info of the video. +    The parameters passed to it can be seen in the method that is called - Los parámetros que se le pasan se puede ver en la el método al que se llama - - @return: devuelve la ventana con los elementos +    @return: returns the window with the elements @rtype: InfoWindow """ @@ -1049,13 +998,12 @@ def show_recaptcha(key, referer): def alert_no_disponible_server(server): - # 'El vídeo ya no está en %s' , 'Prueba en otro servidor o en otro canal' - dialog_ok(config.get_localized_string(30055), (config.get_localized_string(30057) % server), - config.get_localized_string(30058)) + # 'The video is no longer in %s', 'Try another server or another channel' + dialog_ok(config.get_localized_string(30055), (config.get_localized_string(30057) % server), config.get_localized_string(30058)) def alert_unsopported_server(): - # 'Servidor no soportado o desconocido' , 'Prueba en otro servidor o en otro canal' + # 'Unsupported or unknown server ',' Test on another server or on another channel' dialog_ok(config.get_localized_string(30065), config.get_localized_string(30058)) @@ -1079,10 +1027,10 @@ def handle_wait(time_to_wait, title, text): break if cancelled: - logger.info('Espera cancelada') + logger.info('Wait canceled') return False else: - logger.info('Espera finalizada') + logger.info('Wait finished') return True @@ -1102,11 +1050,11 @@ def get_dialogo_opciones(item, default_action, strm, autoplay): if item.server == "": item.server = "directo" - # Si no es el modo normal, no muestra el diálogo porque cuelga XBMC + # If it is not the normal mode, it does not show the dialog because XBMC hangs muestra_dialogo = (config.get_setting("player_mode") == 0 and not strm) - # Extrae las URL de los vídeos, y si no puedes verlo te dice el motivo - # Permitir varias calidades para server "directo" + # Extract the URLs of the videos, and if you can't see it, it tells you the reason + # Allow multiple qualities for "direct" server if item.video_urls: video_urls, puedes, motivo = item.video_urls, True, "" @@ -1115,7 +1063,7 @@ def get_dialogo_opciones(item, default_action, strm, autoplay): item.server, item.url, item.password, muestra_dialogo) seleccion = 0 - # Si puedes ver el vídeo, presenta las opciones + # If you can see the video, present the options if puedes: for video_url in video_urls: opciones.append(config.get_localized_string(60221) + " " + video_url[0]) @@ -1123,48 +1071,45 @@ def get_dialogo_opciones(item, default_action, strm, autoplay): if item.server == "local": opciones.append(config.get_localized_string(30164)) else: - # "Descargar" + # "Download" downloadenabled = config.get_setting('downloadenabled') if downloadenabled != False and item.channel != 'videolibrary': opcion = config.get_localized_string(30153) opciones.append(opcion) if item.isFavourite: - # "Quitar de favoritos" + # "Remove from favorites" opciones.append(config.get_localized_string(30154)) else: - # "Añadir a favoritos" + # "Add to Favorites" opciones.append(config.get_localized_string(30155)) if not strm and item.contentType == 'movie': - # "Añadir a videoteca" + # "Add to video library" opciones.append(config.get_localized_string(30161)) if default_action == 3: seleccion = len(opciones) - 1 - # Busqueda de trailers en youtube + # Search for trailers on youtube if item.channel not in ["Trailer", "ecarteleratrailers"]: - # "Buscar Trailer" + # "Search Trailer" opciones.append(config.get_localized_string(30162)) - # Si no puedes ver el vídeo te informa + # If you can't see the video it informs you else: if not autoplay: if item.server != "": if "
" in motivo: - ret = dialog_yesno(config.get_localized_string(60362), motivo.split("
")[0], motivo.split("
")[1], - item.url, nolabel='ok', yeslabel=config.get_localized_string(70739)) + ret = dialog_yesno(config.get_localized_string(60362), motivo.split("
")[0], motivo.split("
")[1], item.url, nolabel='ok', yeslabel=config.get_localized_string(70739)) else: ret = dialog_yesno(config.get_localized_string(60362), motivo, item.url, nolabel='ok', yeslabel=config.get_localized_string(70739)) else: - ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363), - config.get_localized_string(60364), item.url, nolabel='ok', yeslabel=config.get_localized_string(70739)) + ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363), config.get_localized_string(60364), item.url, nolabel='ok', yeslabel=config.get_localized_string(70739)) if ret: - xbmc.executebuiltin("XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", - url=item.url).tourl())) + xbmc.executebuiltin("XBMC.Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())) if item.channel == "favorites": - # "Quitar de favoritos" + # "Remove from favorites" opciones.append(config.get_localized_string(30154)) if len(opciones) == 0: @@ -1177,10 +1122,10 @@ def set_opcion(item, seleccion, opciones, video_urls): logger.info() # logger.debug(item.tostring('\n')) salir = False - # No ha elegido nada, lo más probable porque haya dado al ESC + # You have not chosen anything, most likely because you have given the ESC if seleccion == -1: - # Para evitar el error "Uno o más elementos fallaron" al cancelar la selección desde fichero strm + # To avoid the error "One or more elements failed" when deselecting from strm file listitem = xbmcgui.ListItem(item.title) if config.get_platform(True)['num_version'] >= 16.0: @@ -1191,7 +1136,7 @@ def set_opcion(item, seleccion, opciones, video_urls): xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem) - # "Descargar" + # "Download" elif opciones[seleccion] == config.get_localized_string(30153): from specials import downloads @@ -1201,25 +1146,23 @@ def set_opcion(item, seleccion, opciones, video_urls): downloads.save_download(item) salir = True - # "Quitar de favoritos" + # "Remove from favorites" elif opciones[seleccion] == config.get_localized_string(30154): from specials import favorites favorites.delFavourite(item) salir = True - # "Añadir a favoritos": + # "Add to Favorites": elif opciones[seleccion] == config.get_localized_string(30155): from specials import favorites item.from_channel = "favorites" favorites.addFavourite(item) salir = True - # "Buscar Trailer": + # "Search Trailer": elif opciones[seleccion] == config.get_localized_string(30162): config.set_setting("subtitulo", False) - xbmc.executebuiltin("XBMC.RunPlugin(%s?%s)" % - (sys.argv[0], item.clone(channel="trailertools", action="buscartrailer", - contextual=True).tourl())) + xbmc.executebuiltin("XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(channel="trailertools", action="buscartrailer", contextual=True).tourl())) salir = True return salir @@ -1232,7 +1175,7 @@ def get_video_seleccionado(item, seleccion, video_urls): wait_time = 0 mpd = False - # Ha elegido uno de los vídeos + # You have chosen one of the videos if seleccion < len(video_urls): mediaurl = video_urls[seleccion][1] if len(video_urls[seleccion]) > 4: @@ -1248,7 +1191,7 @@ def get_video_seleccionado(item, seleccion, video_urls): wait_time = video_urls[seleccion][2] view = True - # Si no hay mediaurl es porque el vídeo no está :) + # If there is no mediaurl it is because the video is not there :) logger.info("mediaurl=" + mediaurl) if mediaurl == "": if item.server == "unknown": @@ -1256,7 +1199,7 @@ def get_video_seleccionado(item, seleccion, video_urls): else: alert_no_disponible_server(item.server) - # Si hay un tiempo de espera (como en megaupload), lo impone ahora + # If there is a timeout (like in megaupload), impose it now if wait_time > 0: continuar = handle_wait(wait_time, item.server, config.get_localized_string(60365)) if not continuar: @@ -1268,12 +1211,12 @@ def get_video_seleccionado(item, seleccion, video_urls): def set_player(item, xlistitem, mediaurl, view, strm): logger.info() logger.debug("item:\n" + item.tostring('\n')) - # Movido del conector "torrent" aqui + # Moved del conector "torrent" here if item.server == "torrent": play_torrent(item, xlistitem, mediaurl) return - # Si es un fichero strm no hace falta el play + # If it is a strm file, play is not necessary elif strm: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem) if item.subtitle != "": @@ -1290,7 +1233,7 @@ def set_player(item, xlistitem, mediaurl, view, strm): elif config.get_setting("player_mode") == 0 or item.play_from == 'window' or \ (config.get_setting("player_mode") == 3 and mediaurl.startswith("rtmp")): - # Añadimos el listitem a una lista de reproducción (playlist) + # We add the listitem to a playlist playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(mediaurl, xlistitem) @@ -1304,7 +1247,7 @@ def set_player(item, xlistitem, mediaurl, view, strm): # elif config.get_setting("player_mode") == 1 or item.isPlayable: elif config.get_setting("player_mode") == 1: logger.info("Tras setResolvedUrl") - # si es un archivo de la videoteca enviar a marcar como visto + # if it is a video library file send to mark as seen if strm or item.strm_path: from platformcode import xbmc_videolibrary @@ -1317,23 +1260,23 @@ def set_player(item, xlistitem, mediaurl, view, strm): elif config.get_setting("player_mode") == 2: xbmc.executebuiltin("PlayMedia(" + mediaurl + ")") - # TODO MIRAR DE QUITAR VIEW + # ALL LOOKING TO REMOVE VIEW if item.subtitle != "" and view: logger.info("Subtítulos externos: " + item.subtitle) xbmc.sleep(2000) xbmc_player.setSubtitles(item.subtitle) - # si es un archivo de la videoteca enviar a marcar como visto + # if it is a video library file send to mark as seen if strm or item.strm_path: from platformcode import xbmc_videolibrary xbmc_videolibrary.mark_auto_as_watched(item) def torrent_client_installed(show_tuple=False): - # Plugins externos se encuentra en servers/torrent.json nodo clients + # External plugins found in servers / torrent.json node clients from core import filetools from core import jsontools - torrent_clients = jsontools.get_node_from_file("torrent.json", "clients", filetools.join(config.get_runtime_path(),"servers")) + torrent_clients = jsontools.get_node_from_file("torrent.json", "clients", filetools.join(config.get_runtime_path(), "servers")) torrent_options = [] for client in torrent_clients: if xbmc.getCondVisibility('System.HasAddon("%s")' % client["id"]): @@ -1346,7 +1289,6 @@ def torrent_client_installed(show_tuple=False): def play_torrent(item, xlistitem, mediaurl): logger.info() - # from core.support import dbg;dbg() import time from servers import torrent diff --git a/servers/torrent.py b/servers/torrent.py index c0b9ba84..7c288695 100755 --- a/servers/torrent.py +++ b/servers/torrent.py @@ -1,41 +1,25 @@ # -*- coding: utf-8 -*- -import re, os, sys +import re, os, sys, time, requests, xbmc, xbmcaddon -# from builtins import str -from builtins import range +from core import filetools, jsontools +from core.support import dbg, log, match +from platformcode import config, platformtools +from torrentool.api import Torrent +from lib.guessit import guessit -PY3 = False -VFS = True -if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int; VFS = False - -if PY3: +if sys.version_info[0] >= 3: import urllib.parse as urllib else: import urllib -import time, requests, xbmc, xbmcgui, xbmcaddon, shutil -from core import filetools, jsontools -from core.support import dbg, log, match -# from core import httptools -# from core import scrapertools -from platformcode import config, platformtools -from threading import Thread, currentThread -from torrentool.api import Torrent -from lib.guessit import guessit -try: - elementum_setting = xbmcaddon.Addon(id='plugin.video.elementum') - elementum_host = 'http://127.0.0.1:' + elementum_setting.getSetting('remote_port') + '/torrents/' - TorrentPath = xbmc.translatePath(elementum_setting.getSetting('torrents_path')) -except: - pass +monitor = filetools.join(config.get_data_path(), 'elementum_monitor.json') extensions_list = ['.aaf', '.3gp', '.asf', '.avi', '.flv', '.mpeg', '.m1v', '.m2v', '.m4v', '.mkv', '.mov', '.mpg', '.mpe', '.mp4', '.ogg', '.wmv'] -monitorPath = filetools.join(config.get_data_path(), 'elementum_torrent.txt') + # Returns an array of possible video url's from the page_url def get_video_url(page_url, premium=False, user='', password='', video_password=''): - torrent_options = platformtools.torrent_client_installed(show_tuple=True) if len(torrent_options) == 0: from specials import elementum_download @@ -71,184 +55,154 @@ def mark_auto_as_watched(item): xbmc_videolibrary.mark_auto_as_watched(item) -########################## ELEMENTUM MONITOR TEST ########################## +def setting(): + try: + elementum_setting = xbmcaddon.Addon(id='plugin.video.elementum') + elementum_host = 'http://127.0.0.1:' + elementum_setting.getSetting('remote_port') + '/torrents/' + TorrentPath = xbmc.translatePath(elementum_setting.getSetting('torrents_path')) + except: + elementum_setting = '' + elementum_host = '' + TorrentPath = '' + return elementum_setting, elementum_host, TorrentPath -elementumHost = 'http://127.0.0.1:65220/torrents/' def elementum_download(item): - elementum = False - while not elementum: - try: - sleep = False - if elementum_setting.getSetting('logger_silent') == False: - elementum_setting.setSetting('logger_silent', 'true') - sleep = True - if elementum_setting.getSetting('download_storage') != 0: - config.set_setting('elementumtype', elementum_setting.getSetting('download_storage')) # Backup Setting - elementum_setting.setSetting('download_storage', '0') # Set Setting - sleep = True - if elementum_setting.getSetting('download_path') != config.get_setting('downloadpath'): - elementum_setting.setSetting('download_path', config.get_setting('downloadpath')) # Backup Setting - config.set_setting('elementumdl', elementum_setting.getSetting('download_path')) # Set Setting - sleep = True - if sleep: time.sleep(3) - elementum = True - path = filetools.join(config.get_data_path(),'elementum_torrent.txt') - url = urllib.quote_plus(item.url) - filetools.write(path, url) - except: - pass + elementum_setting, elementum_host, TorrentPath = setting() + if elementum_setting: + set_elementum(True) + time.sleep(3) + TorrentName = match(item.url, patron=r'btih(?::|%3A)([^&%]+)', string=True).match + post = 'uri=%s&file=null&all=1' % urllib.quote_plus(item.url) + match(elementum_host + 'add', post=post, timeout=5, alfa_s=True, ignore_response_code=True) + while not filetools.isfile(filetools.join(elementum_setting.getSetting('torrents_path'), TorrentName + '.torrent')): + time.sleep(1) -# def stop_elementum_monitor(): -# config.set_setting('stop_elementum_monitor', True) -# time.sleep(2) - -# def start_elementum_monitor(): -# config.set_setting('stop_elementum_monitor', False) -# time.sleep(3) -# Thread(target=elementum_monitor).start() - + monitor_update(TorrentPath, TorrentName) def elementum_monitor(): - partials = [] - try: - if filetools.isfile(monitorPath): - log('Add Torrent') - url = filetools.read(monitorPath) - if url.startswith('/'): - requests.get(elementum_host + url) - wait = False - else: - TorrentName = match(url, patron=r'btih(?::|%3A)([^&%]+)', string=True).match - uri = elementum_host + 'add' - post = 'uri=%s&file=null&all=1' % url - match(uri, post=post, timeout=5, alfa_s=True, ignore_response_code=True) - wait = True - filetools.remove(monitorPath) - if wait: - while not filetools.isfile(filetools.join(elementum_setting.getSetting('torrents_path'), TorrentName + '.torrent')): - time.sleep(1) + path = xbmc.translatePath(config.get_setting('downloadlistpath')) + elementum_setting, elementum_host, TorrentPath = setting() + active_torrent = filetools.listdir(TorrentPath) + + if elementum_setting: + # check if command file exist + if filetools.isfile(monitor): + json = jsontools.load(open(monitor, "r").read()) + Monitor = json['monitor'] + # else create it else: - log('Watch') + json = jsontools.load('{"monitor":{},"settings":{}}') + json = jsontools.dump(json) + filetools.write(monitor, json, silent=True) + + if len(Monitor) > 0: try: - data = requests.get(elementum_host).json() + data = requests.get(elementum_host + '/list').json() except: data = '' if data: - json = data['items'] - - for it in json: - Partial = float(match(it['label'], patron=r'(\d+\.\d+)%').match) - Title = it['info']['title'] - TorrentName = match(it['path'], patron=r'resume=([^&]+)').match - File, Json = find_file(TorrentName) - update_download_info(Partial, Title, TorrentName, File, Json) - partials.append(Partial) - - partials.sort() - if len(partials) > 0 and partials[0] == 100: - unset_elementum() - except: - pass + for it in data: + progress = round(it['progress'], 2) + status = it['status'] + name = it['id'] + if name in Monitor: + jsontools.update_node(progress, Monitor[name]['file'], 'downloadProgress', path, silent=True) + jsontools.update_node(4, Monitor[name]['file'], 'downloadStatus', path, silent=True) + if status in ['Paused']: + jsontools.update_node(0, Monitor[name]['file'], 'downloadStatus', path, silent=True) + if status in ['Seeding', 'Finished']: + monitor_update(TorrentPath, name, remove=True) + dlJson = jsontools.load(open(filetools.join(path, Monitor[name]['file']), "r").read()) + jsontools.update_node(dlJson['downloadSize'], Monitor[name]['file'], 'downloadCompleted', path, silent=True) + jsontools.update_node(2, Monitor[name]['file'], 'downloadStatus', path, silent=True) + requests.get(elementum_host + 'pause/' + name) + filetools.remove(filetools.join(TorrentPath, name + '.torrent')) + filetools.remove(filetools.join(TorrentPath, name + '.fastresume')) + time.sleep(1) + rename(Monitor[name]['file']) -def find_file(File): +def monitor_update(TorrentPath, value, remove=False): + elementum_setting, elementum_host, TorrentPath = setting() + json = jsontools.load(open(monitor, "r").read()) + Monitor = json['monitor'] + info = Torrent.from_file(filetools.join(TorrentPath, value + '.torrent')) + path = xbmc.translatePath(config.get_setting('downloadlistpath')) + + if not value in Monitor: + Monitor[value]={} + Monitor[value]['name'] = info.name + Monitor[value]['size'] = info.total_size + File = find_file(value) + Monitor[value]['file'] = File + json = jsontools.dump(json) + filetools.write(monitor, json, silent=True) + + backupFilename = jsontools.load(open(filetools.join(path, File), "r").read())['downloadFilename'] + jsontools.update_node(value, File, 'TorrentName', path, silent=True) + jsontools.update_node(info.total_size, File, 'downloadSize', path, silent=True) + jsontools.update_node(backupFilename, File, 'backupFilename', path, silent=True) + jsontools.update_node(info.name, File, 'downloadFilename', path, silent=True) + + elif remove: + Monitor.pop(value) + jsontools.dump(json) + filetools.write(monitor, jsontools.dump(json), silent=True) + + if len(Monitor) == 0: set_elementum() + + +def set_elementum(SET=False): + elementum_setting, elementum_host, TorrentPath = setting() + json = jsontools.load(open(monitor, "r").read()) + backup_setting = json['settings'] + write = False + if SET: + if elementum_setting.getSetting('logger_silent') == False or not 'logger_silent' in backup_setting: + elementum_setting.setSetting('logger_silent', 'true') + backup_setting['logger_silent'] = 'false' + + if elementum_setting.getSetting('download_storage') != 0 or not 'download_storage' in backup_setting: + backup_setting['download_storage'] = elementum_setting.getSetting('download_storage') # Backup Setting + elementum_setting.setSetting('download_storage', '0') # Set Setting + + if elementum_setting.getSetting('download_path') != config.get_setting('downloadpath') or not 'download_path' in backup_setting: + backup_setting['download_path'] = elementum_setting.getSetting('download_path') # Backup Setting + elementum_setting.setSetting('download_path', config.get_setting('downloadpath')) # Set Setting + write = True + + elif backup_setting: + elementum_setting.setSetting('logger_silent', backup_setting['logger_silent']) + elementum_setting.setSetting('download_storage', backup_setting['download_storage']) + elementum_setting.setSetting('download_path', backup_setting['download_path']) + json['settings'] = {} + write = True + if write: + json = jsontools.dump(json) + filetools.write(monitor, json, silent=True) + time.sleep(1) + + +def find_file(hash): path = xbmc.translatePath(config.get_setting('downloadlistpath')) files = filetools.listdir(path) - # dbg() for f in files: filepath = filetools.join(path, f) json = jsontools.load(filetools.read(filepath)) - if ('downloadServer' in json and 'url' in json['downloadServer'] and File in json['downloadServer']['url']) or ('url' in json and File in json['url']): + if ('downloadServer' in json and 'url' in json['downloadServer'] and hash in json['downloadServer']['url']) or ('url' in json and hash in json['url']): break - return filetools.split(filepath)[-1], json + return filetools.split(filepath)[-1] -def update_download_info(Partial, Title, TorrentName, File, Json): - path = xbmc.translatePath(config.get_setting('downloadlistpath')) - dlpath = filetools.join(config.get_setting('downloadpath'), Title) +def elementum_actions(parameter, TorrentHash): + elementum_setting, elementum_host, TorrentPath = setting() + if elementum_setting: + if parameter == 'delete' : monitor_update(TorrentPath, TorrentHash, remove=True) + requests.get('%s/%s/%s' %(elementum_host, parameter, TorrentHash)) - if 'TorrentName' not in Json: - jsontools.update_node(TorrentName, File, 'TorrentName', path, silent=True) - if Json['downloadSize'] == 0: - size = Torrent.from_file(filetools.join(TorrentPath, TorrentName + '.torrent')).total_size - jsontools.update_node(size, File, 'downloadSize', path, silent=True) - if Json['downloadFilename'] != dlpath and 'backupFilename' not in Json: - jsontools.update_node(Json['downloadFilename'], File, 'backupFilename', path, silent=True) - jsontools.update_node(dlpath, File, 'downloadFilename', path, silent=True) - if Json['downloadProgress'] != Partial and Partial != 0: - jsontools.update_node(Partial, File, 'downloadProgress', path, silent=True) - jsontools.update_node(4, File, 'downloadStatus', path, silent=True) - if Partial == 100: - jsontools.update_node(Json['downloadSize'], File, 'downloadCompleted', path, silent=True) - jsontools.update_node(2, File, 'downloadStatus', path, silent=True) - requests.get(elementum_host + 'pause/' + TorrentName) - del_torrent(TorrentName) - time.sleep(1) - rename(TorrentName, path) - # requests.get(elementum_host + 'delete/' + TorrentName + '?files=false') - -def del_torrent(TorrentName): - filetools.remove(filetools.join(TorrentPath, TorrentName + '.torrent')) - - -def rename(TorrentName, Path): - # dbg() - File, Json = find_file(TorrentName) - path = Json['downloadFilename'] - if Json['infoLabels']['mediatype'] == 'movie': - if filetools.isdir(path): - extension = '' - files = filetools.listdir(path) - sep = '/' if path.lower().startswith("smb://") else os.sep - oldName = path.split(sep)[-1] - newName = Json['backupFilename'] - for f in files: - ext = os.path.splitext(f)[-1] - if ext in extensions_list: extension = ext - filetools.rename(filetools.join(path, f), f.replace(oldName, newName)) - filetools.rename(path, newName) - jsontools.update_node(filetools.join(newName, newName + extension), File, 'downloadFilename', Path) - - else: - oldName = filetools.split(path)[-1] - newName = Json['backupFilename'] + os.path.splitext(oldName)[-1] - filetools.rename(path, newName) - jsontools.update_node(newName, File, 'downloadFilename', Path) - else: - sep = '/' if path.lower().startswith("smb://") else os.sep - FolderName = Json['backupFilename'].split(sep)[0] - Title = re.sub(r'(\s*\[[^\]]+\])', '', FolderName) - if filetools.isdir(path): - files = filetools.listdir(path) - file_dict = {} - for f in files: - title = process_filename(f, Title, ext=False) - ext = os.path.splitext(f)[-1] - name = os.path.splitext(f)[0] - if title not in file_dict and ext in extensions_list: - file_dict[title] = name - - for title, name in file_dict.items(): - for f in files: - if name in f: - # log('Name:',name,'Title:',title) - filetools.rename(filetools.join(path, f), f.replace(name, title)) - - filetools.rename(path, FolderName) - jsontools.update_node(FolderName, File, 'downloadFilename', Path) - else: - filename = filetools.split(path)[-1] - title = process_filename(filename, Title) - NewFolder = filetools.join(config.get_setting('downloadpath'), FolderName) - if not filetools.isdir(NewFolder): - filetools.mkdir(NewFolder) - from_folder = filetools.join(config.get_setting('downloadpath'), filename) - to_folder = filetools.join(config.get_setting('downloadpath'), FolderName, title) - filetools.move(from_folder, to_folder) - jsontools.update_node(filetools.join(FolderName, title), File, 'downloadFilename', Path) def process_filename(filename, Title, ext=True): extension = os.path.splitext(filename)[-1] @@ -275,16 +229,58 @@ def process_filename(filename, Title, ext=True): title = (t if t else Title) + s + episode + (extension if ext else '') return title -def unset_elementum(): - log('UNSET Elementum') - Sleep = False - if config.get_setting('elementumtype') and config.get_setting('elementumtype') != elementum_setting.gerSetting('download_storage'): - elementum_setting.setSetting('download_storage', str(config.get_setting('elementumtype'))) - Sleep = True - if config.get_setting('elementumdl') and config.get_setting('elementumdl') != elementum_setting.gerSetting('download_path'): - elementum_setting.setSetting('download_path', config.get_setting('elementumdl')) - Sleep = True - if Sleep: - time.sleep(1) -########################## ELEMENTUM MONITOR TEST ########################## +def rename(File): + jsonPath = xbmc.translatePath(config.get_setting('downloadlistpath')) + json = jsontools.load(open(filetools.join(jsonPath, File), "r").read()) + filePath = filetools.join(xbmc.translatePath(config.get_setting('downloadpath')), json['downloadFilename']) + + if json['infoLabels']['mediatype'] == 'movie': + if filetools.isdir(filePath): + extension = '' + files = filetools.listdir(filePath) + oldName = json['downloadFilename'] + newName = json['backupFilename'] + for f in files: + ext = os.path.splitext(f)[-1] + if ext in extensions_list: extension = ext + filetools.rename(filetools.join(filePath, f), f.replace(oldName, newName)) + filetools.rename(filePath, newName) + jsontools.update_node(filetools.join(newName, newName + extension), File, 'downloadFilename', jsonPath) + + else: + oldName = json['downloadFilename'] + newName = json['backupFilename'] + os.path.splitext(oldName)[-1] + filetools.rename(filePath, newName) + jsontools.update_node(newName, File, 'downloadFilename', jsonPath) + else: + sep = '/' if filePath.lower().startswith("smb://") else os.sep + FolderName = json['backupFilename'].split(sep)[0] + Title = re.sub(r'(\s*\[[^\]]+\])', '', FolderName) + if filetools.isdir(filePath): + files = filetools.listdir(filePath) + file_dict = {} + for f in files: + title = process_filename(f, Title, ext=False) + ext = os.path.splitext(f)[-1] + name = os.path.splitext(f)[0] + if title not in file_dict and ext in extensions_list: + file_dict[title] = name + + for title, name in file_dict.items(): + for f in files: + if name in f: + filetools.rename(filetools.join(filePath, f), f.replace(name, title)) + + filetools.rename(filePath, FolderName) + jsontools.update_node(FolderName, File, 'downloadFilename', jsonPath) + else: + filename = filetools.split(filePath)[-1] + title = process_filename(filename, Title) + NewFolder = filetools.join(config.get_setting('downloadpath'), FolderName) + if not filetools.isdir(NewFolder): + filetools.mkdir(NewFolder) + from_folder = filetools.join(config.get_setting('downloadpath'), filename) + to_folder = filetools.join(config.get_setting('downloadpath'), FolderName, title) + filetools.move(from_folder, to_folder) + jsontools.update_node(filetools.join(FolderName, title), File, 'downloadFilename', jsonPath) \ No newline at end of file diff --git a/specials/downloads.py b/specials/downloads.py index 8d0eb478..077ede0a 100644 --- a/specials/downloads.py +++ b/specials/downloads.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ------------------------------------------------------------ -# Gestor de descargas +# Download manager # ------------------------------------------------------------ from __future__ import division @@ -23,6 +23,7 @@ from core.item import Item from platformcode import config, logger from platformcode import platformtools from core.support import log, dbg, typo +from servers import torrent kb = '0xFF65B3DA' kg = '0xFF65DAA8' @@ -46,21 +47,21 @@ def mainlist(item): log() itemlist = [] - # Lista de archivos + # File list for file in sorted(filetools.listdir(DOWNLOAD_LIST_PATH)): - # Saltamos todos los que no sean JSON + # We skip all the non JSON if not file.endswith(".json"): continue - # cargamos el item + # we load the item file = filetools.join(DOWNLOAD_LIST_PATH, file) i = Item(path=file).fromjson(filetools.read(file)) i.thumbnail = i.contentThumbnail - # Listado principal + # Main listing if not item.contentType == "tvshow": # Series if i.contentType == "episode": - # Comprobamos que la serie no este ya en el itemlist + # We check that the series is not already in the itemlist if not [x for x in itemlist if x.contentSerieName == i.contentSerieName and x.contentChannel == i.contentChannel]: title = TITLE_TVSHOW % (STATUS_COLORS[i.downloadStatus], i.downloadProgress, i.contentSerieName, i.contentChannel) @@ -81,12 +82,12 @@ def mainlist(item): s.title = TITLE_TVSHOW % (STATUS_COLORS[s.downloadStatus], downloadProgress, i.contentSerieName, i.contentChannel) - # Peliculas + # Movies elif i.contentType == "movie" or i.contentType == "video": i.title = TITLE_FILE % (STATUS_COLORS[i.downloadStatus], i.downloadProgress, i.contentTitle) itemlist.append(i) - # Listado dentro de una serie + # Listed within a series else: if i.contentType == "episode" and i.contentSerieName == item.contentSerieName and i.contentChannel == item.contentChannel: i.title = TITLE_FILE % (STATUS_COLORS[i.downloadStatus], i.downloadProgress, "%dx%0.2d: %s" % (i.contentSeason, i.contentEpisodeNumber, i.contentTitle)) @@ -94,19 +95,19 @@ def mainlist(item): estados = [i.downloadStatus for i in itemlist] - # Si hay alguno completado + # If there is any completed if 2 in estados: itemlist.insert(0, Item(channel=item.channel, action="clean_ready", title=config.get_localized_string(70218), contentType=item.contentType, contentChannel=item.contentChannel, thumbnail=get_thumb('delete.png'), contentSerieName=item.contentSerieName, text_color=STATUS_COLORS[STATUS_CODES.completed])) - # Si hay alguno con error + # If there is any error if 3 in estados: itemlist.insert(0, Item(channel=item.channel, action="restart_error", title=config.get_localized_string(70219), contentType=item.contentType, contentChannel=item.contentChannel, thumbnail=get_thumb('update.png'), contentSerieName=item.contentSerieName, text_color=STATUS_COLORS[STATUS_CODES.error])) - # Si hay alguno pendiente + # If there is any pending if 1 in estados or 0 in estados: itemlist.insert(0, Item(channel=item.channel, action="download_all", title=support.typo(config.get_localized_string(70220),'bold'), contentType=item.contentType, contentChannel=item.contentChannel, thumbnail=get_thumb('downloads.png'), @@ -190,11 +191,7 @@ def clean_all(item): if File.endswith(".json"): download_item = Item().fromjson(filetools.read(filetools.join(DOWNLOAD_LIST_PATH, File))) if download_item.TorrentName: - path = filetools.join(config.get_data_path(),'elementum_torrent.txt') - url = '/pause/' + download_item.TorrentName - filetools.write(path, url) - from servers.torrent import del_torrent - del_torrent(download_item.TorrentName) + torrent.elementum_actions('delete', item.TorrentName) if not item.contentType == "tvshow" or ( item.contentSerieName == download_item.contentSerieName and item.contentChannel == download_item.contentChannel): filetools.remove(filetools.join(DOWNLOAD_LIST_PATH, File)) if removeFiles: @@ -218,9 +215,7 @@ def stop_all(item=None): if fichero.endswith(".json"): download_item = Item().fromjson(filetools.read(filetools.join(DOWNLOAD_LIST_PATH, fichero))) if download_item.TorrentName: - path = filetools.join(config.get_data_path(),'elementum_torrent.txt') - url = '/pause/' + download_item.TorrentName - filetools.write(path, url) + torrent.elementum_actions('pause', download_item.TorrentName) if download_item.downloadStatus == 4: update_json(filetools.join(DOWNLOAD_LIST_PATH, fichero), {"downloadStatus": STATUS_CODES.stoped}) xbmc.sleep(300) @@ -275,72 +270,75 @@ def download_all_background(item): if download_item.downloadStatus in [STATUS_CODES.stoped, STATUS_CODES.canceled]: res = start_download(download_item) # platformtools.itemlist_refresh() - # Si se ha cancelado paramos + # If canceled, we stop if res == STATUS_CODES.canceled: break def menu(item): - log() + log(item) if item.downloadServer: servidor = item.downloadServer.get("server", "Auto") else: servidor = "Auto" - # Opciones disponibles para el menu + # Options available for the menu op = [config.get_localized_string(70225), config.get_localized_string(70226), config.get_localized_string(70227), config.get_localized_string(30165) % (servidor.capitalize()), config.get_localized_string(60220), config.get_localized_string(60221)] opciones = [] - # Opciones para el menu + # Options for the menu if item.downloadStatus == STATUS_CODES.stoped: - opciones.append(op[0]) # Descargar - if not item.server: opciones.append(op[3]) # Elegir Servidor - opciones.append(op[1]) # Eliminar de la lista + opciones.append(op[0]) # Download + if not item.server: opciones.append(op[3]) # Choose Server + opciones.append(op[1]) # Remove from the list if item.downloadStatus == STATUS_CODES.canceled: - 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 + opciones.append(op[0]) # Download + if not item.server: opciones.append(op[3]) # Choose Server + opciones.append(op[2]) # Restart download + opciones.append(op[1]) # Remove from the list if item.downloadStatus == STATUS_CODES.completed: - opciones.append(op[5]) # Play - opciones.append(op[1]) # Eliminar de la lista - opciones.append(op[2]) # Reiniciar descarga + opciones.append(op[5]) # Play + opciones.append(op[1]) # Remove from the list + opciones.append(op[2]) # Restart download - if item.downloadStatus == STATUS_CODES.error: # descarga con error - opciones.append(op[2]) # Reiniciar descarga - opciones.append(op[1]) # Eliminar de la lista + if item.downloadStatus == STATUS_CODES.error: # Download with error + opciones.append(op[2]) # Restart download + opciones.append(op[1]) # Remove from the list if item.downloadStatus == STATUS_CODES.downloading: - opciones.append(op[5]) # Play - opciones.append(op[4]) # pause download - opciones.append(op[1]) # Eliminar de la lista + opciones.append(op[5]) # Play + opciones.append(op[4]) # Pause Download + opciones.append(op[1]) # Remove from the list - # Mostramos el dialogo + # Show Dialog seleccion = platformtools.dialog_select(config.get_localized_string(30163), opciones) + logger.info('SELECTION: '+ op[seleccion]) - # -1 es cancelar + # -1 is cancel if seleccion == -1: return - log("option=", opciones[seleccion]) - # Opcion Eliminar + # Delete if opciones[seleccion] == op[1]: filetools.remove(item.path) - if platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(30300)): - filetools.remove(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) + if item.TorrentName: + torrent.elementum_actions('delete', item.TorrentName) + else: + if platformtools.dialog_yesno(config.get_localized_string(20000), config.get_localized_string(30300)): + filetools.remove(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) - # Opcion inicaiar descarga + # Start Download if opciones[seleccion] == op[0]: item.action = "start_download" xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")") - # Elegir Servidor + # Select Server if opciones[seleccion] == op[3]: select_server(item) - # Reiniciar descarga + # Restart Download if opciones[seleccion] == op[2]: if filetools.isfile(filetools.join(DOWNLOAD_PATH, item.downloadFilename)): filetools.remove(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) @@ -348,6 +346,8 @@ def menu(item): update_json(item.path, {"downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0, "downloadServer": {}}) if opciones[seleccion] == op[4]: + if item.TorrentName: + torrent.elementum_actions('pause', item.TorrentName) update_json(item.path, {"downloadStatus": STATUS_CODES.stoped}) if opciones[seleccion] == op[5]: @@ -472,9 +472,7 @@ def get_server_position(server): servers = {} if server in servers: - pos = [s for s in sorted(servers, key=lambda x: (old_div(sum(servers[x]["speeds"]), (len(servers[x]["speeds"]) or 1)), - float(sum(servers[x]["success"])) / ( - len(servers[x]["success"]) or 1)), reverse=True)] + pos = [s for s in sorted(servers, key=lambda x: (old_div(sum(servers[x]["speeds"]), (len(servers[x]["speeds"]) or 1)), float(sum(servers[x]["success"])) / ( len(servers[x]["success"]) or 1)), reverse=True)] return pos.index(server) + 1 else: return 0 @@ -482,27 +480,26 @@ def get_server_position(server): def get_match_list(data, match_list, order_list=None, only_ascii=False, ignorecase=False): """ - Busca coincidencias en una cadena de texto, con un diccionario de "ID" / "Listado de cadenas de busqueda": - { "ID1" : ["Cadena 1", "Cadena 2", "Cadena 3"], - "ID2" : ["Cadena 4", "Cadena 5", "Cadena 6"] - } + Search for matches in a text string, with a dictionary of "ID" / "List of search strings": +    {"ID1": ["String 1", "String 2", "String 3"], +      "ID2": ["String 4", "String 5", "String 6"] +    } - El diccionario no pude contener una misma cadena de busqueda en varías IDs. - - La busqueda se realiza por orden de tamaño de cadena de busqueda (de mas larga a mas corta) si una cadena coincide, - se elimina de la cadena a buscar para las siguientes, para que no se detecten dos categorias si una cadena es parte de otra: - por ejemplo: "Idioma Español" y "Español" si la primera aparece en la cadena "Pablo sabe hablar el Idioma Español" - coincidira con "Idioma Español" pero no con "Español" ya que la coincidencia mas larga tiene prioridad. +    The dictionary could not contain the same search string in several IDs. +    The search is performed in order of search string size (from longest to shortest) if a string matches, +    it is removed from the search string for the following, so that two categories are not detected if one string is part of another: +    for example: "Spanish Language" and "Spanish" if the first appears in the string "Pablo knows how to speak the Spanish Language" +    It will match "Spanish Language" but not "Spanish" since the longest match has priority. """ match_dict = dict() matches = [] - # Pasamos la cadena a unicode + # We pass the string to unicode if not PY3: data = unicode(data, "utf8") - # Pasamos el diccionario a {"Cadena 1": "ID1", "Cadena 2", "ID1", "Cadena 4", "ID2"} y los pasamos a unicode + # We pass the dictionary to {"String 1": "ID1", "String 2", "ID1", "String 4", "ID2"} and we pass them to unicode for key in match_list: if order_list and not key in order_list: raise Exception("key '%s' not in match_list" % key) @@ -514,17 +511,17 @@ def get_match_list(data, match_list, order_list=None, only_ascii=False, ignoreca else: match_dict[value] = key - # Si ignorecase = True, lo pasamos todo a mayusculas + # If ignorecase = True, we pass everything to capital letters if ignorecase: data = data.upper() match_dict = dict((key.upper(), match_dict[key]) for key in match_dict) - # Si ascii = True, eliminamos todos los accentos y Ñ + # If ascii = True, we remove all accents and Ñ if only_ascii: data = ''.join((c for c in unicodedata.normalize('NFD', data) if unicodedata.category(c) != 'Mn')) match_dict = dict((''.join((c for c in unicodedata.normalize('NFD', key) if unicodedata.category(c) != 'Mn')), match_dict[key]) for key in match_dict) - # Ordenamos el listado de mayor tamaño a menor y buscamos. + # We sort the list from largest to smallest and search. for match in sorted(match_dict, key=lambda x: len(x), reverse=True): s = data for a in matches: @@ -533,8 +530,7 @@ def get_match_list(data, match_list, order_list=None, only_ascii=False, ignoreca matches.append(match) if matches: if order_list: - return type("Mtch_list", (), - {"key": match_dict[matches[-1]], "index": order_list.index(match_dict[matches[-1]])}) + return type("Mtch_list", (), {"key": match_dict[matches[-1]], "index": order_list.index(match_dict[matches[-1]])}) else: return type("Mtch_list", (), {"key": match_dict[matches[-1]], "index": None}) else: @@ -595,17 +591,17 @@ def download_from_url(url, item): platformtools.dialog_notification('m3u8 Download',config.get_localized_string(60364), sound=False) return {"downloadStatus": STATUS_CODES.error} - # Obtenemos la ruta de descarga y el nombre del archivo + # We get the download path and the file name item.downloadFilename = item.downloadFilename download_path = filetools.dirname(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) file_name = filetools.basename(filetools.join(DOWNLOAD_PATH, item.downloadFilename)) - # Creamos la carpeta si no existe + # We create the folder if it does not exist if not filetools.exists(download_path): filetools.mkdir(download_path) - # Lanzamos la descarga + # We launch the download d = Downloader(url, download_path, file_name, max_connections=1 + int(config.get_setting("max_connections", "downloads")), block_size=2 ** (17 + int(config.get_setting("block_size", "downloads"))), @@ -620,18 +616,18 @@ def download_from_url(url, item): d.start_dialog(config.get_localized_string(60332)) - # Descarga detenida. Obtenemos el estado: - # Se ha producido un error en la descarga + # Download stopped. We get the state: + # Download failed if d.state == d.states.error: log("Error trying to download", url) status = STATUS_CODES.error - # La descarga se ha detenifdo + # Download has stopped elif d.state == d.states.stopped: log("Stop download") status = STATUS_CODES.canceled - # La descarga ha finalizado + # Download is complete elif d.state == d.states.completed: log("Downloaded correctly") status = STATUS_CODES.completed @@ -701,7 +697,7 @@ def download_from_server(item): else: video_urls, puedes, motivo = item.video_urls, True, "" - # Si no esta disponible, salimos + # If it is not available, we go out if not puedes: log("The video is NOT available") return {"downloadStatus": STATUS_CODES.error} @@ -711,7 +707,7 @@ def download_from_server(item): result = {} - # Recorre todas las opciones hasta que consiga descargar una correctamente + # Go through all the options until I can download one correctly for video_url in reversed(video_urls): result = download_from_url(video_url[1], item) @@ -719,11 +715,11 @@ def download_from_server(item): if result["downloadStatus"] in [STATUS_CODES.canceled, STATUS_CODES.completed]: break - # Error en la descarga, continuamos con la siguiente opcion + # Download error, we continue with the next option if result["downloadStatus"] == STATUS_CODES.error: continue - # Devolvemos el estado + # We return the state return result @@ -737,10 +733,6 @@ def download_from_best_server(item): if item.downloadItemlist: log('using cached servers') play_items = [Item().fromurl(i) for i in item.downloadItemlist] - elif item.TorrentName: - path = filetools.join(config.get_data_path(),'elementum_torrent.txt') - url = '/resume/' + item.TorrentName - filetools.write(path, url) else: if item.contentChannel in ['community', 'videolibrary']: channel = __import__('specials.%s' % item.contentChannel, None, None, ['specials.%s' % item.contentChannel]) @@ -766,7 +758,7 @@ def download_from_best_server(item): finally: progreso.close() - # Recorremos el listado de servers, hasta encontrar uno que funcione + # We go through the list of servers, until we find one that works for play_item in play_items: play_item = item.clone(**play_item.__dict__) play_item.contentAction = play_item.action @@ -777,7 +769,7 @@ def download_from_best_server(item): # if progreso.iscanceled(): # result["downloadStatus"] = STATUS_CODES.canceled - # Tanto si se cancela la descarga como si se completa dejamos de probar mas opciones + # Whether the download is canceled or completed, we stop trying more options if result["downloadStatus"] in [STATUS_CODES.canceled, STATUS_CODES.completed]: result["downloadServer"] = {"url": play_item.url, "server": play_item.server} break @@ -820,7 +812,7 @@ def select_server(item): # if there is only one server select it seleccion = 1 else: - # altrimenti mostra la finestra di selezione + # otherwise it shows the selection window seleccion = platformtools.dialog_select(config.get_localized_string(70192), ["Auto"] + [s.title for s in play_items]) if seleccion >= 1: @@ -835,14 +827,14 @@ def select_server(item): def start_download(item): log("contentAction: %s | contentChannel: %s | url: %s" % (item.contentAction, item.contentChannel, item.url)) - # Ya tenemnos server, solo falta descargar + # We already have a server, we just need to download if item.contentAction == "play": ret = download_from_server(item) elif item.downloadServer and item.downloadServer.get("server"): ret = download_from_server( item.clone(server=item.downloadServer.get("server"), url=item.downloadServer.get("url"), contentAction="play")) - # No tenemos server, necesitamos buscar el mejor + # We don't have a server, we need to find the best else: ret = download_from_best_server(item) @@ -861,21 +853,21 @@ def get_episodes(item): season_number = item.dlseason else: season = False - # El item que pretendemos descargar YA es un episodio + # The item we want to download NOW is an episode if item.contentType == "episode": episodes = [item.clone()] - # El item es uma serie o temporada + # The item is a series or season elif item.contentType in ["tvshow", "season"]: if item.downloadItemlist: episodes = [Item().fromurl(i) for i in item.downloadItemlist] else: - # importamos el canal + # The item is a series or season... if item.contentChannel in ['community', 'videolibrary']: channel = __import__('specials.%s' % item.contentChannel, None, None, ["specials.%s" % item.contentChannel]) else: channel = __import__('channels.%s' % item.contentChannel, None, None, ["channels.%s" % item.contentChannel]) - # Obtenemos el listado de episodios + # We get the list of episodes episodes = getattr(channel, item.contentAction)(item) itemlist = [] @@ -888,38 +880,38 @@ def get_episodes(item): else: renumber(episodes, item) - # Tenemos las lista, ahora vamos a comprobar + # We get the list of episodes... for episode in episodes: - # Si partiamos de un item que ya era episodio estos datos ya están bien, no hay que modificarlos + # If we started from an item that was already an episode, this data is already good, it should not be modified if item.contentType != "episode": episode.contentAction = episode.action episode.contentChannel = episode.channel - # Si el resultado es una temporada, no nos vale, tenemos que descargar los episodios de cada temporada + # If the result is a season, it is not worth it, we have to download the episodes of each season if episode.contentType == "season": itemlist.extend(get_episodes(episode)) - # Si el resultado es un episodio ya es lo que necesitamos, lo preparamos para añadirlo a la descarga + # If the result is an episode is already what we need, we prepare it to add it to the download if episode.contentType == "episode": - # Pasamos el id al episodio + # We pass the id to the episode if not episode.infoLabels["tmdb_id"]: episode.infoLabels["tmdb_id"] = item.infoLabels["tmdb_id"] - # Episodio, Temporada y Titulo + # Episode, Season and Title if not episode.contentSeason or not episode.contentEpisodeNumber: season_and_episode = scrapertools.get_season_and_episode(episode.title) if season_and_episode: episode.contentSeason = season_and_episode.split("x")[0] episode.contentEpisodeNumber = season_and_episode.split("x")[1] - # Buscamos en tmdb + # Episode, Season and Title... if item.infoLabels["tmdb_id"]: scraper.find_and_set_infoLabels(episode) - # Episodio, Temporada y Titulo + # Episode, Season and Title if not episode.contentTitle: - episode.contentTitle = re.sub("\[[^\]]+\]|\([^\)]+\)|\d*x\d*\s*-", "", episode.title).strip() + episode.contentTitle = re.sub(r"\[[^\]]+\]|\([^\)]+\)|\d*x\d*\s*-", "", episode.title).strip() episode.downloadFilename = filetools.validate_path(filetools.join(item.downloadFilename, "%dx%0.2d - %s" % (episode.contentSeason, episode.contentEpisodeNumber, episode.contentTitle.strip()))) if season: @@ -929,11 +921,11 @@ def get_episodes(item): itemlist.append(episode) - # Cualquier otro resultado no nos vale, lo ignoramos + # Any other result is not worth it, we ignore it else: log("Omitiendo item no válido:", episode.tostring()) - # if Multiple Languages or Qualities + # Any other result is not worth it, we ignore it... itemlist = videolibrarytools.filter_list(itemlist) return itemlist @@ -1079,8 +1071,7 @@ def save_download_movie(item): progreso.close() if not platformtools.dialog_yesno(config.get_localized_string(30101), config.get_localized_string(70189)): - platformtools.dialog_ok(config.get_localized_string(30101), item.contentTitle, - config.get_localized_string(30109)) + platformtools.dialog_ok(config.get_localized_string(30101), item.contentTitle, config.get_localized_string(30109)) else: play_item = select_server(item) if play_item == 'Auto': @@ -1144,10 +1135,10 @@ def save_download_tvshow(item): def set_movie_title(item): if not item.contentTitle: - item.contentTitle = re.sub("\[[^\]]+\]|\([^\)]+\)", "", item.contentTitle).strip() + item.contentTitle = re.sub(r"\[[^\]]+\]|\([^\)]+\)", "", item.contentTitle).strip() if not item.contentTitle: - item.contentTitle = re.sub("\[[^\]]+\]|\([^\)]+\)", "", item.title).strip() + item.contentTitle = re.sub(r"\[[^\]]+\]|\([^\)]+\)", "", item.title).strip() def show_disclaimer():