diff options
-rw-r--r-- | module/Api.py | 13 | ||||
-rw-r--r-- | module/HookManager.py | 55 | ||||
-rw-r--r-- | module/database/FileDatabase.py | 9 | ||||
-rw-r--r-- | module/plugins/Hook.py | 32 | ||||
-rw-r--r-- | module/plugins/Plugin.py | 3 | ||||
-rw-r--r-- | module/plugins/hooks/CaptchaTrader.py | 3 | ||||
-rw-r--r-- | module/plugins/hooks/ExternalScripts.py | 5 | ||||
-rw-r--r-- | module/plugins/hooks/IRCInterface.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/XMPPInterface.py | 4 |
9 files changed, 98 insertions, 30 deletions
diff --git a/module/Api.py b/module/Api.py index 2f6200950..832122ac5 100644 --- a/module/Api.py +++ b/module/Api.py @@ -185,8 +185,15 @@ class Api(Iface): except: return ['No log available'] - def checkURL(self, urls): - raise NotImplemented #TODO + def parseURLs(self, html): + #TODO implement + pass + + def checkURLs(self, urls): + pass + + def checkOnlineStatus(self, urls): + pass def isTimeDownload(self): """Checks if pyload will start new downloads according to time in config . @@ -655,7 +662,7 @@ class Api(Iface): :param username: :param password: - :param remoteip: + :param remoteip: Omit this argument, its only used internal :return: bool indicating login was successful """ if self.core.config["remote"]["nolocalauth"] and remoteip == "127.0.0.1": diff --git a/module/HookManager.py b/module/HookManager.py index 8b039683f..13e8695c2 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -25,8 +25,11 @@ from time import time from module.PluginThread import HookThread from module.plugins.PluginManager import literal_eval +from utils import lock class HookManager: + """Manages hooks and delegates and handles Events""" + def __init__(self, core): self.core = core self.config = self.core.config @@ -37,17 +40,11 @@ class HookManager: self.plugins = [] self.pluginMap = {} self.methods = {} #dict of names and list of methods usable by rpc - self.lock = RLock() - self.createIndex() - def lock(func): - def new(*args): - args[0].lock.acquire() - res = func(*args) - args[0].lock.release() - return res + self.events = {} # contains events - return new + self.lock = RLock() + self.createIndex() def try_catch(func): def new(*args): @@ -92,7 +89,7 @@ class HookManager: #hookClass = getattr(plugin, plugin.__name__) if self.core.config.getPlugin(pluginClass.__name__, "load"): - plugin = pluginClass(self.core) + plugin = pluginClass(self.core, self) plugins.append(plugin) self.pluginMap[pluginClass.__name__] = plugin if plugin.isActivated(): @@ -142,10 +139,13 @@ class HookManager: @lock def downloadStarts(self, pyfile): + #TODO: rename to downloadPreparing for plugin in self.plugins: if plugin.isActivated(): plugin.downloadStarts(pyfile) + self.dispatchEvent("downloadPreparing", pyfile) + @lock def downloadFinished(self, pyfile): for plugin in self.plugins: @@ -155,6 +155,8 @@ class HookManager: else: plugin.downloadFinished(pyfile) + self.dispatchEvent("downloadFinished", pyfile) + @lock def packageFinished(self, package): for plugin in self.plugins: @@ -164,22 +166,30 @@ class HookManager: else: plugin.packageFinished(package) + self.dispatchEvent("packageFinished", package) + @lock def beforeReconnecting(self, ip): for plugin in self.plugins: plugin.beforeReconnecting(ip) + self.dispatchEvent("beforeReconnecting", ip) + @lock def afterReconnecting(self, ip): for plugin in self.plugins: if plugin.isActivated(): plugin.afterReconnecting(ip) + self.dispatchEvent("afterReconnecting", ip) + @lock def unrarFinished(self, folder, fname): for plugin in self.plugins: plugin.unrarFinished(folder, fname) + self.dispatchEvent("unrarFinished", folder, fname) + def startThread(self, function, pyfile): t = HookThread(self.core.threadManager, function, pyfile) @@ -193,6 +203,29 @@ class HookManager: for name, plugin in self.pluginMap.iteritems(): if plugin.info: #copy and convert so str - info[name] = dict([(x, str(y)) for x, y in plugin.info.iteritems()]) + info[name] = dict([(x, str(y) if type(y) != basestring else y) for x, y in plugin.info.iteritems()]) return info + + def addEvent(self, event, func): + """Adds an event listener for event name""" + if self.events.has_key(event): + self.events[event].append(func) + else: + self.events[event] = [func] + + def removeEvent(self, event, func): + """removes previously added event listener""" + if self.events.has_key(event): + self.events[event].remove(func) + + def dispatchEvent(self, event, *args): + """dispatches event with args""" + if self.events.has_key(event): + for f in self.events[event]: + try: + f(*args) + except Exception, e: + self.log.debug("Error calling event handler %s: %s, %s, %s" + % (event, f, args, str(e))) +
\ No newline at end of file diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py index 0ed526240..c77bf5e95 100644 --- a/module/database/FileDatabase.py +++ b/module/database/FileDatabase.py @@ -115,12 +115,14 @@ class FileHandler: @change def addLinks(self, urls, package): """adds links""" - + + self.core.hookManager.dispatchEvent("linksAdded", urls, package) + data = self.core.pluginManager.parseUrls(urls) self.db.addLinks(data, package) self.core.threadManager.createInfoThread(data, package) - + #@TODO change from reloadAll event to package update event self.core.pullManager.addEvent(ReloadAllEvent("collector")) @@ -158,6 +160,7 @@ class FileHandler: self.db.deletePackage(p) self.core.pullManager.addEvent(e) + self.core.hookManager.dispatchEvent("packageDeleted", id) if self.packageCache.has_key(id): del self.packageCache[id] @@ -183,7 +186,7 @@ class FileHandler: del self.cache[id] self.db.deleteLink(f) - + self.core.pullManager.addEvent(e) p = self.getPackage(pid) diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py index 5e4b192ea..47faba95a 100644 --- a/module/plugins/Hook.py +++ b/module/plugins/Hook.py @@ -51,16 +51,36 @@ class Hook(): __description__ = """interface for hook""" __author_name__ = ("mkaay", "RaNaN") __author_mail__ = ("mkaay@mkaay.de", "RaNaN@pyload.org") - - def __init__(self, core): + + #: automatically register event listeners for functions, attribute will be deleted dont use it yourself + event_map = None + + #: periodic call interval in secondc + interval = 60 + + def __init__(self, core, manager): self.core = core self.log = core.log self.config = core.config - - self.interval = 60 #: periodic call interval in seconds - self.info = None #: Provide information in dict here, usable by API `getInfo` - + #: Provide information in dict here, usable by API `getInfo` + self.info = None + + #: `HookManager` + self.manager = manager + + #register events + if self.event_map: + for event, funcs in self.event_map.iteritems(): + if type(funcs) in (list, tuple): + for f in funcs: + self.manager.addEvent(event, getattr(self,f)) + else: + self.manager.addEvent(event, getattr(self,funcs)) + + #delete for various reasons + self.event_map = None + self.setup() def __repr__(self): diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py index 71a06c8b5..ec8a0151a 100644 --- a/module/plugins/Plugin.py +++ b/module/plugins/Plugin.py @@ -450,6 +450,9 @@ class Plugin(object): name = removeChars(name, '/\\"') filename = join(location, fs_encode(name)) + + self.core.hookManager.dispatchEvent("downloadStarts", self.pyfile, url, filename) + try: newname = self.req.httpDownload(url, filename, get=get, post=post, ref=ref, cookies=cookies, chunks=self.getChunkCount(), resume=self.resumeDownload, diff --git a/module/plugins/hooks/CaptchaTrader.py b/module/plugins/hooks/CaptchaTrader.py index 2bae9401a..62ac2c8cc 100644 --- a/module/plugins/hooks/CaptchaTrader.py +++ b/module/plugins/hooks/CaptchaTrader.py @@ -58,6 +58,8 @@ class CaptchaTrader(Hook): RESPOND_URL = "http://captchatrader.com/api/respond" GETCREDITS_URL = "http://captchatrader.com/api/get_credits/username:%(user)s/password:%(password)s/" + def setup(self): + self.info = {} def getCredits(self): json = getURL(CaptchaTrader.GETCREDITS_URL % {"user": self.getConfig("username"), @@ -67,6 +69,7 @@ class CaptchaTrader(Hook): raise CaptchaTraderException(response[1]) else: self.logInfo(_("%s credits left") % response[1]) + self.info["credits"] = response[1] return response[1] def submit(self, captcha, captchaType="file", match=None): diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index bbf5acde3..daffc1827 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -40,7 +40,6 @@ class ExternalScripts(Hook): folders = ['download_preparing', 'download_finished', 'package_finished', 'before_reconnect', 'after_reconnect', 'unrar_finished'] - for folder in folders: self.scripts[folder] = [] @@ -52,6 +51,7 @@ class ExternalScripts(Hook): if names: self.logInfo(_("Installed scripts for %s : %s") % (script_type, ", ".join([basename(x) for x in names]))) + def initPluginType(self, folder, path): if not exists(path): try: @@ -91,8 +91,7 @@ class ExternalScripts(Hook): def packageFinished(self, pypack): for script in self.scripts['package_finished']: folder = self.core.config['general']['download_folder'] - if self.core.config.get("general", "folder_per_package"): - folder = save_join(folder. pypack.folder) + folder = save_join(folder. pypack.folder) self.callScript(script, pypack.name, folder, pypack.id) diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 6fdb7622f..8be84f863 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -49,9 +49,9 @@ class IRCInterface(Thread, Hook): __author_name__ = ("Jeix") __author_mail__ = ("Jeix@hasnomail.com") - def __init__(self, core): + def __init__(self, core, manager): Thread.__init__(self) - Hook.__init__(self, core) + Hook.__init__(self, core, manager) self.setDaemon(True) self.sm = core.server_methods diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py index ce937c5d6..a96adf524 100644 --- a/module/plugins/hooks/XMPPInterface.py +++ b/module/plugins/hooks/XMPPInterface.py @@ -43,8 +43,8 @@ class XMPPInterface(IRCInterface, JabberClient): implements(IMessageHandlersProvider) - def __init__(self, core): - IRCInterface.__init__(self, core) + def __init__(self, core, manager): + IRCInterface.__init__(self, core, manager) self.jid = JID(self.getConfig("jid")) password = self.getConfig("pw") |