summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/AccountManager.py20
-rw-r--r--module/plugins/Crypter.py16
-rw-r--r--module/plugins/Hook.py6
-rw-r--r--module/plugins/OCR.py (renamed from module/plugins/captcha/captcha.py)40
-rw-r--r--module/plugins/Plugin.py89
-rw-r--r--module/plugins/PluginManager.py66
-rw-r--r--module/plugins/README.md16
-rw-r--r--module/plugins/ReCaptcha.py24
-rw-r--r--module/plugins/accounts/Ftp.py2
-rw-r--r--module/plugins/accounts/Http.py2
-rw-r--r--module/plugins/internal/MultiHoster.py11
-rw-r--r--module/plugins/ocr/GigasizeCom.py (renamed from module/plugins/captcha/GigasizeCom.py)2
-rw-r--r--module/plugins/ocr/LinksaveIn.py (renamed from module/plugins/captcha/LinksaveIn.py)5
-rw-r--r--module/plugins/ocr/NetloadIn.py (renamed from module/plugins/captcha/NetloadIn.py)3
-rw-r--r--module/plugins/ocr/ShareonlineBiz.py (renamed from module/plugins/captcha/ShareonlineBiz.py)2
-rw-r--r--module/plugins/ocr/__init__.py (renamed from module/plugins/captcha/__init__.py)0
16 files changed, 160 insertions, 144 deletions
diff --git a/module/plugins/AccountManager.py b/module/plugins/AccountManager.py
index 4b8063002..6c908738c 100644
--- a/module/plugins/AccountManager.py
+++ b/module/plugins/AccountManager.py
@@ -11,10 +11,10 @@ from module.utils import chmod, lock
ACC_VERSION = 1
-class AccountManager():
+class AccountManager:
"""manages all accounts"""
- #----------------------------------------------------------------------
+ #--------------------------------------------------------------------------
def __init__(self, core):
"""Constructor"""
@@ -35,7 +35,10 @@ class AccountManager():
"""get account instance for plugin or None if anonymous"""
if plugin in self.accounts:
if plugin not in self.plugins:
- self.plugins[plugin] = self.core.pluginManager.loadClass("accounts", plugin)(self, self.accounts[plugin])
+ try:
+ self.plugins[plugin] = self.core.pluginManager.loadClass("accounts", plugin)(self, self.accounts[plugin])
+ except TypeError: # The account class no longer exists (blacklisted plugin). Skipping the account to avoid crash
+ return None
return self.plugins[plugin]
else:
@@ -50,7 +53,7 @@ class AccountManager():
return plugins
- #----------------------------------------------------------------------
+ #--------------------------------------------------------------------------
def loadAccounts(self):
"""loads all accounts available"""
@@ -97,7 +100,7 @@ class AccountManager():
name, sep, pw = line.partition(":")
self.accounts[plugin][name] = {"password": pw, "options": {}, "valid": True}
- #----------------------------------------------------------------------
+ #--------------------------------------------------------------------------
def saveAccounts(self):
"""save all account information"""
@@ -117,7 +120,7 @@ class AccountManager():
f.close()
chmod(f.name, 0600)
- #----------------------------------------------------------------------
+ #--------------------------------------------------------------------------
def initAccountPlugins(self):
"""init names"""
for name in self.core.pluginManager.getAccountPlugins():
@@ -155,7 +158,10 @@ class AccountManager():
for p in self.accounts.keys():
if self.accounts[p]:
p = self.getAccountPlugin(p)
- data[p.__name__] = p.getAllAccounts(force)
+ if p:
+ data[p.__name__] = p.getAllAccounts(force)
+ else: # When an account has been skipped, p is None
+ data[p] = []
else:
data[p] = []
e = AccountUpdateEvent()
diff --git a/module/plugins/Crypter.py b/module/plugins/Crypter.py
index 74ae8d102..b127777e7 100644
--- a/module/plugins/Crypter.py
+++ b/module/plugins/Crypter.py
@@ -45,14 +45,20 @@ class Crypter(Plugin):
""" create new packages from self.packages """
for pack in self.packages:
- self.log.debug("Parsed package %(name)s with %(len)d links" % { "name" : pack[0], "len" : len(pack[1]) } )
+ name, links, folder = pack
- links = [x.decode("utf-8") for x in pack[1]]
+ self.logDebug("Parsed package %(name)s with %(len)d links" % {"name": name, "len": len(links)})
- pid = self.core.api.addPackage(pack[0], links, self.pyfile.package().queue)
+ links = [x.decode("utf-8") for x in links]
+
+ pid = self.api.addPackage(name, links, self.pyfile.package().queue)
+
+ if name != folder is not None:
+ self.api.setPackageData(pid, {"folder": folder}) #: Due to not break API addPackage method right now
+ self.logDebug("Set package %(name)s folder to %(folder)s" % {"name": name, "folder": folder})
if self.pyfile.package().password:
- self.core.api.setPackageData(pid, {"password": self.pyfile.package().password})
+ self.api.setPackageData(pid, {"password": self.pyfile.package().password})
if self.urls:
- self.core.api.generateAndAddPackages(self.urls)
+ self.api.generateAndAddPackages(self.urls)
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
index 279f813d1..e72ab7ebb 100644
--- a/module/plugins/Hook.py
+++ b/module/plugins/Hook.py
@@ -28,7 +28,6 @@ class Hook(Base):
__type__ = "hook"
__version__ = "0.2"
- __threaded__ = []
__config__ = [("name", "type", "desc", "default")]
__description__ = """Interface for hook"""
@@ -76,8 +75,9 @@ class Hook(Base):
self.event_list = None
- self.initPeriodical()
self.setup()
+ self.initPeriodical()
+
def initPeriodical(self):
if self.interval >=1:
@@ -87,7 +87,7 @@ class Hook(Base):
try:
if self.isActivated(): self.periodical()
except Exception, e:
- self.core.log.error(_("Error executing hooks: %s") % str(e))
+ self.logError(_("Error executing hooks: %s") % str(e))
if self.core.debug:
print_exc()
diff --git a/module/plugins/captcha/captcha.py b/module/plugins/OCR.py
index cc07f50cf..0991184f3 100644
--- a/module/plugins/captcha/captcha.py
+++ b/module/plugins/OCR.py
@@ -1,18 +1,16 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
-
-import GifImagePlugin
-import Image
-import JpegImagePlugin
-import PngImagePlugin
-import TiffImagePlugin
-import logging
import os
+import logging
import subprocess
-#import tempfile
from os.path import abspath, join
+from PIL import Image
+from PIL import TiffImagePlugin
+from PIL import PngImagePlugin
+from PIL import GifImagePlugin
+from PIL import JpegImagePlugin
class OCR(object):
@@ -43,16 +41,15 @@ class OCR(object):
def run(self, command):
"""Run a command"""
- popen = subprocess.Popen(command, bufsize = -1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ popen = subprocess.Popen(command, bufsize=-1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
popen.wait()
- output = popen.stdout.read() +" | "+ popen.stderr.read()
+ output = popen.stdout.read() + " | " + popen.stderr.read()
popen.stdout.close()
popen.stderr.close()
self.logger.debug("Tesseract ReturnCode %s Output: %s" % (popen.returncode, output))
def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True):
#self.logger.debug("create tmp tif")
-
#tmp = tempfile.NamedTemporaryFile(suffix=".tif")
tmp = open(join("tmp", "tmpTif_%s.tif" % self.__name__), "wb")
tmp.close()
@@ -67,9 +64,9 @@ class OCR(object):
if os.name == "nt":
tessparams = [join(pypath, "tesseract", "tesseract.exe")]
else:
- tessparams = ["tesseract"]
+ tessparams = ['tesseract']
- tessparams.extend( [abspath(tmp.name), abspath(tmpTxt.name).replace(".txt", "")] )
+ tessparams.extend([abspath(tmp.name), abspath(tmpTxt.name).replace(".txt", "")])
if subset and (digits or lowercase or uppercase):
#self.logger.debug("create temp subset config")
@@ -138,11 +135,11 @@ class OCR(object):
count = 0
try:
- if pixels[x-1, y-1] != 255:
+ if pixels[x - 1, y - 1] != 255:
count += 1
- if pixels[x-1, y] != 255:
+ if pixels[x - 1, y] != 255:
count += 1
- if pixels[x-1, y + 1] != 255:
+ if pixels[x - 1, y + 1] != 255:
count += 1
if pixels[x, y + 1] != 255:
count += 1
@@ -150,19 +147,19 @@ class OCR(object):
count += 1
if pixels[x + 1, y] != 255:
count += 1
- if pixels[x + 1, y-1] != 255:
+ if pixels[x + 1, y - 1] != 255:
count += 1
- if pixels[x, y-1] != 255:
+ if pixels[x, y - 1] != 255:
count += 1
except:
pass
- # not enough neighbors are dark pixels so mark this pixel
- # to be changed to white
+ # not enough neighbors are dark pixels so mark this pixel
+ # to be changed to white
if count < allowed:
pixels[x, y] = 1
- # second pass: this time set all 1's to 255 (white)
+ # second pass: this time set all 1's to 255 (white)
for x in xrange(w):
for y in xrange(h):
if pixels[x, y] == 1:
@@ -197,7 +194,6 @@ class OCR(object):
if pixels[x, y] == 0:
pixels[x, y] = 255
-
count = {}
for x in xrange(w):
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 68b2311b3..8a2554ea0 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -14,8 +14,7 @@ if os.name != "nt":
from itertools import islice
-from module.utils import save_join, save_path, fs_encode, fs_decode
-
+from module.utils import safe_join, safe_path, fs_encode, fs_decode
def chunks(iterable, size):
it = iter(iterable)
@@ -74,7 +73,7 @@ class Base(object):
def setConf(self, option, value):
""" see `setConfig` """
- self.core.config.setPlugin(self.__name__, option, value)
+ self.config.setPlugin(self.__name__, option, value)
def setConfig(self, option, value):
""" Set config value for current plugin
@@ -85,9 +84,10 @@ class Base(object):
"""
self.setConf(option, value)
+ #: Deprecated method
def getConf(self, option):
""" see `getConfig` """
- return self.core.config.getPlugin(self.__name__, option)
+ return self.getConfig(option)
def getConfig(self, option):
""" Returns config value for current plugin
@@ -95,7 +95,7 @@ class Base(object):
:param option:
:return:
"""
- return self.getConf(option)
+ return self.config.getPlugin(self.__name__, option)
def setStorage(self, key, value):
""" Saves a value persistently to the database """
@@ -127,7 +127,7 @@ class Plugin(Base):
"""
__name__ = "Plugin"
__type__ = "hoster"
- __version__ = "0.4"
+ __version__ = "0.5"
__pattern__ = None
__config__ = [("name", "type", "desc", "default")]
@@ -140,10 +140,13 @@ class Plugin(Base):
def __init__(self, pyfile):
Base.__init__(self, pyfile.m.core)
+ #: engage wan reconnection
self.wantReconnect = False
- #: enables simultaneous processing of multiple downloads
+
+ #: enable simultaneous processing of multiple downloads
self.multiDL = True
self.limitDL = 0
+
#: chunk limit
self.chunkLimit = 1
self.resumeDownload = False
@@ -152,7 +155,9 @@ class Plugin(Base):
self.waitUntil = 0
self.waiting = False
- self.ocr = None #captcha reader instance
+ #: captcha reader instance
+ self.ocr = None
+
#: account handler instance, see :py:class:`Account`
self.account = pyfile.m.core.accountManager.getAccountPlugin(self.__name__)
@@ -161,7 +166,9 @@ class Plugin(Base):
#: username/login
self.user = None
- if self.account and not self.account.canUse(): self.account = None
+ if self.account and not self.account.canUse():
+ self.account = None
+
if self.account:
self.user, data = self.account.selectAccount()
#: Browser instance, see `network.Browser`
@@ -177,18 +184,28 @@ class Plugin(Base):
#: associated pyfile instance, see `PyFile`
self.pyfile = pyfile
+
self.thread = None # holds thread in future
#: location where the last call to download was saved
self.lastDownload = ""
#: re match of the last call to `checkDownload`
self.lastCheck = None
+
#: js engine, see `JsEngine`
self.js = self.core.js
- self.cTask = None #captcha task
- self.retries = 0 # amount of retries already made
- self.html = None # some plugins store html code here
+ #: captcha task
+ self.cTask = None
+
+ #: amount of retries already made
+ self.retries = 0
+
+ #: some plugins store html code here
+ self.html = None
+
+ #: quick caller for API
+ self.api = self.core.api
self.init()
@@ -248,7 +265,7 @@ class Plugin(Base):
return True, 10
- def setWait(self, seconds, reconnect=False):
+ def setWait(self, seconds, reconnect=None):
"""Set a specific wait time later used with `wait`
:param seconds: wait time in seconds
@@ -258,15 +275,23 @@ class Plugin(Base):
self.wantReconnect = True
self.pyfile.waitUntil = time() + int(seconds)
- def wait(self):
- """ waits the time previously set """
+ def wait(self, seconds=None, reconnect=None):
+ """ Waits the time previously set or use these from arguments. See `setWait`
+ """
+ if seconds:
+ self.setWait(seconds, reconnect)
+
+ self._wait()
+
+ def _wait(self):
self.waiting = True
self.pyfile.setStatus("waiting")
while self.pyfile.waitUntil > time():
self.thread.m.reconnecting.wait(2)
- if self.pyfile.abort: raise Abort
+ if self.pyfile.abort:
+ raise Abort
if self.thread.m.reconnecting.isSet():
self.waiting = False
self.wantReconnect = False
@@ -372,7 +397,7 @@ class Plugin(Base):
self.fail(_("No captcha result obtained in appropiate time by any of the plugins."))
result = task.result
- self.log.debug("Received captcha result: %s" % str(result))
+ self.logDebug("Received captcha result: %s" % str(result))
if not self.core.debug:
try:
@@ -462,23 +487,23 @@ class Plugin(Base):
download_folder = self.config['general']['download_folder']
- location = save_join(download_folder, self.pyfile.package().folder)
+ location = safe_join(download_folder, self.pyfile.package().folder)
if not exists(location):
- makedirs(location, int(self.core.config['permission']['folder'], 8))
+ makedirs(location, int(self.config['permission']['folder'], 8))
- if self.core.config['permission']['change_dl'] and os.name != "nt":
+ if self.config['permission']['change_dl'] and os.name != "nt":
try:
uid = getpwnam(self.config['permission']['user'])[2]
gid = getgrnam(self.config['permission']['group'])[2]
chown(location, uid, gid)
except Exception, e:
- self.log.warning(_("Setting User and Group failed: %s") % str(e))
+ self.logWarning(_("Setting User and Group failed: %s") % str(e))
# convert back to unicode
location = fs_decode(location)
- name = save_path(self.pyfile.name)
+ name = safe_path(self.pyfile.name)
filename = join(location, name)
@@ -492,23 +517,23 @@ class Plugin(Base):
self.pyfile.size = self.req.size
if disposition and newname and newname != name: #triple check, just to be sure
- self.log.info("%(name)s saved as %(newname)s" % {"name": name, "newname": newname})
+ self.logInfo("%(name)s saved as %(newname)s" % {"name": name, "newname": newname})
self.pyfile.name = newname
filename = join(location, newname)
fs_filename = fs_encode(filename)
- if self.core.config['permission']['change_file']:
- chmod(fs_filename, int(self.core.config['permission']['file'], 8))
+ if self.config['permission']['change_file']:
+ chmod(fs_filename, int(self.config['permission']['file'], 8))
- if self.core.config['permission']['change_dl'] and os.name != "nt":
+ if self.config['permission']['change_dl'] and os.name != "nt":
try:
uid = getpwnam(self.config['permission']['user'])[2]
gid = getgrnam(self.config['permission']['group'])[2]
chown(fs_filename, uid, gid)
except Exception, e:
- self.log.warning(_("Setting User and Group failed: %s") % str(e))
+ self.logWarning(_("Setting User and Group failed: %s") % str(e))
self.lastDownload = filename
return self.lastDownload
@@ -531,12 +556,12 @@ class Plugin(Base):
if api_size and api_size <= size: return None
elif size > max_size and not read_size: return None
- self.log.debug("Download Check triggered")
+ self.logDebug("Download Check triggered")
f = open(lastDownload, "rb")
content = f.read(read_size if read_size else -1)
f.close()
#produces encoding errors, better log to other file in the future?
- #self.log.debug("Content: %s" % content)
+ #self.logDebug("Content: %s" % content)
for name, rule in rules.iteritems():
if type(rule) in (str, unicode):
if rule in content:
@@ -577,9 +602,9 @@ class Plugin(Base):
raise SkipDownload(pyfile.pluginname)
download_folder = self.config['general']['download_folder']
- location = save_join(download_folder, pack.folder, self.pyfile.name)
+ location = safe_join(download_folder, pack.folder, self.pyfile.name)
- if starting and self.core.config['download']['skip_existing'] and exists(location):
+ if starting and self.config['download']['skip_existing'] and exists(location):
size = os.stat(location).st_size
if size >= self.pyfile.size:
raise SkipDownload("File exists.")
@@ -589,7 +614,7 @@ class Plugin(Base):
if exists(location):
raise SkipDownload(pyfile[0])
- self.log.debug("File %s not skipped, because it does not exists." % self.pyfile.name)
+ self.logDebug("File %s not skipped, because it does not exists." % self.pyfile.name)
def clean(self):
""" clean everything and remove references """
diff --git a/module/plugins/PluginManager.py b/module/plugins/PluginManager.py
index 9c7cab64c..32ea4d16b 100644
--- a/module/plugins/PluginManager.py
+++ b/module/plugins/PluginManager.py
@@ -17,7 +17,7 @@ from module.ConfigParser import IGNORE
class PluginManager:
ROOT = "module.plugins."
USERROOT = "userplugins."
- TYPES = ("crypter", "container", "hoster", "captcha", "accounts", "hooks", "internal")
+ TYPES = ("accounts", "container", "crypter", "hooks", "hoster", "internal", "ocr")
PATTERN = re.compile(r'__pattern__.*=.*r("|\')([^"\']+)')
VERSION = re.compile(r'__version__.*=.*("|\')([0-9.]+)')
@@ -28,7 +28,7 @@ class PluginManager:
def __init__(self, core):
self.core = core
- #self.config = self.core.config
+ self.config = core.config
self.log = core.log
self.plugins = {}
@@ -53,7 +53,7 @@ class PluginManager:
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['ocr'] = self.captchaPlugins = self.parse("ocr")
self.plugins['accounts'] = self.accountPlugins = self.parse("accounts")
self.plugins['hooks'] = self.hookPlugins = self.parse("hooks")
self.plugins['internal'] = self.internalPlugins = self.parse("internal")
@@ -140,7 +140,7 @@ class PluginManager:
# internals have no config
if folder == "internal":
- self.core.config.deleteConfig(name)
+ self.config.deleteConfig(name)
continue
config = self.CONFIG.findall(content)
@@ -163,7 +163,7 @@ class PluginManager:
if append: config.append(["activated", "bool", "Activated", False])
try:
- self.core.config.addPluginConfig(name, config, desc)
+ self.config.addPluginConfig(name, config, desc)
except:
self.log.error("Invalid config in %s: %s" % (name, config))
@@ -173,7 +173,7 @@ class PluginManager:
config = (["activated", "bool", "Activated", False],)
try:
- self.core.config.addPluginConfig(name, config, desc)
+ self.config.addPluginConfig(name, config, desc)
except:
self.log.error("Invalid config in %s: %s" % (name, config))
@@ -308,57 +308,49 @@ class PluginManager:
def reloadPlugins(self, type_plugins):
- """ reloads and reindexes plugins """
- if not type_plugins: return False
+ """ reload and reindex plugins """
+ if not type_plugins:
+ return None
self.log.debug("Request reload of plugins: %s" % type_plugins)
+ reloaded = []
+
as_dict = {}
for t,n in type_plugins:
- if t in as_dict:
+ if t in ("hooks", "internal"): #: do not reload hooks or internals, because would cause to much side effects
+ continue
+ elif t in as_dict:
as_dict[t].append(n)
else:
as_dict[t] = [n]
- # we do not reload hooks or internals, would cause to much side effects
- if "hooks" in as_dict or "internal" in as_dict:
- return False
-
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]:
- self.log.debug("Reloading %s" % plugin)
+ if plugin in self.plugins[type] and "module" in self.plugins[type][plugin]:
+ self.log.debug("Reloading %s" % plugin)
+ id = (type, plugin)
+ try:
reload(self.plugins[type][plugin]['module'])
+ except Exception, e:
+ self.log.error("Error when reloading %s" % id, str(e))
+ continue
+ else:
+ reloaded.append(id)
#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['ocr'] = self.captchaPlugins = self.parse("ocr")
self.plugins['accounts'] = self.accountPlugins = self.parse("accounts")
- if "accounts" in as_dict: #accounts needs to be reloaded
+ if "accounts" in as_dict: #: accounts needs to be reloaded
self.core.accountManager.initPlugins()
self.core.scheduler.addJob(0, self.core.accountManager.getAccountInfos)
- return True
-
-
-
-if __name__ == "__main__":
- _ = lambda x: x
- pypath = "/home/christian/Projekte/pyload-0.4/module/plugins"
-
- from time import time
-
- p = PluginManager(None)
-
- a = time()
-
- test = ["http://www.youtube.com/watch?v=%s" % x for x in xrange(0, 100)]
- print p.parseUrls(test)
-
- b = time()
+ return reloaded #: return a list of the plugins successfully reloaded
- print b - a, "s"
+ def reloadPlugin(self, type_plugin):
+ """ reload and reindex ONE plugin """
+ return True if self.reloadPlugins(type_plugin) else False
diff --git a/module/plugins/README.md b/module/plugins/README.md
new file mode 100644
index 000000000..fa2a4c5b2
--- /dev/null
+++ b/module/plugins/README.md
@@ -0,0 +1,16 @@
+Licensing
+---------
+
+According to the terms of the GNU General Public License,
+pyload's plugins must be treated as an extension of the main program.
+This means the plugins must be released under the GPL or a GPL-compatible
+free software license, and that the terms of the GPL must be followed when
+those plugins are distributed.
+
+ * Any plugin published **without a license notice** is intend published under the **GNU GPLv3**.
+ * A different license can be used but it **must be GPL-compatible** and the license notice must be put in the plugin
+ file.
+ * Any plugin published **with a GPL incompatible license** will be rejected.
+ This includes *copyright all right reserved*.
+ * Is recommended to put the license notice at the top of the plugin file.
+ * Is recommended to **not** put the license notice when plugin is published under the GNU GPLv3.
diff --git a/module/plugins/ReCaptcha.py b/module/plugins/ReCaptcha.py
deleted file mode 100644
index 143ecfb83..000000000
--- a/module/plugins/ReCaptcha.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import re
-
-
-class ReCaptcha():
-
- def __init__(self, plugin):
- self.plugin = plugin
-
- def challenge(self, id):
- js = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", get={"k":id}, cookies=True)
-
- try:
- challenge = re.search("challenge : '(.*?)',", js).group(1)
- server = re.search("server : '(.*?)',", js).group(1)
- except:
- self.plugin.fail("recaptcha error")
- result = self.result(server,challenge)
-
- return challenge, result
-
- def result(self, server, challenge):
- return self.plugin.decryptCaptcha("%simage"%server, get={"c":challenge}, cookies=True, imgtype="jpg")
diff --git a/module/plugins/accounts/Ftp.py b/module/plugins/accounts/Ftp.py
index 2e60874a9..1319ea2a7 100644
--- a/module/plugins/accounts/Ftp.py
+++ b/module/plugins/accounts/Ftp.py
@@ -13,4 +13,4 @@ class Ftp(Account):
__author_mail__ = "zoidberg@mujmail.cz"
- login_timeout = info_threshold = 1000000
+ login_timeout = info_threshold = -1 #: Unlimited
diff --git a/module/plugins/accounts/Http.py b/module/plugins/accounts/Http.py
index 3b64fe8da..589a45617 100644
--- a/module/plugins/accounts/Http.py
+++ b/module/plugins/accounts/Http.py
@@ -13,4 +13,4 @@ class Http(Account):
__author_mail__ = "zoidberg@mujmail.cz"
- login_timeout = info_threshold = 1000000
+ login_timeout = info_threshold = -1 #: Unlimited
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py
index f6d202ee9..6bcad293c 100644
--- a/module/plugins/internal/MultiHoster.py
+++ b/module/plugins/internal/MultiHoster.py
@@ -7,8 +7,9 @@ from module.utils import remove_chars
class MultiHoster(Hook):
- __name__ = "AbtractExtractor"
- __version__ = "0.19"
+ __name__ = "MultiHoster"
+ __type__ = "hook"
+ __version__ = "0.20"
__description__ = """Generic MultiHoster plugin"""
__author_name__ = "pyLoad Team"
@@ -28,15 +29,15 @@ class MultiHoster(Hook):
self.new_supported = []
def getConfig(self, option, default=''):
- """getConfig with default value - sublass may not implements all config options"""
+ """getConfig with default value - subclass may not implements all config options"""
try:
- return self.getConf(option)
+ # Fixed loop due to getConf deprecation in 0.4.10
+ return super(MultiHoster, self).getConfig(option)
except KeyError:
return default
def getHosterCached(self):
if not self.hosters:
-
try:
hosterSet = self.toHosterSet(self.getHoster()) - set(self.ignored)
except Exception, e:
diff --git a/module/plugins/captcha/GigasizeCom.py b/module/plugins/ocr/GigasizeCom.py
index add3ffc57..ba0b805e6 100644
--- a/module/plugins/captcha/GigasizeCom.py
+++ b/module/plugins/ocr/GigasizeCom.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha import OCR
+from module.plugins.OCR import OCR
class GigasizeCom(OCR):
diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/ocr/LinksaveIn.py
index dd5ac7b98..3ae139a4e 100644
--- a/module/plugins/captcha/LinksaveIn.py
+++ b/module/plugins/ocr/LinksaveIn.py
@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
+from module.plugins.OCR import OCR
from PIL import Image
-from glob import glob
from os import sep
from os.path import abspath, dirname
-
-from module.plugins.captcha import OCR
+from glob import glob
class LinksaveIn(OCR):
diff --git a/module/plugins/captcha/NetloadIn.py b/module/plugins/ocr/NetloadIn.py
index cb6cb9264..0de88302e 100644
--- a/module/plugins/captcha/NetloadIn.py
+++ b/module/plugins/ocr/NetloadIn.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha import OCR
-
+from module.plugins.OCR import OCR
class NetloadIn(OCR):
__name__ = "NetloadIn"
diff --git a/module/plugins/captcha/ShareonlineBiz.py b/module/plugins/ocr/ShareonlineBiz.py
index aab4e9da0..0ad018bf9 100644
--- a/module/plugins/captcha/ShareonlineBiz.py
+++ b/module/plugins/ocr/ShareonlineBiz.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha import OCR
+from module.plugins.OCR import OCR
class ShareonlineBiz(OCR):
diff --git a/module/plugins/captcha/__init__.py b/module/plugins/ocr/__init__.py
index e69de29bb..e69de29bb 100644
--- a/module/plugins/captcha/__init__.py
+++ b/module/plugins/ocr/__init__.py