summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-12-29 21:07:28 +0100
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-12-29 21:07:28 +0100
commit8318540e162cccbb049bebebc5aca03384a1e4e9 (patch)
tree5b4dc38520a82b5c8044a026ab996be1d71a782e
parentadded auth to request class (diff)
downloadpyload-8318540e162cccbb049bebebc5aca03384a1e4e9.tar.xz
added progress type enum, new DebugCrypter + Hoster, little improvements for crypter api
-rw-r--r--pyload/PluginManager.py9
-rw-r--r--pyload/datatypes/PyFile.py4
-rw-r--r--pyload/plugins/Account.py2
-rw-r--r--pyload/plugins/Addon.py2
-rw-r--r--pyload/plugins/Base.py8
-rw-r--r--pyload/plugins/Crypter.py30
-rw-r--r--pyload/plugins/Hoster.py2
-rw-r--r--pyload/plugins/crypter/DebugCrypter.py29
-rw-r--r--pyload/plugins/hoster/DebugHoster.py30
-rw-r--r--pyload/remote/apitypes.py15
-rw-r--r--pyload/remote/apitypes_debug.py3
-rw-r--r--pyload/remote/pyload.thrift16
-rw-r--r--pyload/threads/AddonThread.py4
-rw-r--r--pyload/threads/DecrypterThread.py2
-rw-r--r--pyload/threads/DownloadThread.py1
-rw-r--r--pyload/utils/__init__.py2
-rw-r--r--pyload/web/app/scripts/models/Progress.js2
-rw-r--r--pyload/web/app/scripts/utils/apitypes.js1
18 files changed, 137 insertions, 25 deletions
diff --git a/pyload/PluginManager.py b/pyload/PluginManager.py
index ea0515999..f3d2b999d 100644
--- a/pyload/PluginManager.py
+++ b/pyload/PluginManager.py
@@ -132,6 +132,10 @@ class PluginManager:
return res["hoster"], res["crypter"]
+ def getPlugin(self, plugin, name):
+ """ Retrieves the plugin tuple for a single plugin or none """
+ return self.loader.getPlugin(plugin, name)
+
def getPlugins(self, plugin):
""" Get all plugins of a certain type in a dict """
plugins = {}
@@ -179,7 +183,10 @@ class PluginManager:
def loadClass(self, plugin, name):
"""Returns the class of a plugin with the same name"""
module = self.loadModule(plugin, name)
- if module: return getattr(module, name)
+ try:
+ if module: return getattr(module, name)
+ except AttributeError:
+ self.log.error(_("Plugin does not define class '%s'") % name)
def find_module(self, fullname, path=None):
#redirecting imports if necessary
diff --git a/pyload/datatypes/PyFile.py b/pyload/datatypes/PyFile.py
index e27fdd537..58d9f6a6f 100644
--- a/pyload/datatypes/PyFile.py
+++ b/pyload/datatypes/PyFile.py
@@ -19,7 +19,7 @@
from time import sleep, time
from ReadWriteLock import ReadWriteLock
-from pyload.Api import ProgressInfo, DownloadProgress, FileInfo, DownloadInfo, DownloadStatus
+from pyload.Api import ProgressInfo, ProgressType, DownloadProgress, FileInfo, DownloadInfo, DownloadStatus
from pyload.utils import lock, read_lock
from pyload.utils.filetypes import guess_type
@@ -276,5 +276,5 @@ class PyFile(object):
def getProgressInfo(self):
return ProgressInfo(self.pluginname, self.name, self.getStatusName(), self.getETA(),
- self.getBytesArrived(), self.getSize(),
+ self.getBytesArrived(), self.getSize(), self.owner, ProgressType.Download,
DownloadProgress(self.fid, self.packageid, self.getSpeed(), self.status))
diff --git a/pyload/plugins/Account.py b/pyload/plugins/Account.py
index 4e6f174d2..cbf545611 100644
--- a/pyload/plugins/Account.py
+++ b/pyload/plugins/Account.py
@@ -45,6 +45,8 @@ class Account(Base):
return cls(m, info.loginname, info.owner,
True if info.activated else False, True if info.shared else False, password, options)
+ __type__ = "account"
+
def __init__(self, manager, loginname, owner, activated, shared, password, options):
Base.__init__(self, manager.core, owner)
diff --git a/pyload/plugins/Addon.py b/pyload/plugins/Addon.py
index da5bbc1d7..7e331d324 100644
--- a/pyload/plugins/Addon.py
+++ b/pyload/plugins/Addon.py
@@ -100,6 +100,8 @@ class Addon(Base):
#: periodic call interval in seconds
interval = 0
+ __type__ = "addon"
+
def __init__(self, core, manager, user=None):
Base.__init__(self, core, user)
diff --git a/pyload/plugins/Base.py b/pyload/plugins/Base.py
index 9dcb99453..97fb027d8 100644
--- a/pyload/plugins/Base.py
+++ b/pyload/plugins/Base.py
@@ -40,7 +40,10 @@ class Base(object):
"""
The Base plugin class with all shared methods and every possible attribute for plugin definition.
"""
+ #: Version as string or number
__version__ = "0.1"
+ # Type of the plugin, will be inherited and should not be set!
+ __type__ = ""
#: Regexp pattern which will be matched for download/crypter plugins
__pattern__ = r""
#: Internal addon plugin which is always loaded
@@ -150,6 +153,11 @@ class Base(object):
""" Name of the plugin class """
return self.__name__
+ @property
+ def pattern(self):
+ """ Gives the compiled pattern of the plugin """
+ return self.core.pluginManager.getPlugin(self.__type__, self.__name__).re
+
def setConfig(self, option, value):
""" Set config value for current plugin """
self.core.config.set(self.__name__, option, value)
diff --git a/pyload/plugins/Crypter.py b/pyload/plugins/Crypter.py
index a81fffafa..b6bdb1edd 100644
--- a/pyload/plugins/Crypter.py
+++ b/pyload/plugins/Crypter.py
@@ -6,11 +6,19 @@ from pyload.utils.fs import exists, remove, fs_encode
from Base import Base, Retry
+# represent strings as LinkStatus
+def to_link_list(links, status=DS.Queued):
+ return [LinkStatus(link, link, -1, status) if isinstance(link, basestring) else link
+ for link in links]
+
+
class Package:
""" Container that indicates that a new package should be created """
def __init__(self, name=None, links=None):
self.name = name
+
+ # list of link status
self.links = []
if links:
@@ -24,12 +32,7 @@ class Package:
:param links: One or list of urls or :class:`LinkStatus`
"""
- links = to_list(links)
- for link in links:
- if not isinstance(link, LinkStatus):
- link = LinkStatus(link, link, -1, DS.Queued)
-
- self.links.append(link)
+ self.links.extend(to_link_list(to_list(links)))
def addPackage(self, pack):
self.packs.append(pack)
@@ -128,13 +131,16 @@ class Crypter(Base):
for url_or_pack in result:
if isinstance(url_or_pack, Package): #package
ret.extend(url_or_pack.getAllURLs())
- else: # single url
- ret.append(url_or_pack)
- # eliminate duplicates
+ elif isinstance(url_or_pack, LinkStatus): #link
+ ret.append(url_or_pack.url)
+ else:
+ core.log.debug("Invalid decrypter result: " + url_or_pack)
+
return uniqify(ret)
+
+ __type__ = "crypter"
# TODO: pass user to crypter
- # TODO: crypter could not only know url, but also the name and size
def __init__(self, core, password=None):
Base.__init__(self, core)
@@ -196,7 +202,7 @@ class Crypter(Base):
"""Internal method to select decrypting method
:param urls: List of urls/content
- :return:
+ :return: (links, packages)
"""
cls = self.__class__
@@ -235,7 +241,7 @@ class Crypter(Base):
self.logWarning(_("Could not remove file '%s'") % f)
self.core.print_exc()
- return result
+ return to_link_list(result)
def getLocalContent(self, urls):
"""Load files from disk and separate to file content and url list
diff --git a/pyload/plugins/Hoster.py b/pyload/plugins/Hoster.py
index b59d11a9c..0ad07878a 100644
--- a/pyload/plugins/Hoster.py
+++ b/pyload/plugins/Hoster.py
@@ -47,6 +47,8 @@ class Hoster(Base):
"""
pass
+ __type__ = "hoster"
+
def __init__(self, pyfile):
# TODO: pyfile.owner, but it's not correct yet
Base.__init__(self, pyfile.m.core)
diff --git a/pyload/plugins/crypter/DebugCrypter.py b/pyload/plugins/crypter/DebugCrypter.py
new file mode 100644
index 000000000..a10d7c8e7
--- /dev/null
+++ b/pyload/plugins/crypter/DebugCrypter.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+from random import randint
+from time import sleep
+
+from pyload.plugins.Crypter import Crypter
+
+class DebugCrypter(Crypter):
+ """ Generates link used by debug hoster to test the decrypt mechanism """
+
+ __version__ = 0.1
+ __pattern__ = r"^debug_crypter=(\d+)$"
+
+
+ def decryptURL(self, url):
+
+ m = self.pattern.search(url)
+ n = int(m.group(1))
+
+ sleep(randint(3, n if n > 2 else 3))
+
+ return ["debug_hoster=%d" % i for i in range(n)]
+
+
+
+
+
+
+
diff --git a/pyload/plugins/hoster/DebugHoster.py b/pyload/plugins/hoster/DebugHoster.py
new file mode 100644
index 000000000..d168ad1c2
--- /dev/null
+++ b/pyload/plugins/hoster/DebugHoster.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+
+from time import sleep
+from random import randint
+
+from pyload.Api import LinkStatus, DownloadStatus as DS
+from pyload.plugins.Hoster import Hoster
+
+
+class DebugHoster(Hoster):
+ """ Generates link used by debug hoster to test the decrypt mechanism """
+
+ __version__ = 0.1
+ __pattern__ = r"^debug_hoster=\d*$"
+
+ @classmethod
+ def getInfo(cls, urls):
+ for url in urls:
+ yield LinkStatus(url, url + " - checked", randint(1024, 2048), DS.Online)
+ sleep(1)
+
+ def process(self, pyfile):
+ pass
+
+
+
+
+
+
+
diff --git a/pyload/remote/apitypes.py b/pyload/remote/apitypes.py
index 555deca9f..ab68116c3 100644
--- a/pyload/remote/apitypes.py
+++ b/pyload/remote/apitypes.py
@@ -95,6 +95,15 @@ class Permission:
Interaction = 32
Plugins = 64
+class ProgressType:
+ All = 0
+ Other = 1
+ Download = 2
+ Decrypting = 4
+ LinkCheck = 8
+ Addon = 16
+ FileOperation = 32
+
class Role:
Admin = 0
User = 1
@@ -300,15 +309,17 @@ class PackageStats(BaseObject):
self.sizedone = sizedone
class ProgressInfo(BaseObject):
- __slots__ = ['plugin', 'name', 'statusmsg', 'eta', 'done', 'total', 'download']
+ __slots__ = ['plugin', 'name', 'statusmsg', 'eta', 'done', 'total', 'owner', 'type', 'download']
- def __init__(self, plugin=None, name=None, statusmsg=None, eta=None, done=None, total=None, download=None):
+ def __init__(self, plugin=None, name=None, statusmsg=None, eta=None, done=None, total=None, owner=None, type=None, download=None):
self.plugin = plugin
self.name = name
self.statusmsg = statusmsg
self.eta = eta
self.done = done
self.total = total
+ self.owner = owner
+ self.type = type
self.download = download
class ServerStatus(BaseObject):
diff --git a/pyload/remote/apitypes_debug.py b/pyload/remote/apitypes_debug.py
index 74b86f3a8..d5e5f36a0 100644
--- a/pyload/remote/apitypes_debug.py
+++ b/pyload/remote/apitypes_debug.py
@@ -14,6 +14,7 @@ enums = [
"MediaType",
"PackageStatus",
"Permission",
+ "ProgressType",
"Role",
]
@@ -37,7 +38,7 @@ classes = {
'PackageDoesNotExist' : [int],
'PackageInfo' : [int, basestring, basestring, int, int, basestring, basestring, basestring, int, (list, basestring), int, bool, int, PackageStats, (list, int), (list, int)],
'PackageStats' : [int, int, int, int],
- 'ProgressInfo' : [basestring, basestring, basestring, int, int, int, (None, DownloadProgress)],
+ 'ProgressInfo' : [basestring, basestring, basestring, int, int, int, int, int, (None, DownloadProgress)],
'ServerStatus' : [int, int, int, int, int, bool, bool, bool, bool],
'ServiceDoesNotExist' : [basestring, basestring],
'ServiceException' : [basestring],
diff --git a/pyload/remote/pyload.thrift b/pyload/remote/pyload.thrift
index 9b8415d0f..a9431ea7c 100644
--- a/pyload/remote/pyload.thrift
+++ b/pyload/remote/pyload.thrift
@@ -116,6 +116,16 @@ enum Role {
User = 1
}
+enum ProgressType {
+ All = 0,
+ Other = 1,
+ Download = 2,
+ Decrypting = 4,
+ LinkCheck = 8,
+ Addon = 16,
+ FileOperation = 32,
+}
+
struct Input {
1: InputType type,
2: optional JSONString default_value,
@@ -135,8 +145,10 @@ struct ProgressInfo {
3: string statusmsg,
4: i32 eta, // in seconds
5: ByteCount done,
- 6: ByteCount total, // arbitary number, size in case of files
- 7: optional DownloadProgress download
+ 6: ByteCount total, // arbitary number, size in case of files,
+ 7: UserID owner,
+ 8: ProgressType type,
+ 9: optional DownloadProgress download //only given when progress type download
}
// download info for specific file
diff --git a/pyload/threads/AddonThread.py b/pyload/threads/AddonThread.py
index fd613bdec..d8d84cbfa 100644
--- a/pyload/threads/AddonThread.py
+++ b/pyload/threads/AddonThread.py
@@ -4,7 +4,7 @@
from copy import copy
from traceback import print_exc
-from pyload.Api import ProgressInfo
+from pyload.Api import ProgressInfo, ProgressType
from BaseThread import BaseThread
class AddonThread(BaseThread):
@@ -38,7 +38,7 @@ class AddonThread(BaseThread):
if self.active:
active = self.active[0]
return ProgressInfo(active.pluginname, active.name, active.getStatusName(), 0,
- self.progress, 100)
+ self.progress, 100, self.owner, ProgressType.Addon)
def addActive(self, pyfile):
""" Adds a pyfile to active list and thus will be displayed on overview"""
diff --git a/pyload/threads/DecrypterThread.py b/pyload/threads/DecrypterThread.py
index 10d47fcc2..a0bebdfbf 100644
--- a/pyload/threads/DecrypterThread.py
+++ b/pyload/threads/DecrypterThread.py
@@ -35,7 +35,7 @@ class DecrypterThread(BaseThread):
for p in packages:
self.m.core.api.addPackage(p.name, p.getURLs(), pack.password)
- def decrypt(self, plugin_map, password=None, err=None):
+ def decrypt(self, plugin_map, password=None, err=False):
result = []
# TODO QUEUE_DECRYPT
diff --git a/pyload/threads/DownloadThread.py b/pyload/threads/DownloadThread.py
index 4c4ee597c..d1672531b 100644
--- a/pyload/threads/DownloadThread.py
+++ b/pyload/threads/DownloadThread.py
@@ -216,7 +216,6 @@ class DownloadThread(BaseThread):
if self.active:
return self.active.getProgressInfo()
-
def put(self, job):
"""assign a job to the thread"""
self.queue.put(job)
diff --git a/pyload/utils/__init__.py b/pyload/utils/__init__.py
index 09fb76229..1badfbdd2 100644
--- a/pyload/utils/__init__.py
+++ b/pyload/utils/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-""" Store all usefull functions here """
+""" Store all useful functions here """
import os
import time
diff --git a/pyload/web/app/scripts/models/Progress.js b/pyload/web/app/scripts/models/Progress.js
index b0bbb684d..c4480e018 100644
--- a/pyload/web/app/scripts/models/Progress.js
+++ b/pyload/web/app/scripts/models/Progress.js
@@ -14,6 +14,8 @@ define(['jquery', 'backbone', 'underscore', 'utils/apitypes'], function($, Backb
eta: -1,
done: -1,
total: -1,
+ owner: -1,
+ type: 0,
download: null
},
diff --git a/pyload/web/app/scripts/utils/apitypes.js b/pyload/web/app/scripts/utils/apitypes.js
index 12ad6b78d..fc92425de 100644
--- a/pyload/web/app/scripts/utils/apitypes.js
+++ b/pyload/web/app/scripts/utils/apitypes.js
@@ -11,6 +11,7 @@ define([], function() {
MediaType: {'All': 0, 'Audio': 2, 'Image': 4, 'Executable': 64, 'Other': 1, 'Video': 8, 'Document': 16, 'Archive': 32},
PackageStatus: {'Paused': 1, 'Remote': 3, 'Folder': 2, 'Ok': 0},
Permission: {'All': 0, 'Interaction': 32, 'Modify': 4, 'Add': 1, 'Accounts': 16, 'Plugins': 64, 'Download': 8, 'Delete': 2},
+ ProgressType: {'LinkCheck': 8, 'All': 0, 'FileOperation': 32, 'Decrypting': 4, 'Other': 1, 'Download': 2, 'Addon': 16},
Role: {'Admin': 0, 'User': 1},
};
}); \ No newline at end of file