summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/AccountManager.py2
-rw-r--r--module/plugins/Base.py121
-rw-r--r--module/plugins/Hook.py2
-rw-r--r--module/plugins/Hoster.py22
-rw-r--r--module/plugins/Plugin.py98
-rw-r--r--module/plugins/PluginManager.py291
-rw-r--r--module/plugins/hooks/UpdateManager.py6
-rw-r--r--module/plugins/hoster/RapidshareCom.py2
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py9
9 files changed, 315 insertions, 238 deletions
diff --git a/module/plugins/AccountManager.py b/module/plugins/AccountManager.py
index fc521d36c..4f4d9f68d 100644
--- a/module/plugins/AccountManager.py
+++ b/module/plugins/AccountManager.py
@@ -22,7 +22,7 @@ from shutil import copy
from threading import Lock
-from module.PullEvents import AccountUpdateEvent
+from module.interaction.PullEvents import AccountUpdateEvent
from module.utils import chmod, lock
ACC_VERSION = 1
diff --git a/module/plugins/Base.py b/module/plugins/Base.py
new file mode 100644
index 000000000..5a78fddc3
--- /dev/null
+++ b/module/plugins/Base.py
@@ -0,0 +1,121 @@
+# -*- 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 <http://www.gnu.org/licenses/>.
+
+ @author: RaNaN
+"""
+
+# TODO: config format definition
+# more attributes if needed
+# get rid of catpcha & container plugins ?! (move to crypter & internals)
+# adapt old plugins as needed
+
+class Base(object):
+ """
+ The Base plugin class with all shared methods and every possible attribute for plugin definition.
+ """
+ __version__ = "0.1"
+ #: Regexp pattern which will be matched for download plugins
+ __pattern__ = r""
+ #: Flat config definition
+ __config__ = tuple()
+ #: Short description, one liner
+ __description__ = ""
+ #: More detailed text
+ __long_description__ = """"""
+ #: List of needed modules
+ __dependencies__ = tuple()
+ #: Tags to categorize the plugin
+ __tags__ = tuple()
+ #: Base64 encoded .png icon
+ __icon__ = ""
+ #: Alternative, link to png icon
+ __icon_url__ = ""
+ #: Url with general information/support/discussion
+ __url__ = ""
+ __author_name__ = tuple()
+ __author_mail__ = tuple()
+
+
+ def __init__(self, core):
+ self.__name__ = self.__class__.__name__
+
+ #: Core instance
+ self.core = core
+ #: logging instance
+ self.log = core.log
+ #: core config
+ self.config = core.config
+
+ #log functions
+ def logInfo(self, *args):
+ self.log.info("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
+
+ def logWarning(self, *args):
+ self.log.warning("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
+
+ def logError(self, *args):
+ self.log.error("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
+
+ def logDebug(self, *args):
+ self.log.debug("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
+
+
+ def setConf(self, option, value):
+ """ see `setConfig` """
+ self.core.config.set(self.__name__, option, value)
+
+ def setConfig(self, option, value):
+ """ Set config value for current plugin
+
+ :param option:
+ :param value:
+ :return:
+ """
+ self.setConf(option, value)
+
+ def getConf(self, option):
+ """ see `getConfig` """
+ return self.core.config.get(self.__name__, option)
+
+ def getConfig(self, option):
+ """ Returns config value for current plugin
+
+ :param option:
+ :return:
+ """
+ return self.getConf(option)
+
+ def setStorage(self, key, value):
+ """ Saves a value persistently to the database """
+ self.core.db.setStorage(self.__name__, key, value)
+
+ def store(self, key, value):
+ """ same as `setStorage` """
+ self.core.db.setStorage(self.__name__, key, value)
+
+ def getStorage(self, key=None, default=None):
+ """ Retrieves saved value or dict of all saved entries if key is None """
+ if key is not None:
+ return self.core.db.getStorage(self.__name__, key) or default
+ return self.core.db.getStorage(self.__name__, key)
+
+ def retrieve(self, *args, **kwargs):
+ """ same as `getStorage` """
+ return self.getStorage(*args, **kwargs)
+
+ def delStorage(self, key):
+ """ Delete entry in db """
+ self.core.db.delStorage(self.__name__, key)
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
index 5efd08bae..860dc76bb 100644
--- a/module/plugins/Hook.py
+++ b/module/plugins/Hook.py
@@ -119,7 +119,7 @@ class Hook(Base):
def isActivated(self):
""" checks if hook is activated"""
- return self.config.getPlugin(self.__name__, "activated")
+ return self.config.get(self.__name__, "activated")
#event methods - overwrite these if needed
diff --git a/module/plugins/Hoster.py b/module/plugins/Hoster.py
index 814a70949..aa50099fb 100644
--- a/module/plugins/Hoster.py
+++ b/module/plugins/Hoster.py
@@ -19,15 +19,15 @@
from module.plugins.Plugin import Plugin
-def getInfo(self):
- #result = [ .. (name, size, status, url) .. ]
- return
-
class Hoster(Plugin):
- __name__ = "Hoster"
- __version__ = "0.1"
- __pattern__ = None
- __type__ = "hoster"
- __description__ = """Base hoster plugin"""
- __author_name__ = ("mkaay")
- __author_mail__ = ("mkaay@mkaay.de")
+
+ @staticmethod
+ def getInfo(urls):
+ """This method is used to retrieve the online status of files for hoster plugins.
+ It has to *yield* list of tuples with the result in this format (name, size, status, url),
+ where status is one of API pyfile statusses.
+
+ :param urls: List of urls
+ :return:
+ """
+ pass \ No newline at end of file
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index f7587d3f2..327e717a0 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -29,17 +29,9 @@ if os.name != "nt":
from pwd import getpwnam
from grp import getgrnam
-from itertools import islice
-
-from module.utils import save_join, save_path, fs_encode
-
-def chunks(iterable, size):
- it = iter(iterable)
- item = list(islice(it, size))
- while item:
- yield item
- item = list(islice(it, size))
+from Base import Base
+from module.utils import save_join, save_path, fs_encode, chunks
class Abort(Exception):
""" raised when aborted """
@@ -61,95 +53,11 @@ class SkipDownload(Exception):
""" raised when download should be skipped """
-class Base(object):
- """
- A Base class with log/config/db methods *all* plugin types can use
- """
-
- def __init__(self, core):
- #: Core instance
- self.core = core
- #: logging instance
- self.log = core.log
- #: core config
- self.config = core.config
-
- #log functions
- def logInfo(self, *args):
- self.log.info("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
-
- def logWarning(self, *args):
- self.log.warning("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
-
- def logError(self, *args):
- self.log.error("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
-
- def logDebug(self, *args):
- self.log.debug("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args])))
-
-
- def setConf(self, option, value):
- """ see `setConfig` """
- self.core.config.setPlugin(self.__name__, option, value)
-
- def setConfig(self, option, value):
- """ Set config value for current plugin
-
- :param option:
- :param value:
- :return:
- """
- self.setConf(option, value)
-
- def getConf(self, option):
- """ see `getConfig` """
- return self.core.config.getPlugin(self.__name__, option)
-
- def getConfig(self, option):
- """ Returns config value for current plugin
-
- :param option:
- :return:
- """
- return self.getConf(option)
-
- def setStorage(self, key, value):
- """ Saves a value persistently to the database """
- self.core.db.setStorage(self.__name__, key, value)
-
- def store(self, key, value):
- """ same as `setStorage` """
- self.core.db.setStorage(self.__name__, key, value)
-
- def getStorage(self, key=None, default=None):
- """ Retrieves saved value or dict of all saved entries if key is None """
- if key is not None:
- return self.core.db.getStorage(self.__name__, key) or default
- return self.core.db.getStorage(self.__name__, key)
-
- def retrieve(self, *args, **kwargs):
- """ same as `getStorage` """
- return self.getStorage(*args, **kwargs)
-
- def delStorage(self, key):
- """ Delete entry in db """
- self.core.db.delStorage(self.__name__, key)
-
-
class Plugin(Base):
"""
Base plugin for hoster/crypter.
Overwrite `process` / `decrypt` in your subclassed plugin.
"""
- __name__ = "Plugin"
- __version__ = "0.4"
- __pattern__ = None
- __type__ = "hoster"
- __config__ = [("name", "type", "desc", "default")]
- __description__ = """Base Plugin"""
- __author_name__ = ("RaNaN", "spoob", "mkaay")
- __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org", "mkaay@mkaay.de")
-
def __init__(self, pyfile):
Base.__init__(self, pyfile.m.core)
@@ -350,7 +258,7 @@ class Plugin(Base):
temp_file.write(img)
temp_file.close()
- has_plugin = self.__name__ in self.core.pluginManager.captchaPlugins
+ has_plugin = self.__name__ in self.core.pluginManager.getPlugins("captcha")
if self.core.captcha:
Ocr = self.core.pluginManager.loadClass("captcha", self.__name__)
diff --git a/module/plugins/PluginManager.py b/module/plugins/PluginManager.py
index f3f5f47bc..9845590cf 100644
--- a/module/plugins/PluginManager.py
+++ b/module/plugins/PluginManager.py
@@ -21,24 +21,34 @@ 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 itertools import chain
+from time import time
from traceback import print_exc
from module.lib.SafeEval import const_eval as literal_eval
-from module.ConfigParser import IGNORE
+from module.plugins.Base import Base
+
+from new_collections import namedtuple
+
+# ignore these plugin configs, mainly because plugins were wiped out
+IGNORE = (
+ "FreakshareNet", "SpeedManager", "ArchiveTo", "ShareCx", ('hooks', 'UnRar'),
+ 'EasyShareCom', 'FlyshareCz'
+ )
+
+PluginTuple = namedtuple("PluginTuple", "version re deps user path")
class PluginManager:
ROOT = "module.plugins."
USERROOT = "userplugins."
TYPES = ("crypter", "container", "hoster", "captcha", "accounts", "hooks", "internal")
- PATTERN = re.compile(r'__pattern__.*=.*r("|\')([^"\']+)')
- VERSION = re.compile(r'__version__.*=.*("|\')([0-9.]+)')
- CONFIG = re.compile(r'__config__.*=.*\[([^\]]+)', re.MULTILINE)
- DESC = re.compile(r'__description__.?=.?("|"""|\')([^"\']+)')
+ 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)
def __init__(self, core):
self.core = core
@@ -47,15 +57,24 @@ class PluginManager:
self.log = core.log
self.plugins = {}
+ self.modules = {} # cached modules
+ self.names = {} # overwritten names
+ self.history = [] # match history to speedup parsing (type, name)
self.createIndex()
+
+ self.core.config.parseValues(self.core.config.PLUGIN)
+
#register for import hook
sys.meta_path.append(self)
+ def logDebug(self, type, plugin, msg):
+ self.log.debug("Plugin %s | %s: %s" % (type, plugin, msg))
+
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"):
@@ -64,27 +83,14 @@ class PluginManager:
f = open(join("userplugins", "__init__.py"), "wb")
f.close()
- self.plugins["crypter"] = self.crypterPlugins = self.parse("crypter", pattern=True)
- self.plugins["container"] = self.containerPlugins = self.parse("container", pattern=True)
- self.plugins["hoster"] = self.hosterPlugins = self.parse("hoster", pattern=True)
-
- self.plugins["captcha"] = self.captchaPlugins = self.parse("captcha")
- self.plugins["accounts"] = self.accountPlugins = self.parse("accounts")
- self.plugins["hooks"] = self.hookPlugins = self.parse("hooks")
- self.plugins["internal"] = self.internalPlugins = self.parse("internal")
+ a = time()
+ for type in self.TYPES:
+ self.plugins[type] = self.parse(type)
- self.log.debug("created index of plugins")
+ self.log.debug("Created index of plugins in %.2f ms", (time() - a) * 1000)
- def parse(self, folder, pattern=False, home={}):
- """
- returns dict with information
- home contains parsed plugins from module.
-
- {
- name : {path, version, config, (pattern, re), (plugin, class)}
- }
-
- """
+ def parse(self, folder, home=None):
+ """ Analyze and parses all plugins in folder """
plugins = {}
if home:
pfolder = join("userplugins", folder)
@@ -100,10 +106,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):
@@ -111,121 +113,149 @@ 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]
- version = self.VERSION.findall(content)
- if version:
- version = float(version[0][1])
- else:
- version = 0
+ 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]["v"] >= 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
- plugins[name] = {}
- plugins[name]["v"] = version
+ def parsePlugin(self, filename, folder, name, home=None):
+ """ Parses a plugin from disk, folder means plugin type in this context. Also sets config.
- module = f.replace(".pyc", "").replace(".py", "")
+ :arg home: dict with plugins, of which the found one will be matched against (according version)
+ :returns PluginTuple"""
- # the plugin is loaded from user directory
- plugins[name]["user"] = True if home else False
- plugins[name]["name"] = module
+ data = open(filename, "rb")
+ content = data.read()
+ data.close()
- if pattern:
- pattern = self.PATTERN.findall(content)
+ 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])
- if pattern:
- pattern = pattern[0][1]
- else:
- pattern = "^unmachtable$"
+ version = 0
- plugins[name]["pattern"] = pattern
+ 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")
- try:
- plugins[name]["re"] = re.compile(pattern)
- except:
- self.log.error(_("%s has a invalid pattern.") % name)
+ # home contains plugins from pyload root
+ if home and name in home:
+ if home[name].version >= version:
+ return
+ if name in IGNORE or (folder, name) in IGNORE:
+ return
- # internals have no config
- if folder == "internal":
- self.core.config.deleteConfig(name)
- continue
+ 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
- config = self.CONFIG.findall(content)
- if config:
- config = literal_eval(config[0].strip().replace("\n", "").replace("\r", ""))
- desc = self.DESC.findall(content)
- desc = desc[0][1] if desc else ""
+ deps = attrs.get("dependencies", None)
- if type(config[0]) == tuple:
- config = [list(x) for x in config]
- else:
- config = [list(config)]
+ # create plugin tuple
+ plugin = PluginTuple(version, plugin_re, deps, bool(home), filename)
- 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])
+ # internals have no config
+ if folder == "internal":
+ return plugin
- try:
- self.core.config.addPluginConfig(name, config, desc)
- except:
- self.log.error("Invalid config in %s: %s" % (name, config))
+ if folder == "hooks" and "config" not in attrs:
+ attrs["config"] = (["activated", "bool", "Activated", False],)
- elif folder == "hooks": #force config creation
- desc = self.DESC.findall(content)
- desc = desc[0][1] if desc else ""
- config = (["activated", "bool", "Activated", False],)
+ if "config" in attrs and attrs["config"]:
+ config = attrs["config"]
+ desc = attrs.get("description", "")
+ long_desc = attrs.get("long_description", "")
- try:
- self.core.config.addPluginConfig(name, config, desc)
- except:
- self.log.error("Invalid config in %s: %s" % (name, config))
+ if type(config[0]) == tuple:
+ config = [list(x) for x in config]
+ else:
+ config = [list(config)]
- if not home:
- temp = self.parse(folder, pattern, plugins)
- plugins.update(temp)
+ if folder == "hooks":
+ append = True
+ for item in config:
+ if item[0] == "activated": append = False
- return plugins
+ # activated flag missing
+ if append: config.insert(0, ("activated", "bool", "Activated", False))
+
+ try:
+ self.core.config.addConfigSection(name, name, desc, long_desc, config)
+ except:
+ self.logDebug(folder, name, "Invalid config %s" % config)
+
+ return plugin
def parseUrls(self, urls):
"""parse plugins for given list of urls"""
- last = None
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
- if last and last[1]["re"].match(url):
- res.append((url, last[0]))
+ for ptype, name in self.history:
+ if self.plugins[ptype][name].re.match(url):
+ res.append((url, name))
+ found = (ptype, name)
+
+ if found and self.history[0] != found:
+ # found match, update history
+ self.history.remove(found)
+ self.history.insert(0, found)
continue
- for name, value in chain(self.crypterPlugins.iteritems(), self.hosterPlugins.iteritems(),
- self.containerPlugins.iteritems()):
- if value["re"].match(url):
- res.append((url, name))
- last = (name, value)
- found = True
- break
+ for ptype in ("crypter", "hoster", "container"):
+ for name, plugin in self.plugins[ptype].iteritems():
+ if plugin.re.match(url):
+ res.append((url, name))
+ self.history.insert(0, (ptype, name))
+ del self.history[10:] # cut down to size of 10
+ found = True
+ break
if not found:
res.append((url, "BasePlugin"))
return res
+ def getPlugins(self, type):
+ # TODO clean this workaround
+ 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")):
for ptype in pluginlist:
if name in self.plugins[ptype]:
@@ -238,7 +268,7 @@ class PluginManager:
if not plugin:
self.log.warning("Plugin %s not found." % name)
- plugin = self.hosterPlugins["BasePlugin"]
+ plugin = self.plugins["hoster"]["BasePlugin"]
if "new_module" in plugin and not original:
return plugin["new_module"]
@@ -262,11 +292,12 @@ class PluginManager:
"""
plugins = self.plugins[type]
if name in plugins:
- if "module" in plugins[name]: return plugins[name]["module"]
+ if (type, name) in self.modules: return self.modules[(type, name)]
try:
- module = __import__(self.ROOT + "%s.%s" % (type, plugins[name]["name"]), globals(), locals(),
- plugins[name]["name"])
- plugins[name]["module"] = module #cache import, maybe unneeded
+ # 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, maybe unneeded
return module
except Exception, e:
self.log.error(_("Error importing %(name)s: %(msg)s") % {"name": name, "msg": str(e)})
@@ -280,7 +311,7 @@ class PluginManager:
def getAccountPlugins(self):
"""return list of account plugin names"""
- return self.accountPlugins.keys()
+ return self.plugins["accounts"].keys()
def find_module(self, fullname, path=None):
#redirecting imports if necesarry
@@ -294,10 +325,10 @@ class PluginManager:
if type in self.plugins and name in self.plugins[type]:
#userplugin is a newer version
- if not user and self.plugins[type][name]["user"]:
+ if not user and self.plugins[type][name].user:
return self
- #imported from userdir, but pyloads is newer
- if user and not self.plugins[type][name]["user"]:
+ #imported from userdir, but pyloads is newer
+ if user and not self.plugins[type][name].user:
return self
@@ -329,7 +360,7 @@ class PluginManager:
self.log.debug("Request reload of plugins: %s" % type_plugins)
as_dict = {}
- for t,n in type_plugins:
+ for t, n in type_plugins:
if t in as_dict:
as_dict[t].append(n)
else:
@@ -342,16 +373,13 @@ class PluginManager:
for type in as_dict.iterkeys():
for plugin in as_dict[type]:
if plugin in self.plugins[type]:
- if "module" in self.plugins[type][plugin]:
+ if (type, plugin) in self.modules:
self.log.debug("Reloading %s" % plugin)
- reload(self.plugins[type][plugin]["module"])
+ reload(self.modules[(type, plugin)])
- #index creation
- self.plugins["crypter"] = self.crypterPlugins = self.parse("crypter", pattern=True)
- self.plugins["container"] = self.containerPlugins = self.parse("container", pattern=True)
- self.plugins["hoster"] = self.hosterPlugins = self.parse("hoster", pattern=True)
- self.plugins["captcha"] = self.captchaPlugins = self.parse("captcha")
- self.plugins["accounts"] = self.accountPlugins = self.parse("accounts")
+ # index re-creation
+ for type in ("crypter", "container", "hoster", "captcha", "accounts"):
+ self.plugins[type] = self.parse(type)
if "accounts" in as_dict: #accounts needs to be reloaded
self.core.accountManager.initPlugins()
@@ -359,6 +387,23 @@ 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__":
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index 920a88060..4324a96ba 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -24,7 +24,7 @@ from os import stat
from os.path import join, exists
from time import time
-from module.ConfigParser import IGNORE
+from module.plugins.PluginManager import IGNORE
from module.network.RequestFactory import getURL
from module.plugins.Hook import threaded, Expose, Hook
@@ -129,10 +129,10 @@ class UpdateManager(Hook):
else:
type = prefix
- plugins = getattr(self.core.pluginManager, "%sPlugins" % type)
+ plugins = self.core.pluginManager.getPlugins(type)
if name in plugins:
- if float(plugins[name]["v"]) >= float(version):
+ if float(plugins[name].version) >= float(version):
continue
if name in IGNORE or (type, name) in IGNORE:
diff --git a/module/plugins/hoster/RapidshareCom.py b/module/plugins/hoster/RapidshareCom.py
index 0d927c525..f3011a488 100644
--- a/module/plugins/hoster/RapidshareCom.py
+++ b/module/plugins/hoster/RapidshareCom.py
@@ -52,7 +52,7 @@ class RapidshareCom(Hoster):
__pattern__ = r"https?://[\w\.]*?rapidshare.com/(?:files/(?P<id>\d*?)/(?P<name>[^?]+)|#!download\|(?:\w+)\|(?P<id_new>\d+)\|(?P<name_new>[^|]+))"
__version__ = "1.37"
__description__ = """Rapidshare.com Download Hoster"""
- __config__ = [["server", "Cogent;Deutsche Telekom;Level(3);Level(3) #2;GlobalCrossing;Level(3) #3;Teleglobe;GlobalCrossing #2;TeliaSonera #2;Teleglobe #2;TeliaSonera #3;TeliaSonera", "Preferred Server", "None"]]
+ __config__ = [("server", "Cogent;Deutsche Telekom;Level(3);Level(3) #2;GlobalCrossing;Level(3) #3;Teleglobe;GlobalCrossing #2;TeliaSonera #2;Teleglobe #2;TeliaSonera #3;TeliaSonera", "Preferred Server", "None")]
__author_name__ = ("spoob", "RaNaN", "mkaay")
__author_mail__ = ("spoob@pyload.org", "ranan@pyload.org", "mkaay@mkaay.de")
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 2a6645e86..ab7f5b249 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -13,7 +13,7 @@ from module.plugins.Plugin import chunks
def getInfo(urls):
- api_url_base = "http://www.share-online.biz/linkcheck/linkcheck.php"
+ api_url_base = "http://api.share-online.biz/linkcheck.php"
for chunk in chunks(urls, 90):
api_param_file = {"links": "\n".join(x.replace("http://www.share-online.biz/dl/","").rstrip("/") for x in chunk)} #api only supports old style links
@@ -67,7 +67,7 @@ class ShareonlineBiz(Hoster):
self.handleFree()
def downloadAPIData(self):
- api_url_base = "http://www.share-online.biz/linkcheck/linkcheck.php?md5=1"
+ api_url_base = "http://api.share-online.biz/linkcheck.php?md5=1"
api_param_file = {"links": self.pyfile.url.replace("http://www.share-online.biz/dl/","")} #api only supports old style links
src = self.load(api_url_base, cookies=False, post=api_param_file)
@@ -116,9 +116,12 @@ class ShareonlineBiz(Hoster):
self.download(download_url)
- check = self.checkDownload({"invalid" : "Dieses Download-Ticket ist ungültig!"})
+ check = self.checkDownload({"invalid" : "Dieses Download-Ticket ist ungültig!",
+ "error" : "Es ist ein unbekannter Fehler aufgetreten"})
if check == "invalid":
self.retry(reason=_("Invalid download ticket"))
+ elif check == "error":
+ self.fail(reason=_("ShareOnline internal problems"))
def handleAPIPremium(self): #should be working better