summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-12-17 23:55:01 +0100
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-12-17 23:55:01 +0100
commitde5e99f3c3082b96af398c01aec49e231726a36b (patch)
tree8176b5dc69137d6f7488a1814f2e060ed604d1a1
parentupdated plugin api and plugin manager (diff)
downloadpyload-de5e99f3c3082b96af398c01aec49e231726a36b.tar.xz
pluginmanager cleanup
-rw-r--r--module/plugins/PluginManager.py199
1 files changed, 116 insertions, 83 deletions
diff --git a/module/plugins/PluginManager.py b/module/plugins/PluginManager.py
index 744e09ef0..b1a82bcb6 100644
--- a/module/plugins/PluginManager.py
+++ b/module/plugins/PluginManager.py
@@ -21,7 +21,7 @@ import re
import sys
from os import listdir, makedirs
-from os.path import isfile, join, exists, abspath
+from os.path import isfile, join, exists, abspath, basename
from sys import version_info
from time import time
from traceback import print_exc
@@ -66,7 +66,7 @@ class PluginManager:
def createIndex(self):
"""create information for all plugins available"""
-
+ # add to path, so we can import from userplugins
sys.path.append(abspath(""))
if not exists("userplugins"):
@@ -79,10 +79,10 @@ class PluginManager:
for type in self.TYPES:
self.plugins[type] = self.parse(type)
- self.log.debug("Created index of plugins in %.2f ms", (time() - a) * 1000 )
+ self.log.debug("Created index of plugins in %.2f ms", (time() - a) * 1000)
- def parse(self, folder, home={}):
- """ Creates a dict with PluginTuples according to parsed information """
+ def parse(self, folder, home=None):
+ """ Analyze and parses all plugins in folder """
plugins = {}
if home:
pfolder = join("userplugins", folder)
@@ -98,10 +98,6 @@ class PluginManager:
for f in listdir(pfolder):
if (isfile(join(pfolder, f)) and f.endswith(".py") or f.endswith("_25.pyc") or f.endswith(
"_26.pyc") or f.endswith("_27.pyc")) and not f.startswith("_"):
- data = open(join(pfolder, f))
- content = data.read()
- data.close()
-
if f.endswith("_25.pyc") and version_info[0:2] != (2, 5):
continue
elif f.endswith("_26.pyc") and version_info[0:2] != (2, 6):
@@ -109,95 +105,111 @@ class PluginManager:
elif f.endswith("_27.pyc") and version_info[0:2] != (2, 7):
continue
+ # replace suffix and version tag
name = f[:-3]
if name[-1] == ".": name = name[:-4]
- attrs = {}
- for m in self.SINGLE.findall(content) + self.MULTI.findall(content):
- #replace gettext function and eval result
- attrs[m[0]] = literal_eval(m[-1].replace("_(", "("))
- 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])
-
- version = 0
-
- if "version" in attrs:
- try:
- version = float(attrs["version"])
- except ValueError:
- self.logDebug(folder, name, "Invalid version %s" % attrs["version"])
- version = 9 #TODO remove when plugins are fixed, causing update loops
- else:
- self.logDebug(folder, name, "No version attribute")
+ plugin = self.parsePlugin(join(pfolder, f), folder, name, home)
+ if plugin:
+ plugins[name] = plugin
- # home contains plugins from pyload root
- if home and name in home:
- if home[name].version >= version:
- continue
+ if not home:
+ temp = self.parse(folder, plugins)
+ plugins.update(temp)
- if name in IGNORE or (folder, name) in IGNORE:
- continue
+ return plugins
- if "pattern" in attrs and attrs["pattern"]:
- try:
- plugin_re = re.compile(attrs["pattern"])
- except:
- self.logDebug(folder, name, "Invalid regexp pattern '%s'" % attrs["pattern"])
- plugin_re = None
- else: plugin_re = None
+ 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"""
- # create plugin tuple
- plugin = PluginTuple(version, plugin_re, None, None, None, True if home else False,
- f.replace(".pyc", "").replace(".py", ""))
+ data = open(filename, "rb")
+ content = data.read()
+ data.close()
- plugins[name] = plugin
+ attrs = {}
+ for m in 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
+ 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])
- # internals have no config
- if folder == "internal":
- self.core.config.deleteConfig(name)
- continue
+ version = 0
- if "config" in attrs and attrs["config"]:
- config = attrs["config"]
- desc = attrs["description"] if "description" in attrs else ""
+ if "version" in attrs:
+ try:
+ version = float(attrs["version"])
+ except ValueError:
+ self.logDebug(folder, name, "Invalid version %s" % attrs["version"])
+ version = 9 #TODO remove when plugins are fixed, causing update loops
+ else:
+ self.logDebug(folder, name, "No version attribute")
- if type(config[0]) == tuple:
- config = [list(x) for x in config]
- else:
- config = [list(config)]
+ # home contains plugins from pyload root
+ if home and name in home:
+ if home[name].version >= version:
+ return
- if folder == "hooks":
- append = True
- for item in config:
- if item[0] == "activated": append = False
+ if name in IGNORE or (folder, name) in IGNORE:
+ return
- # activated flag missing
- if append: config.append(["activated", "bool", "Activated", False])
+ if "pattern" in attrs and attrs["pattern"]:
+ try:
+ plugin_re = re.compile(attrs["pattern"])
+ except:
+ self.logDebug(folder, name, "Invalid regexp pattern '%s'" % attrs["pattern"])
+ plugin_re = None
+ else: plugin_re = None
- try:
- self.core.config.addPluginConfig(name, config, desc)
- except:
- self.log.error("Invalid config in %s: %s" % (name, config))
- elif folder == "hooks": #force config creation
- desc = attrs["description"] if "description" in attrs else ""
- config = (["activated", "bool", "Activated", False],)
+ # create plugin tuple
+ plugin = PluginTuple(version, plugin_re, None, None, None, bool(home), filename)
- try:
- self.core.config.addPluginConfig(name, config, desc)
- except:
- self.log.error("Invalid config in %s: %s" % (name, config))
- if not home:
- temp = self.parse(folder, plugins)
- plugins.update(temp)
+ # internals have no config
+ if folder == "internal":
+ self.core.config.deleteConfig(name)
+ return plugin
- return plugins
+ if "config" in attrs and attrs["config"]:
+ config = attrs["config"]
+ desc = attrs["description"] if "description" in attrs else ""
- def parsePlugin(self):
- pass
+ if type(config[0]) == tuple:
+ config = [list(x) for x in config]
+ else:
+ config = [list(config)]
+
+ if folder == "hooks":
+ append = True
+ for item in config:
+ if item[0] == "activated": append = False
+
+ # activated flag missing
+ if append: config.append(["activated", "bool", "Activated", False])
+
+ try:
+ self.core.config.addPluginConfig(name, config, desc)
+ except:
+ self.log.error("Invalid config in %s: %s" % (name, config))
+
+ elif folder == "hooks": #force config creation
+ desc = attrs["description"] if "description" in attrs else ""
+ config = (["activated", "bool", "Activated", False],)
+
+ try:
+ self.core.config.addPluginConfig(name, config, desc)
+ except:
+ self.log.error("Invalid config in %s: %s" % (name, config))
+
+ return plugin
def parseUrls(self, urls):
@@ -206,7 +218,9 @@ class PluginManager:
res = [] # tupels of (url, plugin)
for url in urls:
- if type(url) not in (str, unicode, buffer): continue
+ if type(url) not in (str, unicode, buffer):
+ self.log.debug("Parsing invalid type %s" % type(url))
+ continue
found = False
for ptype, name in self.history:
@@ -214,7 +228,7 @@ class PluginManager:
res.append((url, name))
found = (ptype, name)
- if found:
+ if found and self.history[0] != found:
# found match, update history
self.history.remove(found)
self.history.insert(0, found)
@@ -236,7 +250,7 @@ class PluginManager:
def getPlugins(self, type):
# TODO clean this workaround
- if type not in self.plugins: type+="s" # append s, so updater can find the plugins
+ if type not in self.plugins: type += "s" # append s, so updater can find the plugins
return self.plugins[type]
def findPlugin(self, name, pluginlist=("hoster", "crypter", "container")):
@@ -277,8 +291,9 @@ class PluginManager:
if name in plugins:
if (type, name) in self.modules: return self.modules[(type, name)]
try:
- module = __import__(self.ROOT + "%s.%s" % (type, plugins[name].path), globals(), locals(),
- plugins[name].path)
+ # convert path to python recognizable import
+ path = basename(plugins[name].path).replace(".pyc", "").replace(".py", "")
+ module = __import__(self.ROOT + "%s.%s" % (type, path), globals(), locals(), path)
self.modules[(type, name)] = module # cache import, maybne unneeded
return module
except Exception, e:
@@ -369,6 +384,24 @@ class PluginManager:
return True
+ def loadIcons(self):
+ """Loads all icons from plugins, plugin type is not in result, because its not important here.
+
+ :return: Dict of names mapped to icons
+ """
+ pass
+
+ def loadIcon(self, type, name):
+ """ load icon for single plugin, base64 encoded"""
+ pass
+
+ def checkDependencies(self, type, name):
+ """ Check deps for given plugin
+
+ :return: List of unfullfilled dependencies
+ """
+ pass
+
if __name__ == "__main__":
_ = lambda x: x