summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/HookManager.py15
-rw-r--r--module/plugins/Base.py2
-rw-r--r--module/plugins/Hook.py2
-rw-r--r--module/plugins/PluginManager.py53
-rw-r--r--module/plugins/hooks/MultiHoster.py3
-rwxr-xr-xpyLoadCore.py11
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)