diff options
-rw-r--r-- | module/HookManager.py | 15 | ||||
-rw-r--r-- | module/plugins/Base.py | 2 | ||||
-rw-r--r-- | module/plugins/Hook.py | 2 | ||||
-rw-r--r-- | module/plugins/PluginManager.py | 53 | ||||
-rw-r--r-- | module/plugins/hooks/MultiHoster.py | 3 | ||||
-rwxr-xr-x | pyLoadCore.py | 11 |
6 files changed, 59 insertions, 27 deletions
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) diff --git a/module/plugins/Base.py b/module/plugins/Base.py index 34074095e..29ff3a723 100644 --- a/module/plugins/Base.py +++ b/module/plugins/Base.py @@ -39,6 +39,8 @@ class Base(object): __version__ = "0.1" #: Regexp pattern which will be matched for download/crypter plugins __pattern__ = r"" + #: Internal Hook plugin which is always loaded + __internal__ = False #: Config definition: list of (name, type, verbose_name, default_value) or #: (name, type, verbose_name, short_description, default_value) __config__ = list() diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py index 83ef091ae..22765c525 100644 --- a/module/plugins/Hook.py +++ b/module/plugins/Hook.py @@ -124,7 +124,7 @@ class Hook(Base): def isActivated(self): """ checks if hook is activated""" - return self.getConfig("activated") + return True if self.__internal__ else self.getConfig("activated") def init(self): pass diff --git a/module/plugins/PluginManager.py b/module/plugins/PluginManager.py index c345f765f..4e2fa21ed 100644 --- a/module/plugins/PluginManager.py +++ b/module/plugins/PluginManager.py @@ -24,7 +24,6 @@ from os import listdir, makedirs from os.path import isfile, join, exists, abspath, basename from sys import version_info from time import time -from traceback import print_exc from module.lib.SafeEval import const_eval as literal_eval from module.plugins.Base import Base @@ -44,9 +43,9 @@ class PluginManager: USERROOT = "userplugins." TYPES = ("crypter", "hoster", "captcha", "accounts", "hooks", "internal") + BUILTIN = re.compile(r'__(?P<attr>[a-z0-9_]+)__\s*=\s?(True|False|None|[0-9x.]+)', re.I) SINGLE = re.compile(r'__(?P<attr>[a-z0-9_]+)__\s*=\s*(?:r|u|_)?((?:(?<!")"(?!")|\'|\().*(?:(?<!")"(?!")|\'|\)))', re.I) - # note the nongreedy character, that means we can not embed list and dicts MULTI = re.compile(r'__(?P<attr>[a-z0-9_]+)__\s*=\s*((?:\{|\[|"{3}).*?(?:"""|\}|\]))', re.DOTALL | re.M | re.I) @@ -58,10 +57,9 @@ class PluginManager: self.plugins = {} self.modules = {} # cached modules - self.history = [] # match history to speedup parsing (type, name) + self.history = [] # match history to speedup parsing (type, name) self.createIndex() - self.core.config.parseValues(self.core.config.PLUGIN) #register for import hook @@ -126,28 +124,36 @@ class PluginManager: return plugins - def parsePlugin(self, filename, folder, name, home=None): - """ Parses a plugin from disk, folder means plugin type in this context. Also sets config. - - :arg home: dict with plugins, of which the found one will be matched against (according version) - :returns PluginTuple""" - + def parseAttributes(self, filename, name, folder=""): + """ Parse attribute dict from plugin""" data = open(filename, "rb") content = data.read() data.close() attrs = {} - for m in self.SINGLE.findall(content) + self.MULTI.findall(content): + for m in self.BUILTIN.findall(content) + self.SINGLE.findall(content) + self.MULTI.findall(content): #replace gettext function and eval result try: attrs[m[0]] = literal_eval(m[-1].replace("_(", "(")) except: self.logDebug(folder, name, "Error when parsing: %s" % m[-1]) - return + self.core.print_exc() + if not hasattr(Base, "__%s__" % m[0]): if m[0] != "type": #TODO remove type from all plugins, its not needed self.logDebug(folder, name, "Unknown attribute '%s'" % m[0]) + return attrs + + def parsePlugin(self, filename, folder, name, home=None): + """ Parses a plugin from disk, folder means plugin type in this context. Also sets config. + + :arg home: dict with plugins, of which the found one will be matched against (according version) + :returns PluginTuple""" + + attrs = self.parseAttributes(filename, name, folder) + if not attrs: return + version = 0 if "version" in attrs: @@ -185,7 +191,7 @@ class PluginManager: if folder == "internal": return plugin - if folder == "hooks" and "config" not in attrs: + if folder == "hooks" and "config" not in attrs and not attrs.get("internal", False): attrs["config"] = (["activated", "bool", "Activated", False],) if "config" in attrs and attrs["config"]: @@ -198,13 +204,11 @@ class PluginManager: else: config = [list(config)] - if folder == "hooks": - append = True + if folder == "hooks" and not attrs.get("internal", False): for item in config: - if item[0] == "activated": append = False - - # activated flag missing - if append: config.insert(0, ("activated", "bool", "Activated", False)) + if item[0] == "activated": break + else: # activated flag missing + config.insert(0, ("activated", "bool", "Activated", False)) try: self.core.config.addConfigSection(name, name, desc, long_desc, config) @@ -230,7 +234,7 @@ class PluginManager: if self.plugins[ptype][name].re.match(url): res[ptype].append((url, name)) found = (ptype, name) - break + break # need to exit this loop first if found: # found match if self.history[0] != found: #update history @@ -275,6 +279,12 @@ class PluginManager: # MultiHoster will overwrite this getPlugin = getPluginClass + + def loadAttributes(self, type, name): + plugin = self.plugins[type][name] + return self.parseAttributes(plugin.path, name, type) + + def loadModule(self, type, name): """ Returns loaded module for plugin @@ -292,8 +302,7 @@ class PluginManager: return module except Exception, e: self.log.error(_("Error importing %(name)s: %(msg)s") % {"name": name, "msg": str(e)}) - if self.core.debug: - print_exc() + self.core.print_exc() def loadClass(self, type, name): """Returns the class of a plugin with the same name""" diff --git a/module/plugins/hooks/MultiHoster.py b/module/plugins/hooks/MultiHoster.py index 749f2c104..2a567cce4 100644 --- a/module/plugins/hooks/MultiHoster.py +++ b/module/plugins/hooks/MultiHoster.py @@ -10,8 +10,9 @@ from module.plugins.PluginManager import PluginTuple class MultiHoster(Hook): __version__ = "0.1" + __internal__ = True __description__ = "Gives ability to use MultiHoster services. You need to add your account first." - __config__ = [("activated", "bool", "Activated", True)] + __config__ = [] __author_mail__ = ("pyLoad Team",) __author_mail__ = ("support@pyload.org",) diff --git a/pyLoadCore.py b/pyLoadCore.py index 7822fbf54..587dd3cc0 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -72,6 +72,13 @@ sys.stdout = getwriter(enc)(sys.stdout, errors="replace") # TODO List # - configurable auth system ldap/mysql # - cron job like sheduler +# - plugin stack / multi decrypter +# - media plugin type +# - general progress info +# - content attribute for files / sync status +# - sync with disk content / file manager / nested packages +# - would require new/modified link collector concept +# - interaction manager class Core(object): """pyLoad Core, one tool to rule them all... (the filehosters) :D""" @@ -600,6 +607,10 @@ class Core(object): if not self.pdb: self.pdb = Pdb() self.pdb.set_trace() + def print_exc(self): + if self.debug: + print_exc() + def path(self, *args): return join(pypath, *args) |