diff options
-rw-r--r-- | module/Api.py | 2 | ||||
-rw-r--r-- | module/database/FileDatabase.py | 10 | ||||
-rw-r--r-- | module/datatypes/PyFile.py | 26 | ||||
-rw-r--r-- | module/datatypes/PyPackage.py | 5 | ||||
-rw-r--r-- | module/network/Browser.py | 4 | ||||
-rw-r--r-- | module/network/HTTPDownload.py | 9 | ||||
-rw-r--r-- | module/plugins/Hoster.py | 4 | ||||
-rw-r--r-- | module/threads/AddonThread.py | 2 | ||||
-rw-r--r-- | module/threads/BaseThread.py | 12 | ||||
-rw-r--r-- | module/threads/DownloadThread.py | 12 | ||||
-rw-r--r-- | module/threads/ThreadManager.py | 16 | ||||
-rw-r--r-- | module/web/static/js/views/modal/modalView.js | 2 | ||||
-rw-r--r-- | module/web/static/js/views/packageTreeView.js | 2 |
13 files changed, 59 insertions, 47 deletions
diff --git a/module/Api.py b/module/Api.py index cfe1815c1..cf28fda5f 100644 --- a/module/Api.py +++ b/module/Api.py @@ -170,7 +170,7 @@ class Api(Iface): not self.core.threadManager.pause and self.isTimeDownload(), self.core.config['reconnect']['activated'] and self.isTimeReconnect()) - for pyfile in [x.active for x in self.core.threadManager.threads if x.active and isinstance(x.active, PyFile)]: + for pyfile in self.core.threadManager.getActiveDownloads(): serverStatus.speed += pyfile.getSpeed() #bytes/s return serverStatus diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py index e065b84e2..410f1088e 100644 --- a/module/database/FileDatabase.py +++ b/module/database/FileDatabase.py @@ -342,7 +342,7 @@ class FileMethods(DatabaseMethods): # TODO: multi user approach @queue def getJob(self, occ): - """return pyfile ids, which are suitable for download and dont use a occupied plugin""" + """return pyfile ids, which are suitable for download and don't use a occupied plugin""" cmd = "(%s)" % ", ".join(["'%s'" % x for x in occ]) #TODO @@ -351,7 +351,7 @@ class FileMethods(DatabaseMethods): "WHERE f.plugin NOT IN %s AND f.dlstatus IN (2,3) AND p.status=0 " "ORDER BY p.packageorder ASC, f.fileorder ASC LIMIT 5") % cmd - self.c.execute(cmd) # very bad! + self.c.execute(cmd) return [x[0] for x in self.c] @@ -370,10 +370,10 @@ class FileMethods(DatabaseMethods): @queue def findDuplicates(self, id, folder, filename): - """ checks if filename exists with different id and same package """ - # TODO + """ checks if filename exists with different id and same package, dlstatus = finished """ + # TODO: also check root of package self.c.execute( - "SELECT l.plugin FROM files f INNER JOIN packages as p ON f.package=p.pid AND p.folder=? WHERE f.fid!=? AND l.status=0 AND l.name=?" + "SELECT f.plugin FROM files f INNER JOIN packages as p ON f.package=p.pid AND p.folder=? WHERE f.fid!=? AND f.dlstatus=5 AND f.name=?" , (folder, id, filename)) return self.c.fetchone() diff --git a/module/datatypes/PyFile.py b/module/datatypes/PyFile.py index 1a515493c..d6270acaa 100644 --- a/module/datatypes/PyFile.py +++ b/module/datatypes/PyFile.py @@ -19,7 +19,7 @@ from time import sleep, time from threading import RLock -from module.Api import FileInfo, DownloadInfo, DownloadStatus +from module.Api import ProgressInfo, DownloadProgress, FileInfo, DownloadInfo, DownloadStatus from module.utils import format_size, format_time, lock statusMap = { @@ -48,8 +48,8 @@ class PyFile(object): """ __slots__ = ("m", "fid", "_name", "_size", "filestatus", "media", "added", "fileorder", "url", "pluginname", "hash", "status", "error", "packageid", "ownerid", - "lock", "plugin", "waitUntil", "active", "abort", "statusname", - "reconnected", "progress", "maxprogress", "pluginclass") + "lock", "plugin", "waitUntil", "abort", "statusname", + "reconnected", "pluginclass") @staticmethod def fromInfoData(m, info): @@ -88,19 +88,14 @@ class PyFile(object): self.lock = RLock() self.plugin = None - #self.download = None self.waitUntil = 0 # time() + time to wait # status attributes - self.active = False #obsolete? self.abort = False self.reconnected = False - self.statusname = None - self.progress = 0 - self.maxprogress = 100 @property def id(self): @@ -249,6 +244,13 @@ class PyFile(object): except: return 0 + def getBytesArrived(self): + """ gets bytes arrived """ + try: + return self.plugin.req.arrived + except: + return 0 + def getBytesLeft(self): """ gets bytes left """ try: @@ -279,7 +281,7 @@ class PyFile(object): def notifyChange(self): self.m.core.eventManager.dispatchEvent("linkUpdated", self.id, self.packageid) - def setProgress(self, value): - if not value == self.progress: - self.progress = value - self.notifyChange() + def getProgressInfo(self): + return ProgressInfo(self.plugin, self.name, self.statusname, self.getETA(), self.formatETA(), + self.getBytesArrived(), self.getSize(), + DownloadProgress(self.fid, self.packageid, self.getSpeed(), self.status)) diff --git a/module/datatypes/PyPackage.py b/module/datatypes/PyPackage.py index be2f23eea..654a36f76 100644 --- a/module/datatypes/PyPackage.py +++ b/module/datatypes/PyPackage.py @@ -47,6 +47,9 @@ class PyPackage: self.packageorder = packageorder self.timestamp = time() + #: Finish event already fired + self.setFinished = False + @property def id(self): self.m.core.log.debug("Deprecated package attr .id, use .pid instead") @@ -62,7 +65,7 @@ class PyPackage: def getChildren(self): """get information about contained links""" - return self.m.getPackageData(self.id)["links"] + return self.m.getPackageData(self.pid)["links"] def getPath(self, name=""): self.timestamp = time() diff --git a/module/network/Browser.py b/module/network/Browser.py index 9cf6c2f30..25cbf669b 100644 --- a/module/network/Browser.py +++ b/module/network/Browser.py @@ -87,11 +87,11 @@ class Browser(object): self.dl.abort = True def httpDownload(self, url, filename, get={}, post={}, ref=True, cookies=True, chunks=1, resume=False, - progressNotify=None, disposition=False): + disposition=False): """ this can also download ftp """ self._size = 0 self.dl = HTTPDownload(url, filename, get, post, self.lastEffectiveURL if ref else None, - self.cj if cookies else None, self.bucket, self.options, progressNotify, disposition) + self.cj if cookies else None, self.bucket, self.options, disposition) name = self.dl.download(chunks, resume) self._size = self.dl.size diff --git a/module/network/HTTPDownload.py b/module/network/HTTPDownload.py index c6d2e1547..5a4436529 100644 --- a/module/network/HTTPDownload.py +++ b/module/network/HTTPDownload.py @@ -37,7 +37,7 @@ class HTTPDownload(): """ loads an url, http + ftp supported """ def __init__(self, url, filename, get={}, post={}, referer=None, cj=None, bucket=None, - options={}, progressNotify=None, disposition=False): + options={}, disposition=False): self.url = url self.filename = filename #complete file destination, not only name self.get = get @@ -73,8 +73,6 @@ class HTTPDownload(): self.speeds = [] self.lastSpeeds = [0, 0] - self.progressNotify = progressNotify - @property def speed(self): last = [sum(x) for x in self.lastSpeeds if x] @@ -286,7 +284,6 @@ class HTTPDownload(): self.speeds = [float(a) / (t - lastTimeCheck) for a in diff] self.lastArrived = [c.arrived for c in self.chunks] lastTimeCheck = t - self.updateProgress() if self.abort: raise Abort() @@ -299,10 +296,6 @@ class HTTPDownload(): self._copyChunks() - def updateProgress(self): - if self.progressNotify: - self.progressNotify(self.percent) - def findChunk(self, handle): """ linear search to find a chunk (should be ok since chunk size is usually low) """ for chunk in self.chunks: diff --git a/module/plugins/Hoster.py b/module/plugins/Hoster.py index ad4f8f16b..1c53807b7 100644 --- a/module/plugins/Hoster.py +++ b/module/plugins/Hoster.py @@ -284,7 +284,7 @@ class Hoster(Base): try: newname = self.req.httpDownload(url, filename, get=get, post=post, ref=ref, cookies=cookies, chunks=self.getChunkCount(), resume=self.resumeDownload, - progressNotify=self.pyfile.setProgress, disposition=disposition) + disposition=disposition) finally: self.pyfile.size = self.req.size @@ -365,7 +365,7 @@ class Hoster(Base): pack = self.pyfile.package() - for pyfile in self.core.files.cache.values(): + for pyfile in self.core.files.cachedFiles(): if pyfile != self.pyfile and pyfile.name == self.pyfile.name and pyfile.package().folder == pack.folder: if pyfile.status in (0, 12): #finished or downloading raise SkipDownload(pyfile.pluginname) diff --git a/module/threads/AddonThread.py b/module/threads/AddonThread.py index b6a552e0e..afb56f66b 100644 --- a/module/threads/AddonThread.py +++ b/module/threads/AddonThread.py @@ -52,7 +52,7 @@ class AddonThread(BaseThread): except Exception, e: if hasattr(self.f, "im_self"): addon = self.f.im_self - addon.logError(_("An Error occured"), e) + addon.logError(_("An Error occurred"), e) if self.m.core.debug: print_exc() self.writeDebugReport(addon.__name__, plugin=addon) diff --git a/module/threads/BaseThread.py b/module/threads/BaseThread.py index 7a0ee5ee4..3e27eec96 100644 --- a/module/threads/BaseThread.py +++ b/module/threads/BaseThread.py @@ -24,6 +24,13 @@ class BaseThread(Thread): self.core = manager.core self.log = manager.core.log + def getProgress(self): + """ retrieves progress information about the current running task + + :return: :class:`ProgressInfo` + """ + + # Debug Stuff def writeDebugReport(self, name, pyfile=None, plugin=None): """ writes a debug report to disk """ @@ -129,8 +136,3 @@ class BaseThread(Thread): def getSystemDump(self): return "" - - def clean(self, pyfile): - """ set thread inactive and release pyfile """ - self.active = False - pyfile.release() diff --git a/module/threads/DownloadThread.py b/module/threads/DownloadThread.py index 0269b0660..cf59c5639 100644 --- a/module/threads/DownloadThread.py +++ b/module/threads/DownloadThread.py @@ -38,7 +38,7 @@ class DownloadThread(BaseThread): BaseThread.__init__(self, manager) self.queue = Queue() # job queue - self.active = False + self.active = None self.start() @@ -52,7 +52,7 @@ class DownloadThread(BaseThread): pyfile = self.active if self.active == "quit": - self.active = False + self.active = None self.m.threads.remove(self) return True @@ -212,11 +212,19 @@ class DownloadThread(BaseThread): pyfile.finishIfDone() self.core.files.save() + def getProgress(self): + if self.active: + return self.active.getProgressInfo() + def put(self, job): """assign a job to the thread""" self.queue.put(job) + def clean(self, pyfile): + """ set thread inactive and release pyfile """ + self.active = False + pyfile.release() def stop(self): """stops the thread""" diff --git a/module/threads/ThreadManager.py b/module/threads/ThreadManager.py index e3407aac3..a0ece3463 100644 --- a/module/threads/ThreadManager.py +++ b/module/threads/ThreadManager.py @@ -26,7 +26,7 @@ from random import choice import pycurl -from module.datatypes import PyFile +from module.datatypes.PyFile import PyFile from module.network.RequestFactory import getURL from module.utils import lock, uniqify from module.utils.fs import free_space @@ -118,8 +118,11 @@ class ThreadManager: def setInfoResults(self, rid, result): self.infoResults[rid].update(result) + def getActiveDownloads(self): + return [x.active for x in self.threads if x.active and isinstance(x.active, PyFile)] + def getActiveFiles(self): - active = [x.active for x in self.threads if x.active and isinstance(x.active, PyFile)] + active = self.getActiveDownloads() for t in self.localThreads: active.extend(t.getActiveFiles()) @@ -130,6 +133,8 @@ class ThreadManager: """get a id list of all pyfiles processed""" return [x.id for x in self.getActiveFiles()] + def allProgressInfo(self): + pass #TODO def work(self): """run all task which have to be done (this is for repetetive call by core)""" @@ -138,16 +143,15 @@ class ThreadManager: except Exception, e: self.log.error(_("Reconnect Failed: %s") % str(e) ) self.reconnecting.clear() - if self.core.debug: - print_exc() + self.core.print_exc() + self.checkThreadCount() try: self.assignJob() except Exception, e: self.log.warning("Assign job error", e) - if self.core.debug: - print_exc() + self.core.print_exc() sleep(0.5) self.assignJob() diff --git a/module/web/static/js/views/modal/modalView.js b/module/web/static/js/views/modal/modalView.js index 05cb39c33..1de32668d 100644 --- a/module/web/static/js/views/modal/modalView.js +++ b/module/web/static/js/views/modal/modalView.js @@ -27,7 +27,7 @@ define(['jquery', 'backbone', 'underscore', 'text!tpl/default/modal.html', 'omni hideClass: 'hide', animations: { hide: function(subjects, internalCallback) { - subjects.overlay.fadeOut(400, function() { + subjects.overlay.transition({opacity: 'hide', delay: 100}, 300, function() { internalCallback(subjects); }); }, diff --git a/module/web/static/js/views/packageTreeView.js b/module/web/static/js/views/packageTreeView.js index 3329c9582..f746bf0a3 100644 --- a/module/web/static/js/views/packageTreeView.js +++ b/module/web/static/js/views/packageTreeView.js @@ -64,7 +64,7 @@ define(['jquery', 'backbone', 'underscore', 'models/TreeCollection', 'views/pack type: 'POST', data: { name: JSON.stringify($('#name').val()), - links: JSON.stringify(['some link']) + links: JSON.stringify(['http://download.pyload.org/random.bin']) }, success: function() { self.tree.fetch({success: function() { |