diff options
Diffstat (limited to 'pyload/manager')
-rw-r--r-- | pyload/manager/Account.py | 10 | ||||
-rw-r--r-- | pyload/manager/Addon.py | 17 | ||||
-rw-r--r-- | pyload/manager/Captcha.py | 20 | ||||
-rw-r--r-- | pyload/manager/Event.py | 19 | ||||
-rw-r--r-- | pyload/manager/Plugin.py | 15 | ||||
-rw-r--r-- | pyload/manager/Remote.py | 8 | ||||
-rw-r--r-- | pyload/manager/Thread.py | 21 | ||||
-rw-r--r-- | pyload/manager/event/Scheduler.py | 14 | ||||
-rw-r--r-- | pyload/manager/thread/Addon.py | 5 | ||||
-rw-r--r-- | pyload/manager/thread/Decrypter.py | 2 | ||||
-rw-r--r-- | pyload/manager/thread/Download.py | 6 | ||||
-rw-r--r-- | pyload/manager/thread/Info.py | 6 | ||||
-rw-r--r-- | pyload/manager/thread/Plugin.py | 3 |
13 files changed, 141 insertions, 5 deletions
diff --git a/pyload/manager/Account.py b/pyload/manager/Account.py index 12fc970c2..9b7cb590a 100644 --- a/pyload/manager/Account.py +++ b/pyload/manager/Account.py @@ -16,7 +16,6 @@ ACC_VERSION = 1 class AccountManager(object): """manages all accounts""" - #---------------------------------------------------------------------- def __init__(self, core): """Constructor""" @@ -64,6 +63,7 @@ class AccountManager(object): #---------------------------------------------------------------------- + def loadAccounts(self): """loads all accounts available""" @@ -111,6 +111,7 @@ class AccountManager(object): #---------------------------------------------------------------------- + def saveAccounts(self): """save all account information""" @@ -135,6 +136,7 @@ class AccountManager(object): #---------------------------------------------------------------------- + def initAccountPlugins(self): """init names""" for name in self.core.pluginManager.getAccountPlugins(): @@ -142,6 +144,8 @@ class AccountManager(object): @lock + + def updateAccount(self, plugin , user, password=None, options={}): """add or update account""" if plugin in self.accounts: @@ -154,6 +158,8 @@ class AccountManager(object): @lock + + def removeAccount(self, plugin, user): """remove account""" @@ -165,6 +171,8 @@ class AccountManager(object): @lock + + def getAccountInfos(self, force=True, refresh=False): data = {} diff --git a/pyload/manager/Addon.py b/pyload/manager/Addon.py index 9ce3a4f8f..61585e1cb 100644 --- a/pyload/manager/Addon.py +++ b/pyload/manager/Addon.py @@ -67,6 +67,7 @@ class AddonManager(object): def try_catch(func): + def new(*args): try: return func(*args) @@ -178,6 +179,8 @@ class AddonManager(object): @try_catch + + def coreReady(self): for plugin in self.plugins: if plugin.isActivated(): @@ -187,6 +190,8 @@ class AddonManager(object): @try_catch + + def coreExiting(self): for plugin in self.plugins: if plugin.isActivated(): @@ -196,6 +201,8 @@ class AddonManager(object): @lock + + def downloadPreparing(self, pyfile): for plugin in self.plugins: if plugin.isActivated(): @@ -205,6 +212,8 @@ class AddonManager(object): @lock + + def downloadFinished(self, pyfile): for plugin in self.plugins: if plugin.isActivated(): @@ -215,6 +224,8 @@ class AddonManager(object): @lock @try_catch + + def downloadFailed(self, pyfile): for plugin in self.plugins: if plugin.isActivated(): @@ -224,6 +235,8 @@ class AddonManager(object): @lock + + def packageFinished(self, package): for plugin in self.plugins: if plugin.isActivated(): @@ -233,6 +246,8 @@ class AddonManager(object): @lock + + def beforeReconnecting(self, ip): for plugin in self.plugins: plugin.beforeReconnecting(ip) @@ -241,6 +256,8 @@ class AddonManager(object): @lock + + def afterReconnecting(self, ip): for plugin in self.plugins: if plugin.isActivated(): diff --git a/pyload/manager/Captcha.py b/pyload/manager/Captcha.py index e54eacf30..0814cf78a 100644 --- a/pyload/manager/Captcha.py +++ b/pyload/manager/Captcha.py @@ -9,23 +9,27 @@ from pyload.utils import encode class CaptchaManager(object): + def __init__(self, core): self.lock = Lock() self.core = core self.tasks = [] # task store, for outgoing tasks only self.ids = 0 # only for internal purpose + def newTask(self, img, format, file, result_type): task = CaptchaTask(self.ids, img, format, file, result_type) self.ids += 1 return task + def removeTask(self, task): self.lock.acquire() if task in self.tasks: self.tasks.remove(task) self.lock.release() + def getTask(self): self.lock.acquire() for task in self.tasks: @@ -35,6 +39,7 @@ class CaptchaManager(object): self.lock.release() return None + def getTaskByID(self, tid): self.lock.acquire() for task in self.tasks: @@ -44,6 +49,7 @@ class CaptchaManager(object): self.lock.release() return None + def handleCaptcha(self, task, timeout=50): cli = self.core.isClientConnected() @@ -65,6 +71,7 @@ class CaptchaManager(object): class CaptchaTask(object): + def __init__(self, id, img, format, file, result_type='textual'): self.id = str(id) self.captchaImg = img @@ -78,9 +85,11 @@ class CaptchaTask(object): self.status = "init" self.data = {} # handler can store data here + def getCaptcha(self): return self.captchaImg, self.captchaFormat, self.captchaResultType + def setResult(self, text): if self.isTextual(): self.result = text @@ -91,48 +100,59 @@ class CaptchaTask(object): except Exception: self.result = None + def getResult(self): return encode(self.result) + def getStatus(self): return self.status + def setWaiting(self, sec): """ let the captcha wait secs for the solution """ self.waitUntil = max(time() + sec, self.waitUntil) self.status = "waiting" + def isWaiting(self): if self.result or self.error or self.timedOut(): return False else: return True + def isTextual(self): """ returns if text is written on the captcha """ return self.captchaResultType == 'textual' + def isPositional(self): """ returns if user have to click a specific region on the captcha """ return self.captchaResultType == 'positional' + def setWatingForUser(self, exclusive): if exclusive: self.status = "user" else: self.status = "shared-user" + def timedOut(self): return time() > self.waitUntil + def invalid(self): """ indicates the captcha was not correct """ for x in self.handler: x.captchaInvalid(self) + def correct(self): for x in self.handler: x.captchaCorrect(self) + def __str__(self): return "<CaptchaTask '%s'>" % self.id diff --git a/pyload/manager/Event.py b/pyload/manager/Event.py index 20897290e..90aaaca30 100644 --- a/pyload/manager/Event.py +++ b/pyload/manager/Event.py @@ -5,18 +5,22 @@ from time import time from pyload.utils import uniqify class PullManager(object): + def __init__(self, core): self.core = core self.clients = [] + def newClient(self, uuid): self.clients.append(Client(uuid)) + def clean(self): for n, client in enumerate(self.clients): if client.lastActive + 30 < time(): del self.clients[n] + def getEvents(self, uuid): events = [] validUuid = False @@ -32,28 +36,34 @@ class PullManager(object): events = [ReloadAllEvent("queue").toList(), ReloadAllEvent("collector").toList()] return uniqify(events) + def addEvent(self, event): for client in self.clients: client.addEvent(event) class Client(object): + def __init__(self, uuid): self.uuid = uuid self.lastActive = time() self.events = [] + def newEvents(self): return len(self.events) > 0 + def popEvent(self): if not len(self.events): return None return self.events.pop(0) + def addEvent(self, event): self.events.append(event) class UpdateEvent(object): + def __init__(self, itype, iid, destination): assert itype == "pack" or itype == "file" assert destination == "queue" or destination == "collector" @@ -61,10 +71,12 @@ class UpdateEvent(object): self.id = iid self.destination = destination + def toList(self): return ["update", self.destination, self.type, self.id] class RemoveEvent(object): + def __init__(self, itype, iid, destination): assert itype == "pack" or itype == "file" assert destination == "queue" or destination == "collector" @@ -72,10 +84,12 @@ class RemoveEvent(object): self.id = iid self.destination = destination + def toList(self): return ["remove", self.destination, self.type, self.id] class InsertEvent(object): + def __init__(self, itype, iid, after, destination): assert itype == "pack" or itype == "file" assert destination == "queue" or destination == "collector" @@ -84,21 +98,26 @@ class InsertEvent(object): self.after = after self.destination = destination + def toList(self): return ["insert", self.destination, self.type, self.id, self.after] class ReloadAllEvent(object): + def __init__(self, destination): assert destination == "queue" or destination == "collector" self.destination = destination + def toList(self): return ["reload", self.destination] class AccountUpdateEvent(object): + def toList(self): return ["account"] class ConfigUpdateEvent(object): + def toList(self): return ["config"] diff --git a/pyload/manager/Plugin.py b/pyload/manager/Plugin.py index 918f6de8a..10abbc2ea 100644 --- a/pyload/manager/Plugin.py +++ b/pyload/manager/Plugin.py @@ -25,6 +25,7 @@ class PluginManager(object): CONFIG = re.compile(r'__config\s*=\s*\[([^\]]+)', re.M) DESC = re.compile(r'__description\s*=\s*("|"""|\')([^"\']+)') + def __init__(self, core): self.core = core @@ -34,6 +35,7 @@ class PluginManager(object): # register for import addon sys.meta_path.append(self) + def loadTypes(self): rootdir = join(pypath, "pyload", "plugin") userdir = "userplugins" @@ -46,6 +48,7 @@ class PluginManager(object): self.TYPES = list(set(self.TYPES) | types) + def createIndex(self): """create information for all plugins available""" @@ -64,6 +67,7 @@ class PluginManager(object): self.core.log.debug("Created index of plugins") + def parse(self, folder, rootplugins={}): """ returns dict with information @@ -179,6 +183,7 @@ class PluginManager(object): return plugins + def parseUrls(self, urls): """parse plugins for given list of urls""" @@ -217,6 +222,7 @@ class PluginManager(object): print res return res + def findPlugin(self, type, name): if type not in self.plugins: return None @@ -229,6 +235,7 @@ class PluginManager(object): else: return self.plugins[type][name] + def getPlugin(self, type, name, original=False): """return plugin module from hoster|decrypter|container""" plugin = self.findPlugin(type, name) @@ -241,6 +248,7 @@ class PluginManager(object): else: return self.loadModule(type, name) + def getPluginName(self, type, name): """ used to obtain new name if other plugin was injected""" plugin = self.findPlugin(type, name) @@ -253,6 +261,7 @@ class PluginManager(object): return name + def loadModule(self, type, name): """ Returns loaded module for plugin @@ -282,6 +291,7 @@ class PluginManager(object): % {'name': name, 'type': type, 'version': plugins[name]['version']}) return module + def loadClass(self, type, name): """Returns the class of a plugin with the same name""" module = self.loadModule(type, name) @@ -290,10 +300,12 @@ class PluginManager(object): else: return None + def getAccountPlugins(self): """return list of account plugin names""" return self.accountPlugins.keys() + def find_module(self, fullname, path=None): # redirecting imports if necesarry if fullname.startswith(self.ROOT) or fullname.startswith(self.USERROOT): # seperate pyload plugins @@ -312,6 +324,7 @@ class PluginManager(object): if user and not self.plugins[type][name]['user']: return self + def load_module(self, name, replace=True): if name not in sys.modules: # could be already in modules if replace: @@ -333,6 +346,7 @@ class PluginManager(object): return sys.modules[name] + def reloadPlugins(self, type_plugins): """ reload and reindex plugins """ if not type_plugins: @@ -378,6 +392,7 @@ class PluginManager(object): return reloaded #: return a list of the plugins successfully reloaded + def reloadPlugin(self, type_plugin): """ reload and reindex ONE plugin """ return True if self.reloadPlugins(type_plugin) else False diff --git a/pyload/manager/Remote.py b/pyload/manager/Remote.py index 910881164..4fdb36fc2 100644 --- a/pyload/manager/Remote.py +++ b/pyload/manager/Remote.py @@ -5,6 +5,7 @@ from threading import Thread from traceback import print_exc class BackendBase(Thread): + def __init__(self, manager): Thread.__init__(self) self.m = manager @@ -12,6 +13,7 @@ class BackendBase(Thread): self.enabled = True self.running = False + def run(self): self.running = True try: @@ -23,18 +25,23 @@ class BackendBase(Thread): finally: self.running = False + def setup(self, host, port): pass + def checkDeps(self): return True + def serve(self): pass + def shutdown(self): pass + def stop(self): self.enabled = False# set flag and call shutdowm message, so thread can react self.shutdown() @@ -43,6 +50,7 @@ class BackendBase(Thread): class RemoteManager(object): available = [] + def __init__(self, core): self.core = core self.backends = [] diff --git a/pyload/manager/Thread.py b/pyload/manager/Thread.py index 753a8c251..dd8e6bcce 100644 --- a/pyload/manager/Thread.py +++ b/pyload/manager/Thread.py @@ -54,12 +54,14 @@ class ThreadManager(object): for i in range(0, self.core.config.get("download", "max_downloads")): self.createThread() + def createThread(self): """create a download thread""" thread = DownloadThread(self) self.threads.append(thread) + def createInfoThread(self, data, pid): """ start a thread whichs fetches online status and other infos @@ -70,6 +72,8 @@ class ThreadManager(object): InfoThread(self, data, pid) @lock + + def createResultThread(self, data, add=False): """ creates a thread to fetch online status, returns result id """ self.timestamp = time() + 5 * 60 @@ -82,6 +86,8 @@ class ThreadManager(object): return rid @lock + + def getInfoResult(self, rid): """returns result and clears it""" self.timestamp = time() + 5 * 60 @@ -94,9 +100,12 @@ class ThreadManager(object): return {} @lock + + def setInfoResults(self, rid, result): self.infoResults[rid].update(result) + def getActiveFiles(self): active = [x.active for x in self.threads if x.active and isinstance(x.active, PyFile)] @@ -105,10 +114,12 @@ class ThreadManager(object): return active + def processingIds(self): """get a id list of all pyfiles processed""" return [x.id for x in self.getActiveFiles()] + def work(self): """run all task which have to be done (this is for repetivive call by core)""" try: @@ -136,7 +147,9 @@ class ThreadManager(object): self.infoResults.clear() self.core.log.debug("Cleared Result cache") + #-------------------------------------------------------------------------- + def tryReconnect(self): """checks if reconnect needed""" @@ -189,6 +202,7 @@ class ThreadManager(object): self.reconnecting.clear() + def getIP(self): """retrieve current ip""" services = [("http://automation.whatismyip.com/n09230945.asp", "(\S+)"), @@ -207,7 +221,9 @@ class ThreadManager(object): return ip + #-------------------------------------------------------------------------- + def checkThreadCount(self): """checks if there are need for increasing or reducing thread count""" @@ -220,6 +236,7 @@ class ThreadManager(object): if free: free[0].put("quit") + def cleanPycurl(self): """ make a global curl cleanup (currently ununused) """ if self.processingIds(): @@ -230,7 +247,9 @@ class ThreadManager(object): self.core.log.debug("Cleaned up pycurl") return True + #-------------------------------------------------------------------------- + def assignJob(self): """assing a job to a thread if possible""" @@ -287,10 +306,12 @@ class ThreadManager(object): else: thread = DecrypterThread(self, job) + def getLimit(self, thread): limit = thread.active.plugin.account.getAccountData(thread.active.plugin.user)["options"].get("limitDL", ["0"])[0] return int(limit) + def cleanup(self): """do global cleanup, should be called when finished with pycurl""" pycurl.global_cleanup() diff --git a/pyload/manager/event/Scheduler.py b/pyload/manager/event/Scheduler.py index 2cb537383..d67d9063a 100644 --- a/pyload/manager/event/Scheduler.py +++ b/pyload/manager/event/Scheduler.py @@ -11,13 +11,16 @@ class AlreadyCalled(Exception): class Deferred(object): + def __init__(self): self.call = [] self.result = () + def addCallback(self, f, *cargs, **ckwargs): self.call.append((f, cargs, ckwargs)) + def callback(self, *args, **kwargs): if self.result: raise AlreadyCalled @@ -29,11 +32,13 @@ class Deferred(object): class Scheduler(object): + def __init__(self, core): self.core = core self.queue = PriorityQueue() + def addJob(self, t, call, args=[], kwargs={}, threaded=True): d = Deferred() t += time() @@ -41,6 +46,7 @@ class Scheduler(object): self.queue.put((t, j)) return d + def removeJob(self, d): """ :param d: defered object @@ -58,6 +64,7 @@ class Scheduler(object): return False + def work(self): while True: t, j = self.queue.get() @@ -72,6 +79,7 @@ class Scheduler(object): class Job(object): + def __init__(self, time, call, args=[], kwargs={}, deferred=None, threaded=True): self.time = float(time) self.call = call @@ -80,6 +88,7 @@ class Job(object): self.deferred = deferred self.threaded = threaded + def run(self): ret = self.call(*self.args, **self.kwargs) if self.deferred is None: @@ -87,6 +96,7 @@ class Job(object): else: self.deferred.callback(ret) + def start(self): if self.threaded: t = Thread(target=self.run) @@ -103,17 +113,21 @@ class PriorityQueue(object): self.queue = [] self.lock = Lock() + def __iter__(self): return iter(self.queue) + def __delitem__(self, key): del self.queue[key] + def put(self, element): self.lock.acquire() heappush(self.queue, element) self.lock.release() + def get(self): """ return element or None """ self.lock.acquire() diff --git a/pyload/manager/thread/Addon.py b/pyload/manager/thread/Addon.py index 7feec227e..f3d219989 100644 --- a/pyload/manager/thread/Addon.py +++ b/pyload/manager/thread/Addon.py @@ -20,7 +20,6 @@ from pyload.manager.thread.Plugin import PluginThread class AddonThread(PluginThread): """thread for addons""" - #-------------------------------------------------------------------------- def __init__(self, m, function, args, kwargs): """Constructor""" PluginThread.__init__(self, m) @@ -35,20 +34,24 @@ class AddonThread(PluginThread): self.start() + def getActiveFiles(self): return self.active + def addActive(self, pyfile): """ Adds a pyfile to active list and thus will be displayed on overview""" if pyfile not in self.active: self.active.append(pyfile) + def finishFile(self, pyfile): if pyfile in self.active: self.active.remove(pyfile) pyfile.finishIfDone() + def run(self): try: try: diff --git a/pyload/manager/thread/Decrypter.py b/pyload/manager/thread/Decrypter.py index 12806163c..308e94f10 100644 --- a/pyload/manager/thread/Decrypter.py +++ b/pyload/manager/thread/Decrypter.py @@ -33,9 +33,11 @@ class DecrypterThread(PluginThread): self.start() + def getActiveFiles(self): return [self.active] + def run(self): """run method""" diff --git a/pyload/manager/thread/Download.py b/pyload/manager/thread/Download.py index 37fe844ec..fc76b655e 100644 --- a/pyload/manager/thread/Download.py +++ b/pyload/manager/thread/Download.py @@ -21,8 +21,6 @@ from pyload.plugin.Plugin import Abort, Fail, Reconnect, Retry, SkipDownload class DownloadThread(PluginThread): """thread for downloading files from 'real' hoster plugins""" - #-------------------------------------------------------------------------- - def __init__(self, manager): """Constructor""" PluginThread.__init__(self, manager) @@ -32,7 +30,9 @@ class DownloadThread(PluginThread): self.start() + #-------------------------------------------------------------------------- + def run(self): """run method""" pyfile = None @@ -201,10 +201,12 @@ class DownloadThread(PluginThread): pyfile.finishIfDone() self.m.core.files.save() + def put(self, job): """assing job to thread""" self.queue.put(job) + def stop(self): """stops the thread""" self.put("quit") diff --git a/pyload/manager/thread/Info.py b/pyload/manager/thread/Info.py index edc9489e9..487c3b924 100644 --- a/pyload/manager/thread/Info.py +++ b/pyload/manager/thread/Info.py @@ -36,6 +36,7 @@ class InfoThread(PluginThread): self.start() + def run(self): """run method""" @@ -120,9 +121,11 @@ class InfoThread(PluginThread): self.m.timestamp = time() + 5 * 60 + def updateDB(self, plugin, result): self.m.core.files.updateFileInfo(result, self.pid) + def updateResult(self, plugin, result, force=False): # parse package name and generate result # accumulate results @@ -144,9 +147,11 @@ class InfoThread(PluginThread): self.cache = [] + def updateCache(self, plugin, result): self.cache.extend(result) + def fetchForPlugin(self, pluginname, plugin, urls, cb, err=None): try: result = [] # result loaded from cache @@ -184,6 +189,7 @@ class InfoThread(PluginThread): result = [(url, 0, 3, url) for url in urls] cb(pluginname, result) + def decryptContainer(self, plugin, url): data = [] # only works on container plugins diff --git a/pyload/manager/thread/Plugin.py b/pyload/manager/thread/Plugin.py index 1e7d7b4e4..155e687d4 100644 --- a/pyload/manager/thread/Plugin.py +++ b/pyload/manager/thread/Plugin.py @@ -23,7 +23,6 @@ from pyload.api import OnlineStatus class PluginThread(Thread): """abstract base class for thread types""" - #-------------------------------------------------------------------------- def __init__(self, manager): """Constructor""" Thread.__init__(self) @@ -70,6 +69,7 @@ class PluginThread(Thread): self.m.core.log.info("Debug Report written to %s" % dump_name) + def getDebugDump(self, pyfile): dump = "pyLoad %s Debug Report of %s %s \n\nTRACEBACK:\n %s \n\nFRAMESTACK:\n" % ( self.m.core.api.getServerVersion(), pyfile.pluginname, pyfile.plugin.__version, format_exc()) @@ -124,6 +124,7 @@ class PluginThread(Thread): return dump + def clean(self, pyfile): """ set thread unactive and release pyfile """ self.active = False |