diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2011-12-17 23:55:01 +0100 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2011-12-17 23:55:01 +0100 |
commit | de5e99f3c3082b96af398c01aec49e231726a36b (patch) | |
tree | 8176b5dc69137d6f7488a1814f2e060ed604d1a1 | |
parent | updated plugin api and plugin manager (diff) | |
download | pyload-de5e99f3c3082b96af398c01aec49e231726a36b.tar.xz |
pluginmanager cleanup
-rw-r--r-- | module/plugins/PluginManager.py | 199 |
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 |