From 4e918edba6c3808b095eab1bad137a2a8cab970d Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 17 Dec 2011 21:53:57 +0100 Subject: updated plugin api and plugin manager --- module/HookManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 16f692d76..8bfcadca6 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -119,7 +119,7 @@ class HookManager: active = [] deactive = [] - for pluginname in self.core.pluginManager.hookPlugins: + for pluginname in self.core.pluginManager.getPlugins("hooks"): try: #hookClass = getattr(plugin, plugin.__name__) -- cgit v1.2.3 From 6eae782f13953dd0ba2bbe1b582cf33fd4d7d90a Mon Sep 17 00:00:00 2001 From: RaNaN Date: Mon, 19 Dec 2011 23:10:49 +0100 Subject: configparser v2, warning CONFIG will be DELETED. --- module/HookManager.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 8bfcadca6..e32508c48 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -50,8 +50,7 @@ class HookManager: allDownloadsProcessed Every link was handled, pyload would idle afterwards. allDownloadsFinished Every download in queue is finished. unrarFinished folder, fname An Unrar job finished - configChanged The config was changed via the api. - pluginConfigChanged The plugin config changed, due to api or internal process. + configChanged sec,opt,value The config was changed. ===================== ============== ================================== | Notes: @@ -74,14 +73,15 @@ class HookManager: self.events = {} # contains events - #registering callback for config event - self.config.pluginCB = MethodType(self.dispatchEvent, "pluginConfigChanged", basestring) - - self.addEvent("pluginConfigChanged", self.manageHooks) - self.lock = RLock() self.createIndex() + #registering callback for config event + self.config.changeCB = MethodType(self.dispatchEvent, "configChanged", basestring) + + # manage hooks an config change + self.addEvent("configChanged", self.manageHooks) + def try_catch(func): def new(*args): try: @@ -123,7 +123,7 @@ class HookManager: try: #hookClass = getattr(plugin, plugin.__name__) - if self.core.config.getPlugin(pluginname, "activated"): + if self.core.config.get(pluginname, "activated"): pluginClass = self.core.pluginManager.loadClass("hooks", pluginname) if not pluginClass: continue @@ -147,6 +147,11 @@ class HookManager: self.plugins = plugins def manageHooks(self, plugin, name, value): + + # check if section was a plugin + if plugin not in self.core.pluginManager.getPlugins("hooks"): + return + if name == "activated" and value: self.activateHook(plugin) elif name == "activated" and not value: -- cgit v1.2.3 From d35c003cc53d4723d1dfe0d81eeb9bea78cee594 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 31 Dec 2011 16:01:24 +0100 Subject: new crypter plugin API, now decrypting possible for now. --- module/HookManager.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index e32508c48..386be0f5c 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -25,7 +25,7 @@ from threading import RLock from types import MethodType -from module.PluginThread import HookThread +from module.threads.HookThread import HookThread from module.plugins.PluginManager import literal_eval from utils import lock @@ -39,7 +39,7 @@ class HookManager: Only do very short tasks or use threads. **Known Events:** - Most hook methods exists as events. These are the additional known events. + Most hook methods exists as events. These are some additional known events. ===================== ============== ================================== Name Arguments Description @@ -103,10 +103,10 @@ class HookManager: else: self.methods[plugin] = {func: doc} - def callRPC(self, plugin, func, args, parse): - if not args: args = tuple() - if parse: - args = tuple([literal_eval(x) for x in args]) + def callRPC(self, plugin, func, args): + if not args: args = [] + else: + args = literal_eval(args) plugin = self.pluginMap[plugin] f = getattr(plugin, func) -- cgit v1.2.3 From 18466eb7f8f3cd4ca9a0824074d2ff454939fce6 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Wed, 4 Jan 2012 17:23:13 +0100 Subject: some fixes --- module/HookManager.py | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 386be0f5c..4b24f590a 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -15,7 +15,6 @@ along with this program; if not, see . @author: RaNaN, mkaay - @interface-version: 0.1 """ import __builtin__ @@ -30,35 +29,7 @@ from module.plugins.PluginManager import literal_eval from utils import lock class HookManager: - """Manages hooks, delegates and handles Events. - - Every plugin can define events, \ - but some very usefull events are called by the Core. - Contrary to overwriting hook methods you can use event listener, - which provides additional entry point in the control flow. - Only do very short tasks or use threads. - - **Known Events:** - Most hook methods exists as events. These are some additional known events. - - ===================== ============== ================================== - Name Arguments Description - ===================== ============== ================================== - downloadPreparing fid A download was just queued and will be prepared now. - downloadStarts fid A plugin will immediately starts the download afterwards. - linksAdded links, pid Someone just added links, you are able to modify the links. - allDownloadsProcessed Every link was handled, pyload would idle afterwards. - allDownloadsFinished Every download in queue is finished. - unrarFinished folder, fname An Unrar job finished - configChanged sec,opt,value The config was changed. - ===================== ============== ================================== - - | Notes: - | allDownloadsProcessed is *always* called before allDownloadsFinished. - | configChanged is *always* called before pluginConfigChanged. - - - """ + """ Manages hooks, loading, unloading. """ def __init__(self, core): self.core = core -- cgit v1.2.3 From 4f879e899562e19d8a7fc64f3099dbd301ae421f Mon Sep 17 00:00:00 2001 From: Wieland Hoffmann Date: Thu, 5 Jan 2012 20:49:22 +0100 Subject: Only claim to have unloaded a hook after it was unloaded --- module/HookManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 4b24f590a..7057b6ee6 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -157,9 +157,8 @@ class HookManager: if not hook: return - self.log.debug("Plugin unloaded: %s" % plugin) - hook.unload() + self.log.debug("Plugin unloaded: %s" % plugin) #remove periodic call self.log.debug("Removed callback %s" % self.core.scheduler.removeJob(hook.cb)) -- cgit v1.2.3 From b877847094b0ba03a098dff0fd769eb456b48dd1 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Fri, 6 Jan 2012 17:54:53 +0100 Subject: several improvements, also closes #486, #487 --- module/HookManager.py | 191 ++++++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 129 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 7057b6ee6..41908bc47 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -18,7 +18,7 @@ """ import __builtin__ -import traceback +from traceback import print_exc from thread import start_new_thread from threading import RLock @@ -38,11 +38,9 @@ class HookManager: __builtin__.hookManager = self #needed to let hooks register themself self.log = self.core.log - self.plugins = [] - self.pluginMap = {} - self.methods = {} #dict of names and list of methods usable by rpc - - self.events = {} # contains events + self.plugins = {} + self.methods = {} # dict of names and list of methods usable by rpc + self.events = {} # Contains event that will be registred self.lock = RLock() self.createIndex() @@ -53,17 +51,19 @@ class HookManager: # manage hooks an config change self.addEvent("configChanged", self.manageHooks) - def try_catch(func): - def new(*args): + @lock + def callInHooks(self, event, *args): + """ Calls a method in hook and catch / log errors""" + for plugin in self.plugins.itervalues(): try: + func = getattr(plugin, event) return func(*args) except Exception, e: - args[0].log.error(_("Error executing hooks: %s") % str(e)) - if args[0].core.debug: - traceback.print_exc() - - return new + plugin.logError(_("Error executing %s" % event), e) + if self.core.debug: + print_exc() + self.dispatchEvent(event, *args) def addRPC(self, plugin, func, doc): plugin = plugin.rpartition(".")[2] @@ -79,14 +79,12 @@ class HookManager: else: args = literal_eval(args) - plugin = self.pluginMap[plugin] + plugin = self.plugins[plugin] f = getattr(plugin, func) return f(*args) - + @lock def createIndex(self): - plugins = [] - active = [] deactive = [] @@ -97,10 +95,9 @@ class HookManager: if self.core.config.get(pluginname, "activated"): pluginClass = self.core.pluginManager.loadClass("hooks", pluginname) if not pluginClass: continue - + plugin = pluginClass(self.core, self) - plugins.append(plugin) - self.pluginMap[pluginClass.__name__] = plugin + self.plugins[pluginClass.__name__] = plugin if plugin.isActivated(): active.append(pluginClass.__name__) else: @@ -110,15 +107,12 @@ class HookManager: except: self.log.warning(_("Failed activating %(name)s") % {"name": pluginname}) if self.core.debug: - traceback.print_exc() + print_exc() self.log.info(_("Activated plugins: %s") % ", ".join(sorted(active))) self.log.info(_("Deactivate plugins: %s") % ", ".join(sorted(deactive))) - self.plugins = plugins - def manageHooks(self, plugin, name, value): - # check if section was a plugin if plugin not in self.core.pluginManager.getPlugins("hooks"): return @@ -128,12 +122,11 @@ class HookManager: elif name == "activated" and not value: self.deactivateHook(plugin) + @lock def activateHook(self, plugin): - #check if already loaded - for inst in self.plugins: - if inst.__name__ == plugin: - return + if plugin in self.plugins: + return pluginClass = self.core.pluginManager.loadClass("hooks", plugin) @@ -142,105 +135,63 @@ class HookManager: self.log.debug("Plugin loaded: %s" % plugin) plugin = pluginClass(self.core, self) - self.plugins.append(plugin) - self.pluginMap[pluginClass.__name__] = plugin + self.plugins[pluginClass.__name__] = plugin - # call core Ready - start_new_thread(plugin.coreReady, tuple()) + # active the hook in new thread + start_new_thread(plugin.activate, tuple()) + @lock def deactivateHook(self, plugin): + if plugin not in self.plugins: + return + else: + hook = self.plugins[plugin] - hook = None - for inst in self.plugins: - if inst.__name__ == plugin: - hook = inst - - if not hook: return - - hook.unload() - self.log.debug("Plugin unloaded: %s" % plugin) + hook.deactivate() + self.log.debug("Plugin deactivated: %s" % plugin) #remove periodic call self.log.debug("Removed callback %s" % self.core.scheduler.removeJob(hook.cb)) - self.plugins.remove(hook) - del self.pluginMap[hook.__name__] + del self.plugins[hook.__name__] + #remove event listener + for f in dir(hook): + if f.startswith("__") or type(getattr(hook, f)) != MethodType: + continue + self.core.eventManager.removeFromEvents(getattr(hook, f)) - @try_catch - def coreReady(self): - for plugin in self.plugins: + def activateHooks(self): + for plugin in self.plugins.itervalues(): if plugin.isActivated(): - plugin.coreReady() - - self.dispatchEvent("coreReady") + plugin.activate() - @try_catch - def coreExiting(self): - for plugin in self.plugins: + def deactivateHooks(self): + """ Called when core is shutting down """ + for plugin in self.plugins.itervalues(): if plugin.isActivated(): - plugin.coreExiting() - - self.dispatchEvent("coreExiting") + plugin.deactivate() - @lock def downloadPreparing(self, pyfile): - for plugin in self.plugins: - if plugin.isActivated(): - plugin.downloadPreparing(pyfile) + self.callInHooks("downloadPreparing", pyfile) - self.dispatchEvent("downloadPreparing", pyfile) - - @lock def downloadFinished(self, pyfile): - for plugin in self.plugins: - if plugin.isActivated(): - if "downloadFinished" in plugin.__threaded__: - self.startThread(plugin.downloadFinished, pyfile) - else: - plugin.downloadFinished(pyfile) - - self.dispatchEvent("downloadFinished", pyfile) + self.callInHooks("downloadFinished", pyfile) - @lock - @try_catch def downloadFailed(self, pyfile): - for plugin in self.plugins: - if plugin.isActivated(): - if "downloadFailed" in plugin.__threaded__: - self.startThread(plugin.downloadFinished, pyfile) - else: - plugin.downloadFailed(pyfile) - - self.dispatchEvent("downloadFailed", pyfile) + self.callInHooks("downloadFailed", pyfile) - @lock def packageFinished(self, package): - for plugin in self.plugins: - if plugin.isActivated(): - if "packageFinished" in plugin.__threaded__: - self.startThread(plugin.packageFinished, package) - else: - plugin.packageFinished(package) - - self.dispatchEvent("packageFinished", package) + self.callInHooks("packageFinished", package) - @lock def beforeReconnecting(self, ip): - for plugin in self.plugins: - plugin.beforeReconnecting(ip) + self.callInHooks("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) + self.callInHooks("afterReconnecting", ip) + @lock def startThread(self, function, *args, **kwargs): - t = HookThread(self.core.threadManager, function, args, kwargs) + HookThread(self.core.threadManager, function, args, kwargs) def activePlugins(self): """ returns all active plugins """ @@ -249,42 +200,24 @@ class HookManager: def getAllInfo(self): """returns info stored by hook plugins""" info = {} - for name, plugin in self.pluginMap.iteritems(): + for name, plugin in self.plugins.iteritems(): if plugin.info: #copy and convert so str - info[name] = dict([(x, str(y) if not isinstance(y, basestring) else y) for x, y in plugin.info.iteritems()]) + info[name] = dict( + [(x, str(y) if not isinstance(y, basestring) else y) for x, y in plugin.info.iteritems()]) return info - def getInfo(self, plugin): info = {} - if plugin in self.pluginMap and self.pluginMap[plugin].info: + if plugin in self.plugins and self.plugins[plugin].info: info = dict([(x, str(y) if not isinstance(y, basestring) else y) - for x, y in self.pluginMap[plugin].info.iteritems()]) + for x, y in self.plugins[plugin].info.iteritems()]) return info - def addEvent(self, event, func): - """Adds an event listener for event name""" - if event in self.events: - self.events[event].append(func) - else: - self.events[event] = [func] - - def removeEvent(self, event, func): - """removes previously added event listener""" - if event in self.events: - self.events[event].remove(func) - - def dispatchEvent(self, event, *args): - """dispatches event with args""" - if event in self.events: - for f in self.events[event]: - try: - f(*args) - except Exception, e: - self.log.warning("Error calling event handler %s: %s, %s, %s" - % (event, f, args, str(e))) - if self.core.debug: - traceback.print_exc() + def addEvent(self, *args): + self.core.eventManager.addEvent(*args) + + def dispatchEvent(self, *args): + self.core.eventManager.dispatchEvent(*args) -- cgit v1.2.3 From 3c65474105713da5a2b7a77a9e20a5f9b7b3bc47 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Fri, 6 Jan 2012 20:47:16 +0100 Subject: closed #486 --- module/HookManager.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 41908bc47..d0ceb89b2 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -53,18 +53,20 @@ class HookManager: @lock def callInHooks(self, event, *args): - """ Calls a method in hook and catch / log errors""" + """ Calls a method in all hooks and catch / log errors""" for plugin in self.plugins.itervalues(): - try: - func = getattr(plugin, event) - return func(*args) - except Exception, e: - plugin.logError(_("Error executing %s" % event), e) - if self.core.debug: - print_exc() - + self.call(plugin, event, *args) self.dispatchEvent(event, *args) + def call(self, hook, f, *args): + try: + func = getattr(hook, f) + return func(*args) + except Exception, e: + plugin.logError(_("Error executing %s" % event), e) + if self.core.debug: + print_exc() + def addRPC(self, plugin, func, doc): plugin = plugin.rpartition(".")[2] doc = doc.strip() if doc else "" @@ -147,7 +149,7 @@ class HookManager: else: hook = self.plugins[plugin] - hook.deactivate() + self.call(hook, "deactivate") self.log.debug("Plugin deactivated: %s" % plugin) #remove periodic call @@ -161,15 +163,16 @@ class HookManager: self.core.eventManager.removeFromEvents(getattr(hook, f)) def activateHooks(self): + self.log.info(_("Activating Plugins...")) for plugin in self.plugins.itervalues(): if plugin.isActivated(): - plugin.activate() + self.call(plugin, "activate") def deactivateHooks(self): """ Called when core is shutting down """ + self.log.info(_("Deactivating Plugins...")) for plugin in self.plugins.itervalues(): - if plugin.isActivated(): - plugin.deactivate() + self.call(plugin, "deactivate") def downloadPreparing(self, pyfile): self.callInHooks("downloadPreparing", pyfile) -- cgit v1.2.3 From 1bb6ebf544b43cacf7c0755c5a8608b79b95e2d6 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 7 Jan 2012 20:11:16 +0100 Subject: MultiHoster plugin type, some fixes, new documentation structure --- module/HookManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index d0ceb89b2..51bc706ca 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -63,7 +63,7 @@ class HookManager: func = getattr(hook, f) return func(*args) except Exception, e: - plugin.logError(_("Error executing %s" % event), e) + hook.logError(_("Error when executing %s" % f), e) if self.core.debug: print_exc() -- cgit v1.2.3 From 6eaa7bb25e2254c80c43fe46166142d590e86c64 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 7 Jan 2012 23:58:28 +0100 Subject: some cleanups --- module/HookManager.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 51bc706ca..b915341e3 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -26,7 +26,7 @@ from types import MethodType from module.threads.HookThread import HookThread from module.plugins.PluginManager import literal_eval -from utils import lock +from utils import lock, to_string class HookManager: """ Manages hooks, loading, unloading. """ @@ -207,17 +207,23 @@ class HookManager: if plugin.info: #copy and convert so str info[name] = dict( - [(x, str(y) if not isinstance(y, basestring) else y) for x, y in plugin.info.iteritems()]) + [(x, to_string(y)) for x, y in plugin.info.iteritems()]) return info def getInfo(self, plugin): info = {} if plugin in self.plugins and self.plugins[plugin].info: - info = dict([(x, str(y) if not isinstance(y, basestring) else y) + info = dict([(x, to_string(y)) for x, y in self.plugins[plugin].info.iteritems()]) return info + def addEventListener(self, plugin, func, event): + pass + + def addConfigHandler(self, plugin, func): + pass + def addEvent(self, *args): self.core.eventManager.addEvent(*args) -- cgit v1.2.3 From bac28b7740aae772636d8b90e291d9c17dfd59a7 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 8 Jan 2012 14:44:59 +0100 Subject: new MultiHoster hook --- module/HookManager.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index b915341e3..3691fe3ed 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -28,6 +28,9 @@ from module.threads.HookThread import HookThread from module.plugins.PluginManager import literal_eval from utils import lock, to_string +def class_name(p): + return p.rpartition(".")[2] + class HookManager: """ Manages hooks, loading, unloading. """ @@ -68,7 +71,7 @@ class HookManager: print_exc() def addRPC(self, plugin, func, doc): - plugin = plugin.rpartition(".")[2] + plugin = class_name(plugin) doc = doc.strip() if doc else "" if plugin in self.methods: @@ -141,6 +144,7 @@ class HookManager: # active the hook in new thread start_new_thread(plugin.activate, tuple()) + self.registerEvents() @lock def deactivateHook(self, plugin): @@ -168,6 +172,8 @@ class HookManager: if plugin.isActivated(): self.call(plugin, "activate") + self.registerEvents() + def deactivateHooks(self): """ Called when core is shutting down """ self.log.info(_("Deactivating Plugins...")) @@ -219,10 +225,21 @@ class HookManager: return info def addEventListener(self, plugin, func, event): - pass + plugin = class_name(plugin) + if plugin not in self.events: + self.events[plugin] = [] + self.events[plugin].append((func, event)) + + def registerEvents(self): + for name, plugin in self.plugins.iteritems(): + if name in self.events: + for func, event in self.events[name]: + self.addEvent(event, getattr(plugin, func)) + # clean up + del self.events[name] def addConfigHandler(self, plugin, func): - pass + pass #TODO def addEvent(self, *args): self.core.eventManager.addEvent(*args) -- cgit v1.2.3 From 1ecdd9f6b53fec45e1d48592e3ff56aa7a576bec Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 8 Jan 2012 16:47:52 +0100 Subject: some cleanups, closed #490 --- module/HookManager.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 3691fe3ed..8afd6fe26 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -28,9 +28,6 @@ from module.threads.HookThread import HookThread from module.plugins.PluginManager import literal_eval from utils import lock, to_string -def class_name(p): - return p.rpartition(".")[2] - class HookManager: """ Manages hooks, loading, unloading. """ @@ -71,7 +68,6 @@ class HookManager: print_exc() def addRPC(self, plugin, func, doc): - plugin = class_name(plugin) doc = doc.strip() if doc else "" if plugin in self.methods: @@ -225,7 +221,6 @@ class HookManager: return info def addEventListener(self, plugin, func, event): - plugin = class_name(plugin) if plugin not in self.events: self.events[plugin] = [] self.events[plugin].append((func, event)) -- cgit v1.2.3 From c7ad1cc5b4a5d190a060e3ddd9274c3065da6708 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Fri, 13 Jan 2012 23:24:21 +0100 Subject: plugin unit test, closed #499, #500 --- module/HookManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 8afd6fe26..0ad37b321 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -200,7 +200,7 @@ class HookManager: def activePlugins(self): """ returns all active plugins """ - return [x for x in self.plugins if x.isActivated()] + return [x for x in self.plugins.itervalues() if x.isActivated()] def getAllInfo(self): """returns info stored by hook plugins""" -- cgit v1.2.3 From d7eef2c28eae2e43e3ade4441810ecc0cdea6fd7 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 5 Feb 2012 21:21:36 +0100 Subject: option for internal plugins --- module/HookManager.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py index 0ad37b321..f3201738d 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -91,16 +91,23 @@ class HookManager: for pluginname in self.core.pluginManager.getPlugins("hooks"): try: - #hookClass = getattr(plugin, plugin.__name__) + # check first for builtin plugin + attrs = self.core.pluginManager.loadAttributes("hooks", pluginname) + internal = attrs.get("internal", False) - if self.core.config.get(pluginname, "activated"): + if internal or self.core.config.get(pluginname, "activated"): pluginClass = self.core.pluginManager.loadClass("hooks", pluginname) + if not pluginClass: continue plugin = pluginClass(self.core, self) self.plugins[pluginClass.__name__] = plugin - if plugin.isActivated(): + + # hide internals from printing + if not internal and plugin.isActivated(): active.append(pluginClass.__name__) + else: + self.log.debug("Loaded internal plugin: %s" % pluginClass.__name__) else: deactive.append(pluginname) @@ -149,6 +156,8 @@ class HookManager: else: hook = self.plugins[plugin] + if hook.__internal__: return + self.call(hook, "deactivate") self.log.debug("Plugin deactivated: %s" % plugin) -- cgit v1.2.3 From 4df2b77fdf42046fe19bd371be7c7255986b5980 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Tue, 6 Mar 2012 13:36:39 +0100 Subject: renamed hooks to addons, new filemanager and database, many new api methods you will loose ALL your LINKS, webinterface will NOT work --- module/HookManager.py | 253 -------------------------------------------------- 1 file changed, 253 deletions(-) delete mode 100644 module/HookManager.py (limited to 'module/HookManager.py') diff --git a/module/HookManager.py b/module/HookManager.py deleted file mode 100644 index f3201738d..000000000 --- a/module/HookManager.py +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - - @author: RaNaN, mkaay -""" -import __builtin__ - -from traceback import print_exc -from thread import start_new_thread -from threading import RLock - -from types import MethodType - -from module.threads.HookThread import HookThread -from module.plugins.PluginManager import literal_eval -from utils import lock, to_string - -class HookManager: - """ Manages hooks, loading, unloading. """ - - def __init__(self, core): - self.core = core - self.config = self.core.config - - __builtin__.hookManager = self #needed to let hooks register themself - - self.log = self.core.log - self.plugins = {} - self.methods = {} # dict of names and list of methods usable by rpc - self.events = {} # Contains event that will be registred - - self.lock = RLock() - self.createIndex() - - #registering callback for config event - self.config.changeCB = MethodType(self.dispatchEvent, "configChanged", basestring) - - # manage hooks an config change - self.addEvent("configChanged", self.manageHooks) - - @lock - def callInHooks(self, event, *args): - """ Calls a method in all hooks and catch / log errors""" - for plugin in self.plugins.itervalues(): - self.call(plugin, event, *args) - self.dispatchEvent(event, *args) - - def call(self, hook, f, *args): - try: - func = getattr(hook, f) - return func(*args) - except Exception, e: - hook.logError(_("Error when executing %s" % f), e) - if self.core.debug: - print_exc() - - def addRPC(self, plugin, func, doc): - doc = doc.strip() if doc else "" - - if plugin in self.methods: - self.methods[plugin][func] = doc - else: - self.methods[plugin] = {func: doc} - - def callRPC(self, plugin, func, args): - if not args: args = [] - else: - args = literal_eval(args) - - plugin = self.plugins[plugin] - f = getattr(plugin, func) - return f(*args) - - @lock - def createIndex(self): - active = [] - deactive = [] - - for pluginname in self.core.pluginManager.getPlugins("hooks"): - try: - # check first for builtin plugin - attrs = self.core.pluginManager.loadAttributes("hooks", pluginname) - internal = attrs.get("internal", False) - - if internal or self.core.config.get(pluginname, "activated"): - pluginClass = self.core.pluginManager.loadClass("hooks", pluginname) - - if not pluginClass: continue - - plugin = pluginClass(self.core, self) - self.plugins[pluginClass.__name__] = plugin - - # hide internals from printing - if not internal and plugin.isActivated(): - active.append(pluginClass.__name__) - else: - self.log.debug("Loaded internal plugin: %s" % pluginClass.__name__) - else: - deactive.append(pluginname) - - - except: - self.log.warning(_("Failed activating %(name)s") % {"name": pluginname}) - if self.core.debug: - print_exc() - - self.log.info(_("Activated plugins: %s") % ", ".join(sorted(active))) - self.log.info(_("Deactivate plugins: %s") % ", ".join(sorted(deactive))) - - def manageHooks(self, plugin, name, value): - # check if section was a plugin - if plugin not in self.core.pluginManager.getPlugins("hooks"): - return - - if name == "activated" and value: - self.activateHook(plugin) - elif name == "activated" and not value: - self.deactivateHook(plugin) - - @lock - def activateHook(self, plugin): - #check if already loaded - if plugin in self.plugins: - return - - pluginClass = self.core.pluginManager.loadClass("hooks", plugin) - - if not pluginClass: return - - self.log.debug("Plugin loaded: %s" % plugin) - - plugin = pluginClass(self.core, self) - self.plugins[pluginClass.__name__] = plugin - - # active the hook in new thread - start_new_thread(plugin.activate, tuple()) - self.registerEvents() - - @lock - def deactivateHook(self, plugin): - if plugin not in self.plugins: - return - else: - hook = self.plugins[plugin] - - if hook.__internal__: return - - self.call(hook, "deactivate") - self.log.debug("Plugin deactivated: %s" % plugin) - - #remove periodic call - self.log.debug("Removed callback %s" % self.core.scheduler.removeJob(hook.cb)) - del self.plugins[hook.__name__] - - #remove event listener - for f in dir(hook): - if f.startswith("__") or type(getattr(hook, f)) != MethodType: - continue - self.core.eventManager.removeFromEvents(getattr(hook, f)) - - def activateHooks(self): - self.log.info(_("Activating Plugins...")) - for plugin in self.plugins.itervalues(): - if plugin.isActivated(): - self.call(plugin, "activate") - - self.registerEvents() - - def deactivateHooks(self): - """ Called when core is shutting down """ - self.log.info(_("Deactivating Plugins...")) - for plugin in self.plugins.itervalues(): - self.call(plugin, "deactivate") - - def downloadPreparing(self, pyfile): - self.callInHooks("downloadPreparing", pyfile) - - def downloadFinished(self, pyfile): - self.callInHooks("downloadFinished", pyfile) - - def downloadFailed(self, pyfile): - self.callInHooks("downloadFailed", pyfile) - - def packageFinished(self, package): - self.callInHooks("packageFinished", package) - - def beforeReconnecting(self, ip): - self.callInHooks("beforeReconnecting", ip) - - def afterReconnecting(self, ip): - self.callInHooks("afterReconnecting", ip) - - @lock - def startThread(self, function, *args, **kwargs): - HookThread(self.core.threadManager, function, args, kwargs) - - def activePlugins(self): - """ returns all active plugins """ - return [x for x in self.plugins.itervalues() if x.isActivated()] - - def getAllInfo(self): - """returns info stored by hook plugins""" - info = {} - for name, plugin in self.plugins.iteritems(): - if plugin.info: - #copy and convert so str - info[name] = dict( - [(x, to_string(y)) for x, y in plugin.info.iteritems()]) - return info - - def getInfo(self, plugin): - info = {} - if plugin in self.plugins and self.plugins[plugin].info: - info = dict([(x, to_string(y)) - for x, y in self.plugins[plugin].info.iteritems()]) - - return info - - def addEventListener(self, plugin, func, event): - if plugin not in self.events: - self.events[plugin] = [] - self.events[plugin].append((func, event)) - - def registerEvents(self): - for name, plugin in self.plugins.iteritems(): - if name in self.events: - for func, event in self.events[name]: - self.addEvent(event, getattr(plugin, func)) - # clean up - del self.events[name] - - def addConfigHandler(self, plugin, func): - pass #TODO - - def addEvent(self, *args): - self.core.eventManager.addEvent(*args) - - def dispatchEvent(self, *args): - self.core.eventManager.dispatchEvent(*args) - -- cgit v1.2.3