summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-12-30 19:52:29 +0100
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-12-30 19:52:29 +0100
commit1e338a279aba747534fd1e7aedc8d7aec319f5f2 (patch)
tree87f809fabd8c11f45d193475937223bfd097e33c
parentadded progress type enum, new DebugCrypter + Hoster, little improvements for ... (diff)
downloadpyload-1e338a279aba747534fd1e7aedc8d7aec319f5f2.tar.xz
show progress of decrypting and link checking, added indicator in link grabber
-rw-r--r--pyload/threads/AddonThread.py4
-rw-r--r--pyload/threads/BaseThread.py4
-rw-r--r--pyload/threads/DecrypterThread.py26
-rw-r--r--pyload/threads/InfoThread.py20
-rw-r--r--pyload/threads/ThreadManager.py16
-rw-r--r--pyload/web/app/scripts/collections/ProgressList.js8
-rw-r--r--pyload/web/app/scripts/default.js6
-rw-r--r--pyload/web/app/scripts/views/headerView.js16
-rw-r--r--pyload/web/app/scripts/views/linkgrabber/modalView.js22
-rwxr-xr-xpyload/web/app/templates/default/linkgrabber/modal.html4
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}}
&nbsp;<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">