From 183078baff15034e919ef7cd84e9a683255bc2a6 Mon Sep 17 00:00:00 2001 From: marco Date: Fri, 27 Mar 2020 15:43:23 +0100 Subject: [PATCH] download in background (beta) e migliore varie ai download --- core/downloader.py | 22 ++++++- platformcode/platformtools.py | 4 +- resources/language/English/strings.po | 12 ++++ resources/language/Italian/strings.po | 14 ++++- specials/downloads.py | 82 +++++++++++++++++++++------ 5 files changed, 111 insertions(+), 23 deletions(-) diff --git a/core/downloader.py b/core/downloader.py index e5baf8ec..b792bcd8 100644 --- a/core/downloader.py +++ b/core/downloader.py @@ -19,6 +19,9 @@ metodos: """ from __future__ import division from future import standard_library + +from core.item import Item + standard_library.install_aliases() from builtins import range from builtins import object @@ -112,9 +115,13 @@ class Downloader(object): self.speed[1], self.speed[2], self.connections[0], self.connections[1]) line3 = config.get_localized_string(60202) % (self.remaining_time) - progreso.update(int(self.progress), line1, line2 + line3) + progreso.update(int(self.progress), line1, line2 + '\n' + line3) + self.__update_json() + + progreso.close() def start(self): + self.__update_json(started=False) if self._state == self.states.error: return conns = [] for x in range(self._max_connections): @@ -187,7 +194,7 @@ class Downloader(object): # Funciones internas def __init__(self, url, path, filename=None, headers=[], resume=True, max_connections=10, block_size=2 ** 17, - part_size=2 ** 24, max_buffer=10): + part_size=2 ** 24, max_buffer=10, json_path=None): # Parametros self._resume = resume self._path = path @@ -196,6 +203,7 @@ class Downloader(object): self._block_size = block_size self._part_size = part_size self._max_buffer = max_buffer + self._json_path = json_path try: import xbmc @@ -576,3 +584,13 @@ class Downloader(object): self.__set_part_stopped__(id) logger.info("Thread stopped: %s" % threading.current_thread().name) + + def __update_json(self, started=True): + item = Item().fromjson(filetools.read(self._json_path)) + if started and item.downloadStatus == 0: # stopped + logger.info('Download paused') + self.stop() + elif item.downloadProgress != self.progress or not started: + params = {"downloadStatus": 4, "downloadComplete": 0, "downloadProgress": self.progress} + item.__dict__.update(params) + filetools.write(self._json_path, item.tojson()) diff --git a/platformcode/platformtools.py b/platformcode/platformtools.py index 5c98d531..ca94d8f2 100644 --- a/platformcode/platformtools.py +++ b/platformcode/platformtools.py @@ -591,7 +591,7 @@ def set_context_commands(item, parent_item): channel="infoplus", action="start", from_channel=item.channel).tourl()))) # Ir al Menu Principal (channel.mainlist) - if parent_item.channel not in ["news", "channelselector"] and item.action != "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()))) @@ -666,7 +666,7 @@ def set_context_commands(item, parent_item): (sys.argv[0], item.clone(action="add_pelicula_to_library", from_action=item.action).tourl()))) - if item.channel not in ["downloads", "videolibrary"] and item.server != 'torrent': + if item.channel not in ["downloads", "videolibrary"] and item.server != 'torrent' and config.get_setting('downloadenabled'): # Descargar pelicula if item.contentType == "movie": context_commands.append((config.get_localized_string(60354), "XBMC.RunPlugin(%s?%s)" % diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index 4a3b1fbb..0b337ef1 100644 --- a/resources/language/English/strings.po +++ b/resources/language/English/strings.po @@ -6101,4 +6101,16 @@ msgstr "" msgctxt "#80014" msgid "The video library has been moved" +msgstr "" + +msgctxt "#80015" +msgid "Stop download" +msgstr "" + +msgctxt "#80016" +msgid "Play" +msgstr "" + +msgctxt "#80017" +msgid "Stop all" msgstr "" \ No newline at end of file diff --git a/resources/language/Italian/strings.po b/resources/language/Italian/strings.po index 85159a58..44042279 100644 --- a/resources/language/Italian/strings.po +++ b/resources/language/Italian/strings.po @@ -6101,4 +6101,16 @@ msgstr "Aggiornamento database..." msgctxt "#80014" msgid "The video library has been moved" -msgstr "La videoteca è stata spostata" \ No newline at end of file +msgstr "La videoteca è stata spostata" + +msgctxt "#80015" +msgid "Stop download" +msgstr "Stoppa download" + +msgctxt "#80016" +msgid "Play" +msgstr "Riproduci" + +msgctxt "#80017" +msgid "Stop all" +msgstr "Stoppa tutti" \ No newline at end of file diff --git a/specials/downloads.py b/specials/downloads.py index 925f70df..27f0a04e 100644 --- a/specials/downloads.py +++ b/specials/downloads.py @@ -15,17 +15,16 @@ import re import time import unicodedata from threading import Thread - +import xbmc from core import filetools, jsontools, scraper, scrapertools, servertools, videolibrarytools, support from core.downloader import Downloader from core.item import Item from platformcode import config, logger from platformcode import platformtools -from platformcode.launcher import downloaderObj -STATUS_COLORS = {0: "orange", 1: "orange", 2: "green", 3: "red"} -STATUS_CODES = type("StatusCode", (), {"stoped": 0, "canceled": 1, "completed": 2, "error": 3}) +STATUS_COLORS = {0: "black", 1: "black", 2: "green", 3: "red", 4: "yellow"} +STATUS_CODES = type("StatusCode", (), {"stoped": 0, "canceled": 1, "completed": 2, "error": 3, "downloading": 4}) DOWNLOAD_LIST_PATH = config.get_setting("downloadlistpath") DOWNLOAD_PATH = config.get_setting("downloadpath") STATS_FILE = filetools.join(config.get_data_path(), "servers.json") @@ -95,13 +94,13 @@ def mainlist(item): 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, - contentSerieName=item.contentSerieName, text_color="sandybrown")) + contentSerieName=item.contentSerieName, text_color=STATUS_COLORS[STATUS_CODES.completed])) # Si hay alguno con 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, - contentSerieName=item.contentSerieName, text_color="orange")) + contentSerieName=item.contentSerieName, text_color=STATUS_COLORS[STATUS_CODES.error])) # Si hay alguno pendiente if 1 in estados or 0 in estados: @@ -114,6 +113,13 @@ def mainlist(item): contentType=item.contentType, contentChannel=item.contentChannel, contentSerieName=item.contentSerieName)) + # if there's at least one downloading + if 4 in estados: + itemlist.insert(0, Item(channel=item.channel, action="stop_all", title=config.get_localized_string(80017), + contentType=item.contentType, contentChannel=item.contentChannel, + contentSerieName=item.contentSerieName, + text_color=STATUS_COLORS[STATUS_CODES.downloading])) + if not item.contentType == "tvshow" and config.get_setting("browser") == True: itemlist.insert(0, Item(channel=item.channel, action="browser", title=support.typo(config.get_localized_string(70222),'bold'),url=DOWNLOAD_PATH)) @@ -132,7 +138,6 @@ def settings(item): def browser(item): logger.info() itemlist = [] - context = [{ 'title': 'cancella', 'channel': 'downloads', 'action': "del_file"}] for file in filetools.listdir(item.url): if file == "list": continue @@ -145,15 +150,18 @@ def browser(item): def del_file(item): - ok = platformtools.dialog_yesno(config.get_localized_string(30039),config.get_localized_string(30040)) + ok = platformtools.dialog_yesno(config.get_localized_string(30039),config.get_localized_string(30040) % item.title) if ok: filetools.remove(item.url) + xbmc.sleep(100) platformtools.itemlist_refresh() + def del_dir(item): ok = platformtools.dialog_yesno(config.get_localized_string(30037),config.get_localized_string(30038)) if ok: filetools.rmdirtree(item.url) + xbmc.sleep(100) platformtools.itemlist_refresh() @@ -166,7 +174,19 @@ def clean_all(item): if not item.contentType == "tvshow" or ( item.contentSerieName == download_item.contentSerieName and item.contentChannel == download_item.contentChannel): filetools.remove(filetools.join(DOWNLOAD_LIST_PATH, fichero)) + xbmc.sleep(100) + platformtools.itemlist_refresh() + +def stop_all(item): + logger.info() + + for fichero in sorted(filetools.listdir(DOWNLOAD_LIST_PATH)): + if fichero.endswith(".json"): + download_item = Item().fromjson(filetools.read(filetools.join(DOWNLOAD_LIST_PATH, fichero))) + if download_item.downloadStatus == 4: + update_json(filetools.join(DOWNLOAD_LIST_PATH, fichero), {"downloadStatus": STATUS_CODES.stoped}) + xbmc.sleep(100) platformtools.itemlist_refresh() @@ -205,6 +225,13 @@ def restart_error(item): def download_all(item): time.sleep(0.5) + item.action = "download_all_background" + xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")") + xbmc.sleep(100) + platformtools.itemlist_refresh() + + +def download_all_background(item): for fichero in sorted(filetools.listdir(DOWNLOAD_LIST_PATH)): if fichero.endswith(".json"): download_item = Item(path=filetools.join(DOWNLOAD_LIST_PATH, fichero)).fromjson( @@ -227,30 +254,37 @@ def menu(item): servidor = "Auto" # Opciones disponibles para el menu op = [config.get_localized_string(70225), config.get_localized_string(70226), config.get_localized_string(70227), - config.get_localized_string(30165) % (servidor.capitalize())] + config.get_localized_string(30165) % (servidor.capitalize()), config.get_localized_string(80015), + config.get_localized_string(80016)] opciones = [] # Opciones para el menu - if item.downloadStatus == 0: # Sin descargar + 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 - if item.downloadStatus == 1: # descarga parcial + 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 - if item.downloadStatus == 2: # descarga completada + 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 - if item.downloadStatus == 3: # descarga con error + 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.downloading: + opciones.append(op[5]) # Play + opciones.append(op[4]) # pause download + opciones.append(op[1]) # Eliminar de la lista + # Mostramos el dialogo seleccion = platformtools.dialog_select(config.get_localized_string(30163), opciones) @@ -264,8 +298,8 @@ def menu(item): # Opcion inicaiar descarga if opciones[seleccion] == op[0]: - th = Thread(target=start_download, args=(item,)) - th.start() + item.action = "start_download" + xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")") # Elegir Servidor if opciones[seleccion] == op[3]: @@ -279,6 +313,14 @@ def menu(item): update_json(item.path, {"downloadStatus": STATUS_CODES.stoped, "downloadComplete": 0, "downloadProgress": 0, "downloadServer": {}}) + if opciones[seleccion] == op[4]: + update_json(item.path, {"downloadStatus": STATUS_CODES.stoped}) + + if opciones[seleccion] == op[5]: + platformtools.play_video(Item(channel="downloads", title=item.downloadFilename, action="play", + url=filetools.join(DOWNLOAD_PATH, item.downloadFilename), infoLabels=item.infoLabels)) + + xbmc.sleep(100) platformtools.itemlist_refresh() @@ -525,7 +567,8 @@ def download_from_url(url, item): max_connections=1 + int(config.get_setting("max_connections", "downloads")), block_size=2 ** (17 + int(config.get_setting("block_size", "downloads"))), part_size=2 ** (20 + int(config.get_setting("part_size", "downloads"))), - max_buffer=2 * int(config.get_setting("max_buffer", "downloads"))) + max_buffer=2 * int(config.get_setting("max_buffer", "downloads")), + json_path=item.path) d.start_dialog(config.get_localized_string(60332)) # Descarga detenida. Obtenemos el estado: @@ -830,14 +873,18 @@ def write_json(item): item.__dict__.pop(name) path = filetools.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json") - filetools.write(path, item.tojson()) item.path = path + filetools.write(path, item.tojson()) time.sleep(0.1) def save_download(item): logger.info() + item.action = "save_download_background" + xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")") + +def save_download_background(item): # Menu contextual if item.from_action and item.from_channel: item.channel = item.from_channel @@ -859,7 +906,6 @@ def save_download(item): elif item.contentType == "movie": save_download_movie(item) - else: save_download_video(item)