diff options
Diffstat (limited to 'pyload')
| -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"> | 
