diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2013-12-30 19:52:29 +0100 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2013-12-30 19:52:29 +0100 |
commit | 1e338a279aba747534fd1e7aedc8d7aec319f5f2 (patch) | |
tree | 87f809fabd8c11f45d193475937223bfd097e33c | |
parent | added progress type enum, new DebugCrypter + Hoster, little improvements for ... (diff) | |
download | pyload-1e338a279aba747534fd1e7aedc8d7aec319f5f2.tar.xz |
show progress of decrypting and link checking, added indicator in link grabber
-rw-r--r-- | pyload/threads/AddonThread.py | 4 | ||||
-rw-r--r-- | pyload/threads/BaseThread.py | 4 | ||||
-rw-r--r-- | pyload/threads/DecrypterThread.py | 26 | ||||
-rw-r--r-- | pyload/threads/InfoThread.py | 20 | ||||
-rw-r--r-- | pyload/threads/ThreadManager.py | 16 | ||||
-rw-r--r-- | pyload/web/app/scripts/collections/ProgressList.js | 8 | ||||
-rw-r--r-- | pyload/web/app/scripts/default.js | 6 | ||||
-rw-r--r-- | pyload/web/app/scripts/views/headerView.js | 16 | ||||
-rw-r--r-- | pyload/web/app/scripts/views/linkgrabber/modalView.js | 22 | ||||
-rwxr-xr-x | pyload/web/app/templates/default/linkgrabber/modal.html | 4 |
10 files changed, 102 insertions, 24 deletions
diff --git a/pyload/threads/AddonThread.py b/pyload/threads/AddonThread.py index d8d84cbfa..c82045803 100644 --- a/pyload/threads/AddonThread.py +++ b/pyload/threads/AddonThread.py @@ -21,7 +21,7 @@ class AddonThread(BaseThread): self.active = [] self.progress = 0 - m.localThreads.append(self) + m.addThread(self) self.start() @@ -76,4 +76,4 @@ class AddonThread(BaseThread): for x in local: self.finishFile(x) - self.m.localThreads.remove(self)
\ No newline at end of file + self.finished()
\ No newline at end of file diff --git a/pyload/threads/BaseThread.py b/pyload/threads/BaseThread.py index 9b4e5af67..a370bd661 100644 --- a/pyload/threads/BaseThread.py +++ b/pyload/threads/BaseThread.py @@ -30,6 +30,10 @@ class BaseThread(Thread): def user(self): return primary_uid(self.owner) + def finished(self): + """ Remove thread from list """ + self.m.removeThread(self) + def getProgress(self): """ retrieves progress information about the current running task diff --git a/pyload/threads/DecrypterThread.py b/pyload/threads/DecrypterThread.py index a0bebdfbf..c7a01683a 100644 --- a/pyload/threads/DecrypterThread.py +++ b/pyload/threads/DecrypterThread.py @@ -3,13 +3,14 @@ from time import sleep -from pyload.Api import LinkStatus, DownloadStatus as DS +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""" @@ -19,15 +20,22 @@ class DecrypterThread(BaseThread): # [... (plugin, url) ...] self.data = data self.pid = pid + # holds the progress, while running + self.progress = None + self.m.addThread(self) self.start() + def getProgress(self): + return self.progress + def run(self): pack = self.m.core.files.getPackage(self.pid) 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}) + self.log.info( + _("Decrypted %(count)d links into package %(name)s") % {"count": len(links), "name": pack.name}) self.m.core.api.addFiles(self.pid, [l.url for l in links]) # TODO: add single package into this one and rename it? @@ -35,17 +43,25 @@ class DecrypterThread(BaseThread): for p in packages: self.m.core.api.addPackage(p.name, p.getURLs(), pack.password) + self.finished() + 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.m.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: plugin_result.extend(LinkStatus(url, url, -1, DS.NotPossible, name) for url in urls) self.log.debug("Plugin for decrypting was not loaded") @@ -77,8 +93,12 @@ class DecrypterThread(BaseThread): 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 diff --git a/pyload/threads/InfoThread.py b/pyload/threads/InfoThread.py index 8d33df705..a91ca679e 100644 --- a/pyload/threads/InfoThread.py +++ b/pyload/threads/InfoThread.py @@ -3,7 +3,7 @@ from time import time -from pyload.Api import LinkStatus, DownloadStatus +from pyload.Api import LinkStatus, DownloadStatus, ProgressInfo, ProgressType from pyload.utils.packagetools import parseNames from pyload.utils import has_method, accumulate @@ -22,6 +22,7 @@ class InfoThread(DecrypterThread): # urls that already have a package name self.names = {} + self.m.addThread(self) self.start() def run(self): @@ -54,6 +55,9 @@ class InfoThread(DecrypterThread): # db or info result cb = self.updateDB if self.pid > 1 else self.updateResult + self.progress = ProgressInfo("BasePlugin", "", _("online check"), 0, 0, sum(len(urls) for urls in plugins.itervalues()), + self.owner, ProgressType.LinkCheck) + for pluginname, urls in plugins.iteritems(): plugin = self.m.core.pluginManager.loadModule("hoster", pluginname) klass = self.m.core.pluginManager.getPluginClass("hoster", pluginname, overwrite=False) @@ -69,6 +73,8 @@ class InfoThread(DecrypterThread): self.names.clear() self.m.timestamp = time() + 5 * 60 + self.progress = None + self.finished() def updateDB(self, result): # writes results to db @@ -100,6 +106,12 @@ class InfoThread(DecrypterThread): """executes info fetching for given plugin and urls""" # also works on module names pluginname = plugin.__name__.split(".")[-1] + + self.progress.plugin = pluginname + self.progress.name = _("Checking %d links") % len(urls) + + # final number of links to be checked + done = self.progress.done + len(urls) try: cached = [] #results loaded from cache process = [] #urls to process @@ -111,6 +123,7 @@ class InfoThread(DecrypterThread): if cached: self.m.log.debug("Fetched %d links from cache for %s" % (len(cached), pluginname)) + self.progress.done += len(cached) cb(cached) if process: @@ -135,10 +148,13 @@ class InfoThread(DecrypterThread): for link in links: self.m.infoCache[link.url] = link + self.progress.done += len(links) cb(links) self.m.log.debug("Finished Info Fetching for %s" % pluginname) except Exception, e: self.m.log.warning(_("Info Fetching for %(name)s failed | %(err)s") % {"name": pluginname, "err": str(e)}) - self.core.print_exc()
\ No newline at end of file + self.core.print_exc() + finally: + self.progress.done = done
\ No newline at end of file diff --git a/pyload/threads/ThreadManager.py b/pyload/threads/ThreadManager.py index 3132e98e2..0e0b6320d 100644 --- a/pyload/threads/ThreadManager.py +++ b/pyload/threads/ThreadManager.py @@ -19,7 +19,7 @@ from os.path import exists, join import re from subprocess import Popen -from threading import Event, Lock +from threading import Event, RLock from time import sleep, time from traceback import print_exc from random import choice @@ -53,7 +53,7 @@ class ThreadManager: self.reconnecting.clear() self.downloaded = 0 #number of files downloaded since last cleanup - self.lock = Lock() + self.lock = RLock() # some operations require to fetch url info from hoster, so we caching them so it wont be done twice # contains a timestamp and will be purged after timeout @@ -71,13 +71,23 @@ class ThreadManager: for i in range(self.core.config.get("download", "max_downloads")): self.createThread() - def createThread(self): """create a download thread""" thread = DownloadThread(self) self.threads.append(thread) + @lock + def addThread(self, thread): + self.localThreads.append(thread) + + @lock + def removeThread(self, thread): + """ Remove a thread from the local list """ + if thread in self.localThreads: + self.localThreads.remove(thread) + + @lock def createInfoThread(self, data, pid): """ start a thread which fetches online status and other info's """ self.timestamp = time() + 5 * 60 diff --git a/pyload/web/app/scripts/collections/ProgressList.js b/pyload/web/app/scripts/collections/ProgressList.js index 51849d8de..51132d86d 100644 --- a/pyload/web/app/scripts/collections/ProgressList.js +++ b/pyload/web/app/scripts/collections/ProgressList.js @@ -11,6 +11,14 @@ define(['jquery', 'backbone', 'underscore', 'models/Progress'], function($, Back initialize: function() { + }, + + // returns all progresses, that bit matches the given type + // types have to be or'ed + byType: function(types) { + return this.filter(function(progress) { + return (progress.get('type') & types) !== 0; + }); } }); diff --git a/pyload/web/app/scripts/default.js b/pyload/web/app/scripts/default.js index d66c0e1f8..8a8d122f8 100644 --- a/pyload/web/app/scripts/default.js +++ b/pyload/web/app/scripts/default.js @@ -1,6 +1,6 @@ define('default', ['require', 'backbone', 'jquery', 'app', 'router', - 'models/UserSession', 'models/AddonHandler'], - function(require, Backbone, $, App, Router, UserSession, AddonHandler) { + 'models/UserSession', 'models/AddonHandler', 'collections/ProgressList'], + function(require, Backbone, $, App, Router, UserSession, AddonHandler, ProgressList) { 'use strict'; // Global ajax options @@ -21,7 +21,9 @@ define('default', ['require', 'backbone', 'jquery', 'app', 'router', return Backbone.$.ajax.apply(Backbone.$, arguments); }; + // global available models / collections App.addons = new AddonHandler(); + App.progressList = new ProgressList(); $(function() { // load setup async diff --git a/pyload/web/app/scripts/views/headerView.js b/pyload/web/app/scripts/views/headerView.js index 7d892bf01..d4d07ac39 100644 --- a/pyload/web/app/scripts/views/headerView.js +++ b/pyload/web/app/scripts/views/headerView.js @@ -1,8 +1,8 @@ -define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'collections/ProgressList', +define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'views/progressView', 'views/notificationView', 'helpers/formatSize', 'hbs!tpl/header/layout', 'hbs!tpl/header/status', 'hbs!tpl/header/progressbar', 'hbs!tpl/header/progressSup', 'hbs!tpl/header/progressSub' , 'flot'], function( - $, _, Backbone, App, ServerStatus, ProgressList, ProgressView, NotificationView, formatSize, template, templateStatus, templateProgress, templateSup, templateSub) { + $, _, Backbone, App, ServerStatus, ProgressView, NotificationView, formatSize, template, templateStatus, templateProgress, templateSup, templateSub) { 'use strict'; // Renders the header with all information return Backbone.Marionette.ItemView.extend({ @@ -32,7 +32,6 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'colle // models and data ws: null, status: null, - progressList: null, speeds: null, // sub view @@ -51,8 +50,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'colle this.status = new ServerStatus(); this.listenTo(this.status, 'change', this.update); - this.progressList = new ProgressList(); - this.listenTo(this.progressList, 'add', function(model) { + this.listenTo(App.progressList, 'add', function(model) { self.ui.progress.appendWithAnimation(new ProgressView({model: model}).render().el); }); @@ -140,7 +138,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'colle ); var data = {tasks: 0, downloads: 0, speed: 0, single: false}; - this.progressList.each(function(progress) { + App.progressList.each(function(progress) { if (progress.isDownload()) { data.downloads++; data.speed += progress.get('download').speed; @@ -150,7 +148,7 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'colle // Show progress of one task if (data.tasks + data.downloads === 1) { - var progress = this.progressList.at(0); + var progress = App.progressList.at(0); data.single = true; data.eta = progress.get('eta'); data.percent = progress.getPercent(); @@ -233,9 +231,9 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/ServerStatus', 'colle prog.pid = prog.plugin + prog.name; }); - this.progressList.set(progress); + App.progressList.set(progress); // update currently open files with progress - this.progressList.each(function(prog) { + App.progressList.each(function(prog) { if (prog.isDownload() && App.dashboard.files) { var file = App.dashboard.files.get(prog.get('download').fid); if (file) { diff --git a/pyload/web/app/scripts/views/linkgrabber/modalView.js b/pyload/web/app/scripts/views/linkgrabber/modalView.js index 950c0ce2f..9bdb7f4e2 100644 --- a/pyload/web/app/scripts/views/linkgrabber/modalView.js +++ b/pyload/web/app/scripts/views/linkgrabber/modalView.js @@ -1,5 +1,5 @@ -define(['jquery', 'underscore', 'backbone', 'app', 'models/CollectorPackage', 'views/abstract/modalView', './collectorView', 'hbs!tpl/linkgrabber/modal'], - function($, _, Backbone, App, CollectorPackage, modalView, CollectorView, template) { +define(['jquery', 'underscore', 'backbone', 'app', 'utils/apitypes', 'models/CollectorPackage', 'views/abstract/modalView', './collectorView', 'hbs!tpl/linkgrabber/modal'], + function($, _, Backbone, App, Api, CollectorPackage, modalView, CollectorView, template) { 'use strict'; // Modal dialog for package adding - triggers package:added when package was added return modalView.extend({ @@ -24,6 +24,11 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/CollectorPackage', 'v // Inherit parent events this.events = _.extend({}, modalView.prototype.events, this.events); this.listenTo(App.vent, 'collectorPackage:added', _.bind(this.onAdded, this)); + + var update = _.bind(this.onProgressChange, this); + this.listenTo(App.progressList, 'add', update); + this.listenTo(App.progressList, 'remove', update); + this.listenTo(App.progressList, 'change', update); }, // sets a new models as target and render @@ -123,7 +128,18 @@ define(['jquery', 'underscore', 'backbone', 'app', 'models/CollectorPackage', 'v onDestroy: function() { if (this.collectorView) this.collectorView.close(); - } + }, + onProgressChange: function() { + var progress = App.progressList.byType(Api.ProgressType.LinkCheck | Api.ProgressType.Decrypting); + if (progress.length > 0) { + // show indicator + this.$('.status-text').html(progress[0].get('statusmsg')); + this.$('.status').fadeIn(); + } else { + // hide indicator + this.$('.status').fadeOut(); + } + } }); });
\ No newline at end of file diff --git a/pyload/web/app/templates/default/linkgrabber/modal.html b/pyload/web/app/templates/default/linkgrabber/modal.html index c07d8beb1..15f255bd7 100755 --- a/pyload/web/app/templates/default/linkgrabber/modal.html +++ b/pyload/web/app/templates/default/linkgrabber/modal.html @@ -35,6 +35,10 @@ {{_ "Packages" }} {{/if}} <button class="btn btn-danger btn-small btn-remove-all"><i class="icon-trash"></i></button> + <span class="status pull-right" style="opacity: 0"> + <small class="status-text"></small> + <i class="icon-spinner icon-spin"></i> + </span> </legend> <div class="container-fluid prepared-packages"> |