#!/usr/bin/env python # -*- coding: utf-8 -*- from time import sleep from pyload.Api import LinkStatus, DownloadStatus as DS, ProgressInfo, ProgressType from pyload.utils import uniqify, accumulate from pyload.plugins.Base import Abort, Retry from pyload.plugins.Crypter import Package from BaseThread import BaseThread class DecrypterThread(BaseThread): """thread for decrypting""" def __init__(self, manager, data, fid, pid, owner): BaseThread.__init__(self, manager, owner) # [... (url, plugin) ...] self.data = data self.fid = fid self.pid = pid # holds the progress, while running self.progress = None # holds if an error happened self.error = False self.start() def getProgress(self): return self.progress def run(self): pack = self.core.files.getPackage(self.pid) api = self.core.api.withUserContext(self.owner) links, packages = self.decrypt(accumulate(self.data), pack.password) if links: self.log.info( _("Decrypted %(count)d links into package %(name)s") % {"count": len(links), "name": pack.name}) api.addLinks(self.pid, [l.url for l in links]) # if there is only one package links will be added to current one if len(packages) == 1: api.addLinks(self.pid, packages[0].getURLs()) else: for p in packages: api.addPackage(p.name, p.getURLs(), pack.password) self.core.files.setDownloadStatus(self.fid, DS.Finished if not self.error else DS.Failed) self.m.done(self) def decrypt(self, plugin_map, password=None, err=False): result = [] self.progress = ProgressInfo("BasePlugin", "", _("decrypting"), 0, 0, len(self.data), self.owner, ProgressType.Decrypting) # TODO QUEUE_DECRYPT for name, urls in plugin_map.iteritems(): klass = self.core.pluginManager.loadClass("crypter", name) plugin = None plugin_result = [] # updating progress self.progress.plugin = name self.progress.name = _("Decrypting %s links") % len(urls) if len(urls) > 1 else urls[0] #TODO: dependency check, there is a new error code for this # TODO: decrypting with result yielding if not klass: self.error = True if err: plugin_result.extend(LinkStatus(url, url, -1, DS.NotPossible, name) for url in urls) self.log.debug("Plugin '%s' for decrypting was not loaded" % name) else: try: plugin = klass(self.core, password) try: plugin_result = plugin._decrypt(urls) except Retry: sleep(1) plugin_result = plugin._decrypt(urls) plugin.logDebug("Decrypted", plugin_result) except Abort: plugin.logInfo(_("Decrypting aborted")) except Exception, e: plugin.logError(_("Decrypting failed"), e) self.error = True # generate error linkStatus if err: plugin_result.extend(LinkStatus(url, url, -1, DS.Failed, name) for url in urls) if self.core.debug: self.core.print_exc() self.writeDebugReport(plugin.__name__, plugin=plugin) finally: if plugin: plugin.clean() self.progress.done += len(urls) result.extend(plugin_result) # clear the progress self.progress = None # generated packages packs = {} # urls without package urls = [] # merge urls and packages for p in result: if isinstance(p, Package): if p.name in packs: packs[p.name].urls.extend(p.urls) else: if not p.name: urls.extend(p.links) else: packs[p.name] = p else: urls.append(p) urls = uniqify(urls) return urls, packs.values()