diff options
author | Walter Purcaro <vuolter@users.noreply.github.com> | 2015-03-26 18:15:41 +0100 |
---|---|---|
committer | Walter Purcaro <vuolter@users.noreply.github.com> | 2015-03-26 18:15:41 +0100 |
commit | 181ab47c5f775b8b48569361da6b88a801784a30 (patch) | |
tree | f5f6d1d6b75b7f21b89b33733c3536e5ca80e087 | |
parent | Merge branch 'stable' into 0.4.10 (diff) | |
download | pyload-181ab47c5f775b8b48569361da6b88a801784a30.tar.xz |
Cleanup
56 files changed, 141 insertions, 1128 deletions
diff --git a/module/plugins/accounts/Keep2ShareCc.py b/module/plugins/accounts/Keep2ShareCc.py deleted file mode 100644 index d2ba1d237..000000000 --- a/module/plugins/accounts/Keep2ShareCc.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from module.plugins.Account import Account - - -class Keep2ShareCc(Account): - __name__ = "Keep2ShareCc" - __type__ = "account" - __version__ = "0.05" - - __description__ = """Keep2Share.cc account plugin""" - __license__ = "GPLv3" - __authors__ = [("aeronaut", "aeronaut@pianoguy.de"), - ("Walter Purcaro", "vuolter@gmail.com")] - - - VALID_UNTIL_PATTERN = r'Premium expires:\s*<b>(.+?)<' - TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*<b><a href="/user/statistic.html">(.+?)<' - - LOGIN_FAIL_PATTERN = r'Please fix the following input errors' - - - def loadAccountInfo(self, user, req): - validuntil = None - trafficleft = -1 - premium = False - - html = req.load("http://keep2share.cc/site/profile.html", decode=True) - - m = re.search(self.VALID_UNTIL_PATTERN, html) - if m: - expiredate = m.group(1).strip() - self.logDebug("Expire date: " + expiredate) - - if expiredate == "LifeTime": - premium = True - validuntil = -1 - else: - try: - validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d")) - - except Exception, e: - self.logError(e) - - else: - premium = True if validuntil > time.mktime(time.gmtime()) else False - - m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: - try: - trafficleft = self.parseTraffic(m.group(1)) - - except Exception, e: - self.logError(e) - - return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} - - - def login(self, user, data, req): - req.cj.setCookie("keep2share.cc", "lang", "en") - - html = req.load("http://keep2share.cc/login.html", - post={'LoginForm[username]' : user, - 'LoginForm[password]' : data['password'], - 'LoginForm[rememberMe]': 1, - 'yt0' : ""}, - decode=True) - - if re.search(self.LOGIN_FAIL_PATTERN, html): - self.wrongPassword() diff --git a/module/plugins/captcha/OCR.py b/module/plugins/captcha/OCR.py deleted file mode 100644 index 1874ba07d..000000000 --- a/module/plugins/captcha/OCR.py +++ /dev/null @@ -1,319 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -try: - from PIL import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin - -except ImportError: - import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin - -import logging -import os -import subprocess -#import tempfile - -from module.utils import save_join - - -class OCR(object): - __name__ = "OCR" - __type__ = "ocr" - __version__ = "0.11" - - __description__ = """OCR base plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - def __init__(self): - self.logger = logging.getLogger("log") - - - def load_image(self, image): - self.image = Image.open(image) - self.pixels = self.image.load() - self.result_captcha = '' - - - def unload(self): - """delete all tmp images""" - pass - - - def threshold(self, value): - self.image = self.image.point(lambda a: a * value + 10) - - - def run(self, command): - """Run a command""" - - popen = subprocess.Popen(command, bufsize = -1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - popen.wait() - 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): - #tmpTif = tempfile.NamedTemporaryFile(suffix=".tif") - try: - tmpTif = open(save_join("tmp", "tmpTif_%s.tif" % self.__name__), "wb") - tmpTif.close() - - #tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt") - tmpTxt = open(save_join("tmp", "tmpTxt_%s.txt" % self.__name__), "wb") - tmpTxt.close() - - except IOError, e: - self.logError(e) - return - - self.logger.debug("save tiff") - self.image.save(tmpTif.name, 'TIFF') - - if os.name == "nt": - tessparams = [os.path.join(pypath, "tesseract", "tesseract.exe")] - else: - tessparams = ["tesseract"] - - tessparams.extend( [os.path.abspath(tmpTif.name), os.path.abspath(tmpTxt.name).replace(".txt", "")] ) - - if subset and (digits or lowercase or uppercase): - #tmpSub = tempfile.NamedTemporaryFile(suffix=".subset") - with open(save_join("tmp", "tmpSub_%s.subset" % self.__name__), "wb") as tmpSub: - tmpSub.write("tessedit_char_whitelist ") - - if digits: - tmpSub.write("0123456789") - if lowercase: - tmpSub.write("abcdefghijklmnopqrstuvwxyz") - if uppercase: - tmpSub.write("ABCDEFGHIJKLMNOPQRSTUVWXYZ") - - tmpSub.write("\n") - tessparams.append("nobatch") - tessparams.append(os.path.abspath(tmpSub.name)) - - self.logger.debug("run tesseract") - self.run(tessparams) - self.logger.debug("read txt") - - try: - with open(tmpTxt.name, 'r') as f: - self.result_captcha = f.read().replace("\n", "") - except Exception: - self.result_captcha = "" - - self.logger.debug(self.result_captcha) - try: - os.remove(tmpTif.name) - os.remove(tmpTxt.name) - if subset and (digits or lowercase or uppercase): - os.remove(tmpSub.name) - except Exception: - pass - - - def get_captcha(self, name): - raise NotImplementedError - - - def to_greyscale(self): - if self.image.mode != 'L': - self.image = self.image.convert('L') - - self.pixels = self.image.load() - - - def eval_black_white(self, limit): - self.pixels = self.image.load() - w, h = self.image.size - for x in xrange(w): - for y in xrange(h): - if self.pixels[x, y] > limit: - self.pixels[x, y] = 255 - else: - self.pixels[x, y] = 0 - - - def clean(self, allowed): - pixels = self.pixels - - w, h = self.image.size - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 255: - continue - # No point in processing white pixels since we only want to remove black pixel - count = 0 - - try: - if pixels[x-1, y-1] != 255: - count += 1 - if pixels[x-1, y] != 255: - count += 1 - if pixels[x-1, y + 1] != 255: - count += 1 - if pixels[x, y + 1] != 255: - count += 1 - if pixels[x + 1, y + 1] != 255: - count += 1 - if pixels[x + 1, y] != 255: - count += 1 - if pixels[x + 1, y-1] != 255: - count += 1 - if pixels[x, y-1] != 255: - count += 1 - except Exception: - pass - - # 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) - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 1: - pixels[x, y] = 255 - - self.pixels = pixels - - - def derotate_by_average(self): - """rotate by checking each angle and guess most suitable""" - - w, h = self.image.size - pixels = self.pixels - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 155 - - highest = {} - counts = {} - - for angle in xrange(-45, 45): - - tmpimage = self.image.rotate(angle) - - pixels = tmpimage.load() - - w, h = self.image.size - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 255 - - - count = {} - - for x in xrange(w): - count[x] = 0 - for y in xrange(h): - if pixels[x, y] == 155: - count[x] += 1 - - sum = 0 - cnt = 0 - - for x in count.values(): - if x != 0: - sum += x - cnt += 1 - - avg = sum / cnt - counts[angle] = cnt - highest[angle] = 0 - for x in count.values(): - if x > highest[angle]: - highest[angle] = x - - highest[angle] = highest[angle] - avg - - hkey = 0 - hvalue = 0 - - for key, value in highest.iteritems(): - if value > hvalue: - hkey = key - hvalue = value - - self.image = self.image.rotate(hkey) - pixels = self.image.load() - - for x in xrange(w): - for y in xrange(h): - if pixels[x, y] == 0: - pixels[x, y] = 255 - - if pixels[x, y] == 155: - pixels[x, y] = 0 - - self.pixels = pixels - - - def split_captcha_letters(self): - captcha = self.image - started = False - letters = [] - width, height = captcha.size - bottomY, topY = 0, height - pixels = captcha.load() - - for x in xrange(width): - black_pixel_in_col = False - for y in xrange(height): - if pixels[x, y] != 255: - if not started: - started = True - firstX = x - lastX = x - - if y > bottomY: - bottomY = y - if y < topY: - topY = y - if x > lastX: - lastX = x - - black_pixel_in_col = True - - if black_pixel_in_col is False and started is True: - rect = (firstX, topY, lastX, bottomY) - new_captcha = captcha.crop(rect) - - w, h = new_captcha.size - if w > 5 and h > 5: - letters.append(new_captcha) - - started = False - bottomY, topY = 0, height - - return letters - - - def correct(self, values, var=None): - if var: - result = var - else: - result = self.result_captcha - - for key, item in values.iteritems(): - - if key.__class__ == str: - result = result.replace(key, item) - else: - for expr in key: - result = result.replace(expr, item) - - if var: - return result - else: - self.result_captcha = result diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py deleted file mode 100644 index fcb8f0095..000000000 --- a/module/plugins/internal/CaptchaService.py +++ /dev/null @@ -1,526 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import time - -from base64 import b64encode -from random import random, randint -from urlparse import urljoin, urlparse - -from module.common.json_layer import json_loads -from module.plugins.Plugin import Base - - -#@TODO: Extend (new) Plugin class; remove all `html` args -class CaptchaService(Base): - __name__ = "CaptchaService" - __type__ = "captcha" - __version__ = "0.25" - - __description__ = """Base captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - key = None #: last key detected - - - def __init__(self, plugin): - self.plugin = plugin - super(CaptchaService, self).__init__(plugin.core) - - - def detect_key(self, html=None): - raise NotImplementedError - - - def challenge(self, key=None, html=None): - raise NotImplementedError - - - def result(self, server, challenge): - raise NotImplementedError - - -class ReCaptcha(CaptchaService): - __name__ = "ReCaptcha" - __type__ = "captcha" - __version__ = "0.14" - - __description__ = """ReCaptcha captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org"), - ("Walter Purcaro", "vuolter@gmail.com"), - ("zapp-brannigan", "fuerst.reinje@web.de")] - - - KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)' - KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("ReCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html) - if m: - self.key = m.group(1).strip() - self.logDebug("Key: %s" % self.key) - return self.key - else: - self.logDebug("Key not found") - return None - - - def challenge(self, key=None, html=None, version=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("ReCaptcha key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - if version in (1, 2): - return getattr(self, "_challenge_v%s" % version)(key) - - elif not html and hasattr(self.plugin, "html") and self.plugin.html: - version = 2 if re.search(self.KEY_V2_PATTERN, self.plugin.html) else 1 - return self.challenge(key, self.plugin.html, version) - - else: - errmsg = _("ReCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - - def _challenge_v1(self, key): - html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", - get={'k': key}) - try: - challenge = re.search("challenge : '(.+?)',", html).group(1) - server = re.search("server : '(.+?)',", html).group(1) - - except AttributeError: - errmsg = _("ReCaptcha challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(server, challenge), challenge - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha("%simage" % server, - get={'c': challenge}, - cookies=True, - forceUser=True, - imgtype="jpg") - - self.logDebug("Result: %s" % result) - - return result - - - def _collectApiInfo(self): - html = self.plugin.req.load("http://www.google.com/recaptcha/api.js") - a = re.search(r'po.src = \'(.*?)\';', html).group(1) - vers = a.split("/")[5] - - self.logDebug("API version: %s" %vers) - - language = a.split("__")[1].split(".")[0] - - self.logDebug("API language: %s" % language) - - html = self.plugin.req.load("https://apis.google.com/js/api.js") - b = re.search(r'"h":"(.*?)","', html).group(1) - jsh = b.decode('unicode-escape') - - self.logDebug("API jsh-string: %s" % jsh) - - return vers, language, jsh - - - def _prepareTimeAndRpc(self): - self.plugin.req.load("http://www.google.com/recaptcha/api2/demo") - - millis = int(round(time.time() * 1000)) - - self.logDebug("Time: %s" % millis) - - rand = randint(1, 99999999) - a = "0.%s" % str(rand * 2147483647) - rpc = int(100000000 * float(a)) - - self.logDebug("Rpc-token: %s" % rpc) - - return millis, rpc - - - def _challenge_v2(self, key, parent=None): - if parent is None: - try: - parent = urljoin("http://", urlparse(self.plugin.pyfile.url).netloc) - - except Exception: - parent = "" - - botguardstring = "!A" - vers, language, jsh = self._collectApiInfo() - millis, rpc = self._prepareTimeAndRpc() - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor", - get={'k' : key, - 'hl' : language, - 'v' : vers, - 'usegapi' : "1", - 'jsh' : "%s#id=IO_%s" % (jsh, millis), - 'parent' : parent, - 'pfname' : "", - 'rpctoken': rpc}) - - token1 = re.search(r'id="recaptcha-token" value="(.*?)">', html) - self.logDebug("Token #1: %s" % token1.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", - get={'c' : token1.group(1), - 'hl' : language, - 'v' : vers, - 'bg' : botguardstring, - 'k' : key, - 'usegapi': "1", - 'jsh' : jsh}).decode('unicode-escape') - - token2 = re.search(r'"finput","(.*?)",', html) - self.logDebug("Token #2: %s" % token2.group(1)) - - token3 = re.search(r'."asconf".\s,".*?".\s,"(.*?)".', html) - self.logDebug("Token #3: %s" % token3.group(1)) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload", - post={'k' : key, - 'c' : token2.group(1), - 'reason': "fi", - 'fbg' : token3.group(1)}) - - token4 = re.search(r'"rresp","(.*?)",', html) - self.logDebug("Token #4: %s" % token4.group(1)) - - millis_captcha_loading = int(round(time.time() * 1000)) - captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", - get={'c':token4.group(1), 'k':key}, - cookies=True, - forceUser=True) - response = b64encode('{"response":"%s"}' % captcha_response) - - self.logDebug("Result: %s" % response) - - timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading - timeToSolveMore = timeToSolve + int(float("0." + str(randint(1, 99999999))) * 500) - - html = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", - post={'k' : key, - 'c' : token4.group(1), - 'response': response, - 't' : timeToSolve, - 'ct' : timeToSolveMore, - 'bg' : botguardstring}) - - token5 = re.search(r'"uvresp","(.*?)",', html) - self.logDebug("Token #5: %s" % token5.group(1)) - - result = token5.group(1) - - return result, None - - -class AdsCaptcha(CaptchaService): - __name__ = "AdsCaptcha" - __type__ = "captcha" - __version__ = "0.08" - - __description__ = """AdsCaptcha captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - CAPTCHAID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*CaptchaId=(\d+)' - PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*PublicKey=([\w-]+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("AdsCaptcha html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.PUBLICKEY_PATTERN, html) - n = re.search(self.CAPTCHAID_PATTERN, html) - if m and n: - self.key = (m.group(1).strip(), n.group(1).strip()) #: key is the tuple(PublicKey, CaptchaId) - self.logDebug("Key|id: %s | %s" % self.key) - return self.key - else: - self.logDebug("Key or id not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("AdsCaptcha key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - PublicKey, CaptchaId = key - - html = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", - get={'CaptchaId': CaptchaId, - 'PublicKey': PublicKey}) - try: - challenge = re.search("challenge: '(.+?)',", html).group(1) - server = re.search("server: '(.+?)',", html).group(1) - - except AttributeError: - errmsg = _("AdsCaptcha challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(server, challenge), challenge - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server, - get={'cid': challenge, 'dummy': random()}, - cookies=True, - imgtype="jpg") - - self.logDebug("Result: %s" % result) - - return result - - -class SolveMedia(CaptchaService): - __name__ = "SolveMedia" - __type__ = "captcha" - __version__ = "0.12" - - __description__ = """SolveMedia captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("pyLoad Team", "admin@pyload.org")] - - - KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("SolveMedia html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.KEY_PATTERN, html) - if m: - self.key = m.group(1).strip() - self.logDebug("Key: %s" % self.key) - return self.key - else: - self.logDebug("Key not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("SolveMedia key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript", - get={'k': key}) - try: - challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="([^"]+)">', - html).group(1) - server = "http://api.solvemedia.com/papi/media" - - except AttributeError: - errmsg = _("SolveMedia challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - result = self.result(server, challenge) - - try: - magic = re.search(r'name="magic" value="(.+?)"', html).group(1) - - except AttributeError: - self.logDebug("Magic code not found") - - else: - if not self._verify(key, magic, result, challenge): - self.logDebug("Captcha code was invalid") - - return result, challenge - - - def _verify(self, key, magic, result, challenge, ref=None): #@TODO: Clean up - if ref is None: - try: - ref = self.plugin.pyfile.url - - except Exception: - ref = "" - - html = self.plugin.req.load("http://api.solvemedia.com/papi/verify.noscript", - post={'adcopy_response' : result, - 'k' : key, - 'l' : "en", - 't' : "img", - 's' : "standard", - 'magic' : magic, - 'adcopy_challenge' : challenge, - 'ref' : ref}) - try: - html = self.plugin.req.load(re.search(r'URL=(.+?)">', html).group(1)) - gibberish = re.search(r'id=gibberish>(.+?)</textarea>', html).group(1) - - except Exception: - return False - - else: - return True - - - def result(self, server, challenge): - result = self.plugin.decryptCaptcha(server, - get={'c': challenge}, - cookies=True, - imgtype="gif") - - self.logDebug("Result: %s" % result) - - return result - - -class AdYouLike(CaptchaService): - __name__ = "AdYouLike" - __type__ = "captcha" - __version__ = "0.05" - - __description__ = """AdYouLike captcha service plugin""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - AYL_PATTERN = r'Adyoulike\.create\s*\((.+?)\)' - CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)' - - - def detect_key(self, html=None): - if not html: - if hasattr(self.plugin, "html") and self.plugin.html: - html = self.plugin.html - else: - errmsg = _("AdYouLike html not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - m = re.search(self.AYL_PATTERN, html) - n = re.search(self.CALLBACK_PATTERN, html) - if m and n: - self.key = (m.group(1).strip(), n.group(1).strip()) - self.logDebug("Ayl|callback: %s | %s" % self.key) - return self.key #: key is the tuple(ayl, callback) - else: - self.logDebug("Ayl or callback not found") - return None - - - def challenge(self, key=None, html=None): - if not key: - if self.detect_key(html): - key = self.key - else: - errmsg = _("AdYouLike key not found") - self.plugin.fail(errmsg) - raise TypeError(errmsg) - - ayl, callback = key - - # {"adyoulike":{"key":"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"}, - # "all":{"element_id":"ayl_private_cap_92300","lang":"fr","env":"prod"}} - ayl = json_loads(ayl) - - html = self.plugin.req.load("http://api-ayl.appspot.com/challenge", - get={'key' : ayl['adyoulike']['key'], - 'env' : ayl['all']['env'], - 'callback': callback}) - try: - challenge = json_loads(re.search(callback + r'\s*\((.+?)\)', html).group(1)) - - except AttributeError: - errmsg = _("AdYouLike challenge pattern not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - self.logDebug("Challenge: %s" % challenge) - - return self.result(ayl, challenge), challenge - - - def result(self, server, challenge): - # Adyoulike.g._jsonp_5579316662423138 - # ({"translations":{"fr":{"instructions_visual":"Recopiez « Soonnight » ci-dessous :"}}, - # "site_under":true,"clickable":true,"pixels":{"VIDEO_050":[],"DISPLAY":[],"VIDEO_000":[],"VIDEO_100":[], - # "VIDEO_025":[],"VIDEO_075":[]},"medium_type":"image/adyoulike", - # "iframes":{"big":"<iframe src=\"http://www.soonnight.com/campagn.html\" scrolling=\"no\" - # height=\"250\" width=\"300\" frameborder=\"0\"></iframe>"},"shares":{},"id":256, - # "token":"e6QuI4aRSnbIZJg02IsV6cp4JQ9~MjA1","formats":{"small":{"y":300,"x":0,"w":300,"h":60}, - # "big":{"y":0,"x":0,"w":300,"h":250},"hover":{"y":440,"x":0,"w":300,"h":60}}, - # "tid":"SqwuAdxT1EZoi4B5q0T63LN2AkiCJBg5"}) - - if isinstance(server, basestring): - server = json_loads(server) - - if isinstance(challenge, basestring): - challenge = json_loads(challenge) - - try: - instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] - result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() - - except AttributeError: - errmsg = _("AdYouLike result not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) - - result = {'_ayl_captcha_engine' : "adyoulike", - '_ayl_env' : server['all']['env'], - '_ayl_tid' : challenge['tid'], - '_ayl_token_challenge': challenge['token'], - '_ayl_response' : response} - - self.logDebug("Result: %s" % result) - - return result diff --git a/pyload/plugin/Addon.py b/pyload/plugin/Addon.py index dc07a2513..14b5ee2a5 100644 --- a/pyload/plugin/Addon.py +++ b/pyload/plugin/Addon.py @@ -76,11 +76,9 @@ class Addon(Base): self.setup() - # self.initPeriodical() - def initPeriodical(self, delay=0, threaded=False): - self.cb = self.core.scheduler.addJob(delay, self._periodical, args=[threaded], threaded=threaded) + self.cb = self.core.scheduler.addJob(max(0, delay), self._periodical, args=[threaded], threaded=threaded) def _periodical(self, threaded): diff --git a/pyload/plugin/Captcha.py b/pyload/plugin/Captcha.py index 383eedac8..d7a506979 100644 --- a/pyload/plugin/Captcha.py +++ b/pyload/plugin/Captcha.py @@ -19,7 +19,7 @@ class Captcha(Base): def __init__(self, plugin): self.plugin = plugin self.key = None #: last key detected - super(CaptchaService, self).__init__(plugin.core) + super(Captcha, self).__init__(plugin.core) def detect_key(self, html=None): diff --git a/pyload/plugin/account/Keep2ShareCc.py b/pyload/plugin/account/Keep2ShareCc.py index 7ed15dc62..a3cc2c40d 100644 --- a/pyload/plugin/account/Keep2ShareCc.py +++ b/pyload/plugin/account/Keep2ShareCc.py @@ -1,32 +1,32 @@ # -*- coding: utf-8 -*- import re - -from time import gmtime, mktime, strptime +import time from pyload.plugin.Account import Account -class Keep2shareCc(Account): - __name__ = "Keep2shareCc" +class Keep2ShareCc(Account): + __name__ = "Keep2ShareCc" __type__ = "account" - __version__ = "0.02" + __version__ = "0.05" - __description__ = """Keep2share.cc account plugin""" + __description__ = """Keep2Share.cc account plugin""" __license__ = "GPLv3" - __authors__ = [("aeronaut", "aeronaut@pianoguy.de")] + __authors__ = [("aeronaut", "aeronaut@pianoguy.de"), + ("Walter Purcaro", "vuolter@gmail.com")] - VALID_UNTIL_PATTERN = r'Premium expires: <b>(.+?)</b>' - TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):<b><a href="/user/statistic.html">(.+?)</a>' + VALID_UNTIL_PATTERN = r'Premium expires:\s*<b>(.+?)<' + TRAFFIC_LEFT_PATTERN = r'Available traffic \(today\):\s*<b><a href="/user/statistic.html">(.+?)<' LOGIN_FAIL_PATTERN = r'Please fix the following input errors' def loadAccountInfo(self, user, req): validuntil = None - trafficleft = None - premium = None + trafficleft = -1 + premium = False html = req.load("http://keep2share.cc/site/profile.html", decode=True) @@ -35,26 +35,26 @@ class Keep2shareCc(Account): expiredate = m.group(1).strip() self.logDebug("Expire date: " + expiredate) - try: - validuntil = mktime(strptime(expiredate, "%Y.%m.%d")) + if expiredate == "LifeTime": + premium = True + validuntil = -1 + else: + try: + validuntil = time.mktime(time.strptime(expiredate, "%Y.%m.%d")) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) - else: - if validuntil > mktime(gmtime()): - premium = True else: - premium = False - validuntil = None + premium = True if validuntil > time.mktime(time.gmtime()) else False - m = re.search(self.TRAFFIC_LEFT_PATTERN, html) - if m: - try: - trafficleft = self.parseTraffic(m.group(1)) + m = re.search(self.TRAFFIC_LEFT_PATTERN, html) + if m: + try: + trafficleft = self.parseTraffic(m.group(1)) - except Exception, e: - self.logError(e) + except Exception, e: + self.logError(e) return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} @@ -63,7 +63,11 @@ class Keep2shareCc(Account): req.cj.setCookie("keep2share.cc", "lang", "en") html = req.load("http://keep2share.cc/login.html", - post={'LoginForm[username]': user, 'LoginForm[password]': data['password']}) + post={'LoginForm[username]' : user, + 'LoginForm[password]' : data['password'], + 'LoginForm[rememberMe]': 1, + 'yt0' : ""}, + decode=True) if re.search(self.LOGIN_FAIL_PATTERN, html): self.wrongPassword() diff --git a/module/plugins/accounts/MegaRapidoNet.py b/pyload/plugin/account/MegaRapidoNet.py index 80e066244..22979a09a 100644 --- a/module/plugins/accounts/MegaRapidoNet.py +++ b/pyload/plugin/account/MegaRapidoNet.py @@ -3,7 +3,7 @@ import re import time -from module.plugins.Account import Account +from pyload.plugin.Account import Account class MegaRapidoNet(Account): @@ -50,8 +50,8 @@ class MegaRapidoNet(Account): if "sair" not in html.lower(): self.wrongPassword() else: - m = re.search(self.USER_ID_PATTERN, html) - if m: - data['uid'] = m.group(1) - else: - self.fail("Couldn't find the user ID") + m = re.search(self.USER_ID_PATTERN, html) + if m: + data['uid'] = m.group(1) + else: + self.fail("Couldn't find the user ID") diff --git a/pyload/plugin/addon/AndroidPhoneNotify.py b/pyload/plugin/addon/AndroidPhoneNotify.py index 53af8aa1c..d3b390e6e 100644 --- a/pyload/plugin/addon/AndroidPhoneNotify.py +++ b/pyload/plugin/addon/AndroidPhoneNotify.py @@ -28,11 +28,9 @@ class AndroidPhoneNotify(Addon): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -44,7 +42,7 @@ class AndroidPhoneNotify(Addon): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/module/plugins/hooks/AntiVirus.py b/pyload/plugin/addon/AntiVirus.py index cc3c5c754..619893735 100644 --- a/module/plugins/hooks/AntiVirus.py +++ b/pyload/plugin/addon/AntiVirus.py @@ -4,13 +4,13 @@ import os import shutil import subprocess -from module.plugins.Hook import Hook, Expose, threaded -from module.utils import fs_encode, save_join +from pyload.plugin.Addon import Addon, Expose, threaded +from pyload.utils import fs_encode, fs_join -class AntiVirus(Hook): +class AntiVirus(Addon): __name__ = "AntiVirus" - __type__ = "hook" + __type__ = "addon" __version__ = "0.05" #@TODO: add trash option (use Send2Trash lib) @@ -26,13 +26,6 @@ class AntiVirus(Hook): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @Expose @threaded def scan(self, pyfile, thread): diff --git a/pyload/plugin/addon/Checksum.py b/pyload/plugin/addon/Checksum.py index 7ba5d7ab6..4b1380506 100644 --- a/pyload/plugin/addon/Checksum.py +++ b/pyload/plugin/addon/Checksum.py @@ -56,7 +56,6 @@ class Checksum(Addon): ("stickell" , "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 methods = {'sfv' : 'crc32', 'crc' : 'crc32', 'hash': 'md5'} @@ -72,7 +71,6 @@ class Checksum(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.algorithms = sorted( getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True) diff --git a/pyload/plugin/addon/ClickAndLoad.py b/pyload/plugin/addon/ClickAndLoad.py index 63647e30a..df8d09806 100644 --- a/pyload/plugin/addon/ClickAndLoad.py +++ b/pyload/plugin/addon/ClickAndLoad.py @@ -30,15 +30,12 @@ class ClickAndLoad(Addon): ("port" , "int" , "Port" , 9666), ("extern" , "bool", "Listen on the public network interface", True)] - __description__ = """Click'n'Load hook plugin""" + __description__ = """Click'n'Load addon plugin""" __license__ = "GPLv3" __authors__ = [("RaNaN" , "RaNaN@pyload.de" ), ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def activate(self): if not self.config['webinterface']['activated']: return diff --git a/pyload/plugin/addon/DeleteFinished.py b/pyload/plugin/addon/DeleteFinished.py index aad05891e..989271fa8 100644 --- a/pyload/plugin/addon/DeleteFinished.py +++ b/pyload/plugin/addon/DeleteFinished.py @@ -25,7 +25,6 @@ class DeleteFinished(Addon): ## overwritten methods ## def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.interval = self.MIN_CHECK_INTERVAL @@ -56,6 +55,7 @@ class DeleteFinished(Addon): # self.pluginConfigChanged(self.__name__, 'interval', interval) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60 * 60) self.addEvent('packageFinished', self.wakeup) + self.initPeriodical() ## own methods ## diff --git a/pyload/plugin/addon/DownloadScheduler.py b/pyload/plugin/addon/DownloadScheduler.py index ff65a478d..de961cc1f 100644 --- a/pyload/plugin/addon/DownloadScheduler.py +++ b/pyload/plugin/addon/DownloadScheduler.py @@ -20,14 +20,6 @@ class DownloadScheduler(Addon): ("stickell", "l.stickell@yahoo.it")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded - - def activate(self): self.updateSchedule() diff --git a/pyload/plugin/addon/ExternalScripts.py b/pyload/plugin/addon/ExternalScripts.py index 139be1299..502a6dc7b 100644 --- a/pyload/plugin/addon/ExternalScripts.py +++ b/pyload/plugin/addon/ExternalScripts.py @@ -28,7 +28,6 @@ class ExternalScripts(Addon): "all_archives_extracted", "all_archives_processed", "allDownloadsFinished" , "allDownloadsProcessed" , "packageDeleted"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): @@ -65,7 +64,7 @@ class ExternalScripts(Addon): return for filename in os.listdir(dir): - file = save_join(dir, filename) + file = fs_join(dir, filename) if not os.path.isfile(file): continue @@ -102,7 +101,7 @@ class ExternalScripts(Addon): self.callScript(script) - def coreExiting(self): + def exit(self): for script in self.scripts['pyload_restart' if self.core.do_restart else 'pyload_stop']: self.callScript(script) @@ -125,23 +124,23 @@ class ExternalScripts(Addon): def downloadFailed(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_failed']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) def downloadFinished(self, pyfile): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pyfile.package().folder) + download_folder = fs_join(self.config['general']['download_folder'], pyfile.package().folder) else: download_folder = self.config['general']['download_folder'] for script in self.scripts['download_finished']: - file = save_join(download_folder, pyfile.name) + file = fs_join(download_folder, pyfile.name) self.callScript(script, pyfile.id, pyfile.name, pyfile.pluginname, pyfile.url, file) @@ -157,7 +156,7 @@ class ExternalScripts(Addon): def packageFinished(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -169,7 +168,7 @@ class ExternalScripts(Addon): pack = self.core.api.getPackageInfo(pid) if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pack.folder) else: download_folder = self.config['general']['download_folder'] @@ -179,7 +178,7 @@ class ExternalScripts(Addon): def package_extract_failed(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] @@ -189,7 +188,7 @@ class ExternalScripts(Addon): def package_extracted(self, pypack): if self.config['general']['folder_per_package']: - download_folder = save_join(self.config['general']['download_folder'], pypack.folder) + download_folder = fs_join(self.config['general']['download_folder'], pypack.folder) else: download_folder = self.config['general']['download_folder'] diff --git a/pyload/plugin/addon/ExtractArchive.py b/pyload/plugin/addon/ExtractArchive.py index 3c71e7e1a..419ca609e 100644 --- a/pyload/plugin/addon/ExtractArchive.py +++ b/pyload/plugin/addon/ExtractArchive.py @@ -137,8 +137,6 @@ class ExtractArchive(Addon): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.queue = ArchiveQueue(self, "Queue") self.failed = ArchiveQueue(self, "Failed") diff --git a/pyload/plugin/addon/IRCInterface.py b/pyload/plugin/addon/IRCInterface.py index 9038ce993..6d85a5681 100644 --- a/pyload/plugin/addon/IRCInterface.py +++ b/pyload/plugin/addon/IRCInterface.py @@ -37,9 +37,6 @@ class IRCInterface(Thread, Addon): __authors__ = [("Jeix", "Jeix@hasnomail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def __init__(self, core, manager): Thread.__init__(self) Addon.__init__(self, core, manager) diff --git a/pyload/plugin/addon/JustPremium.py b/pyload/plugin/addon/JustPremium.py index e69bc24f6..b878f302d 100644 --- a/pyload/plugin/addon/JustPremium.py +++ b/pyload/plugin/addon/JustPremium.py @@ -21,11 +21,6 @@ class JustPremium(Addon): event_list = ["linksAdded"] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 def linksAdded(self, links, pid): diff --git a/pyload/plugin/addon/MergeFiles.py b/pyload/plugin/addon/MergeFiles.py index 374604d82..e0233af10 100644 --- a/pyload/plugin/addon/MergeFiles.py +++ b/pyload/plugin/addon/MergeFiles.py @@ -23,15 +23,9 @@ class MergeFiles(Addon): __authors__ = [("and9000", "me@has-no-mail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - BUFFER_SIZE = 4096 - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @threaded def packageFinished(self, pack): files = {} diff --git a/pyload/plugin/addon/MultiHome.py b/pyload/plugin/addon/MultiHome.py index 0cebf35b8..03974d6c6 100644 --- a/pyload/plugin/addon/MultiHome.py +++ b/pyload/plugin/addon/MultiHome.py @@ -17,11 +17,7 @@ class MultiHome(Addon): __authors__ = [("mkaay", "mkaay@mkaay.de")] - interval = 0 #@TODO: Remove in 0.4.10 - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.register = {} self.interfaces = [] diff --git a/pyload/plugin/addon/RestartFailed.py b/pyload/plugin/addon/RestartFailed.py index e34424a8c..c568bfb0a 100644 --- a/pyload/plugin/addon/RestartFailed.py +++ b/pyload/plugin/addon/RestartFailed.py @@ -40,3 +40,4 @@ class RestartFailed(Addon): def activate(self): # self.pluginConfigChanged(self.__name__, "interval", self.getConfig('interval')) self.interval = max(self.MIN_CHECK_INTERVAL, self.getConfig('interval') * 60) + self.initPeriodical() diff --git a/pyload/plugin/addon/RestartSlow.py b/pyload/plugin/addon/RestartSlow.py index cd503518d..34416e79a 100644 --- a/pyload/plugin/addon/RestartSlow.py +++ b/pyload/plugin/addon/RestartSlow.py @@ -22,11 +22,12 @@ class RestartSlow(Addon): event_list = ["downloadStarts"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): self.info = {'chunk': {}} + + def periodical(self): if not self.pyfile.plugin.req.dl: return @@ -36,8 +37,8 @@ class RestartSlow(Addon): limit = 5 else: type = "premium" if self.pyfile.plugin.premium else "free" - time = max(30, self.getConfig("%s_time" % type) * 60) - limit = max(5, self.getConfig("%s_limit" % type) * 1024) + time = max(30, self.getConfig('%s_time' % type) * 60) + limit = max(5, self.getConfig('%s_limit' % type) * 1024) chunks = [chunk for chunk in self.pyfile.plugin.req.dl.chunks \ if chunk.id not in self.info['chunk'] or self.info['chunk'][chunk.id] is not (time, limit)] diff --git a/pyload/plugin/addon/SkipRev.py b/pyload/plugin/addon/SkipRev.py index 157b55bbd..1c42ddfd8 100644 --- a/pyload/plugin/addon/SkipRev.py +++ b/pyload/plugin/addon/SkipRev.py @@ -6,14 +6,14 @@ from types import MethodType from urllib import unquote from urlparse import urlparse -from module.PyFile import PyFile -from module.plugins.Hook import Hook -from module.plugins.Plugin import SkipDownload +from pyload.datatype.File import PyFile +from pyload.plugin.Addon import Addon +from pyload.plugin.Plugin import SkipDownload -class SkipRev(Hook): +class SkipRev(Addon): __name__ = "SkipRev" - __type__ = "hook" + __type__ = "addon" __version__ = "0.29" __config__ = [("mode" , "Auto;Manual", "Choose recovery archives to skip" , "Auto"), @@ -24,13 +24,6 @@ class SkipRev(Hook): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - - def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - - @staticmethod def _setup(self): self.pyfile.plugin._setup() diff --git a/pyload/plugin/addon/UnSkipOnFail.py b/pyload/plugin/addon/UnSkipOnFail.py index 55de85082..f81066daa 100644 --- a/pyload/plugin/addon/UnSkipOnFail.py +++ b/pyload/plugin/addon/UnSkipOnFail.py @@ -16,9 +16,6 @@ class UnSkipOnFail(Addon): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - - def downloadFailed(self, pyfile): #: Check if pyfile is still "failed", # maybe might has been restarted in meantime diff --git a/pyload/plugin/addon/UpdateManager.py b/pyload/plugin/addon/UpdateManager.py index 643b5c2d1..cd8dc9a03 100644 --- a/pyload/plugin/addon/UpdateManager.py +++ b/pyload/plugin/addon/UpdateManager.py @@ -9,9 +9,9 @@ import time from operator import itemgetter -from module.network.RequestFactory import getURL -from module.plugins.Hook import Expose, Hook, threaded -from module.utils import save_join +from pyload.network.RequestFactory import getURL +from pyload.plugin.Addon import Expose, Addon, threaded +from pyload.utils import fs_join # Case-sensitive os.path.exists @@ -26,9 +26,9 @@ def exists(path): return False -class UpdateManager(Hook): +class UpdateManager(Addon): __name__ = "UpdateManager" - __type__ = "hook" + __type__ = "addon" __version__ = "0.50" __config__ = [("activated" , "bool", "Activated" , True ), @@ -43,14 +43,11 @@ class UpdateManager(Hook): __license__ = "GPLv3" __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - interval = 0 - SERVER_URL = "http://updatemanager.pyload.org" MIN_CHECK_INTERVAL = 3 * 60 * 60 #: 3 hours - def coreReady(self): + def activate(self): if self.checkonstart: self.update() @@ -189,7 +186,7 @@ class UpdateManager(Hook): # Protect UpdateManager from self-removing try: - type_plugins.remove(("hook", "UpdateManager")) + type_plugins.remove(("addon", "UpdateManager")) except ValueError: pass @@ -242,7 +239,7 @@ class UpdateManager(Hook): m = VERSION.search(content) if m and m.group(2) == version: - with open(save_join("userplugins", prefix, filename), "wb") as f: + with open(fs_join("userplugins", prefix, filename), "wb") as f: f.write(content) updated.append((prefix, name)) @@ -288,12 +285,12 @@ class UpdateManager(Hook): rootplugins = os.path.join(pypath, "module", "plugins") for dir in ("userplugins", rootplugins): - py_filename = save_join(dir, type, name + ".py") + py_filename = fs_join(dir, type, name + ".py") pyc_filename = py_filename + "c" - if type == "hook": + if type == "addon": try: - self.manager.deactivateHook(name) + self.manager.deactivateAddon(name) except Exception, e: self.logDebug(e) diff --git a/pyload/plugin/addon/WindowsPhoneNotify.py b/pyload/plugin/addon/WindowsPhoneNotify.py index e61057f9f..341e682b2 100644 --- a/pyload/plugin/addon/WindowsPhoneNotify.py +++ b/pyload/plugin/addon/WindowsPhoneNotify.py @@ -3,12 +3,12 @@ import httplib import time -from module.plugins.Hook import Hook, Expose +from pyload.plugin.Addon import Addon, Expose -class WindowsPhoneNotify(Hook): +class WindowsPhoneNotify(Addon): __name__ = "WindowsPhoneNotify" - __type__ = "hook" + __type__ = "addon" __version__ = "0.09" __config__ = [("id" , "str" , "Push ID" , "" ), @@ -29,11 +29,9 @@ class WindowsPhoneNotify(Hook): event_list = ["allDownloadsProcessed", "plugin_updated"] - interval = 0 #@TODO: Remove in 0.4.10 def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 self.last_notify = 0 self.notifications = 0 @@ -45,7 +43,7 @@ class WindowsPhoneNotify(Hook): self.notify(_("Plugins updated"), str(type_plugins)) - def coreExiting(self): + def exit(self): if not self.getConfig('notifyexit'): return diff --git a/pyload/plugin/captcha/AdYouLike.py b/pyload/plugin/captcha/AdYouLike.py index 0ff1a799b..d656acb09 100644 --- a/pyload/plugin/captcha/AdYouLike.py +++ b/pyload/plugin/captcha/AdYouLike.py @@ -8,6 +8,7 @@ from pyload.utils import json_loads class AdYouLike(Captcha): __name__ = "AdYouLike" + __type__ = "captcha" __version__ = "0.05" __description__ = """AdYouLike captcha service plugin""" diff --git a/pyload/plugin/captcha/AdsCaptcha.py b/pyload/plugin/captcha/AdsCaptcha.py index 75852e36d..5b23247c0 100644 --- a/pyload/plugin/captcha/AdsCaptcha.py +++ b/pyload/plugin/captcha/AdsCaptcha.py @@ -9,6 +9,7 @@ from pyload.plugin.Captcha import Captcha class AdsCaptcha(Captcha): __name__ = "AdsCaptcha" + __type__ = "captcha" __version__ = "0.08" __description__ = """AdsCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/ReCaptcha.py b/pyload/plugin/captcha/ReCaptcha.py index 295491bd8..62b82d1d5 100644 --- a/pyload/plugin/captcha/ReCaptcha.py +++ b/pyload/plugin/captcha/ReCaptcha.py @@ -12,6 +12,7 @@ from pyload.plugin.Captcha import Captcha class ReCaptcha(Captcha): __name__ = "ReCaptcha" + __type__ = "captcha" __version__ = "0.14" __description__ = """ReCaptcha captcha service plugin""" diff --git a/pyload/plugin/captcha/SolveMedia.py b/pyload/plugin/captcha/SolveMedia.py index af45101b4..7f421f490 100644 --- a/pyload/plugin/captcha/SolveMedia.py +++ b/pyload/plugin/captcha/SolveMedia.py @@ -7,6 +7,7 @@ from pyload.plugin.Captcha import Captcha class SolveMedia(Captcha): __name__ = "SolveMedia" + __type__ = "captcha" __version__ = "0.12" __description__ = """SolveMedia captcha service plugin""" diff --git a/module/plugins/crypter/DailymotionComFolder.py b/pyload/plugin/crypter/DailymotionComFolder.py index 5c078000a..3c5000515 100644 --- a/module/plugins/crypter/DailymotionComFolder.py +++ b/pyload/plugin/crypter/DailymotionComFolder.py @@ -4,9 +4,9 @@ import re from urlparse import urljoin -from module.common.json_layer import json_loads -from module.plugins.Crypter import Crypter -from module.utils import save_join +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join class DailymotionComFolder(Crypter): @@ -101,6 +101,6 @@ class DailymotionComFolder(Crypter): for p_id, p_name, p_owner in playlists: p_videos = self.getVideos(p_id) - p_folder = save_join(self.config['general']['download_folder'], p_owner, p_name) + p_folder = fs_join(self.config['general']['download_folder'], p_owner, p_name) self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) self.packages.append((p_name, p_videos, p_folder)) #: folder is NOT recognized by pyload 0.4.9! diff --git a/pyload/plugin/crypter/FilecryptCc.py b/pyload/plugin/crypter/FilecryptCc.py index c052573e1..1d8388dcd 100644 --- a/pyload/plugin/crypter/FilecryptCc.py +++ b/pyload/plugin/crypter/FilecryptCc.py @@ -10,7 +10,7 @@ from Crypto.Cipher import AES from urlparse import urljoin from pyload.plugin.Crypter import Crypter -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha class FilecryptCc(Crypter): diff --git a/module/plugins/crypter/YoutubeComFolder.py b/pyload/plugin/crypter/YoutubeComFolder.py index d7ca494fa..e42615af0 100644 --- a/module/plugins/crypter/YoutubeComFolder.py +++ b/pyload/plugin/crypter/YoutubeComFolder.py @@ -4,9 +4,9 @@ import re from urlparse import urljoin -from module.common.json_layer import json_loads -from module.plugins.Crypter import Crypter -from module.utils import save_join +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import fs_join class YoutubeComFolder(Crypter): @@ -132,7 +132,7 @@ class YoutubeComFolder(Crypter): for p in playlists: p_name = p['title'] p_videos = self.getVideosId(p['id']) - p_folder = save_join(self.config['general']['download_folder'], p['channelTitle'], p_name) + p_folder = fs_join(self.config['general']['download_folder'], p['channelTitle'], p_name) self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) if not p_videos: diff --git a/pyload/plugin/extractor/UnRar.py b/pyload/plugin/extractor/UnRar.py index 5b9052bff..3bc4f3464 100644 --- a/pyload/plugin/extractor/UnRar.py +++ b/pyload/plugin/extractor/UnRar.py @@ -198,13 +198,13 @@ class UnRar(Extractor): if not self.fullpath and self.VERSION.startswith('5'): # NOTE: Unrar 5 always list full path for f in fs_decode(out).splitlines(): - f = save_join(self.out, os.path.basename(f.strip())) + f = fs_join(self.out, os.path.basename(f.strip())) if os.path.isfile(f): - result.add(save_join(self.out, os.path.basename(f))) + result.add(fs_join(self.out, os.path.basename(f))) else: for f in fs_decode(out).splitlines(): f = f.strip() - result.add(save_join(self.out, f)) + result.add(fs_join(self.out, f)) return list(result) diff --git a/pyload/plugin/hook/BypassCaptcha.py b/pyload/plugin/hook/BypassCaptcha.py index 786f5dff3..4579d17c5 100644 --- a/pyload/plugin/hook/BypassCaptcha.py +++ b/pyload/plugin/hook/BypassCaptcha.py @@ -40,8 +40,6 @@ class BypassCaptcha(Hook): ("zoidberg" , "zoidberg@mujmail.cz" )] - interval = 0 #@TODO: Remove in 0.4.10 - PYLOAD_KEY = "4f771155b640970d5607f919a615bdefc67e7d32" SUBMIT_URL = "http://bypasscaptcha.com/upload.php" diff --git a/pyload/plugin/hook/Captcha9Kw.py b/pyload/plugin/hook/Captcha9Kw.py index 38cbb5a21..012266739 100644 --- a/pyload/plugin/hook/Captcha9Kw.py +++ b/pyload/plugin/hook/Captcha9Kw.py @@ -36,8 +36,6 @@ class Captcha9kw(Hook): ("Walter Purcaro", "vuolter@gmail.com")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.9kw.eu/index.cgi" diff --git a/pyload/plugin/hook/CaptchaBrotherhood.py b/pyload/plugin/hook/CaptchaBrotherhood.py index fbf2e2e29..3cbdb27d7 100644 --- a/pyload/plugin/hook/CaptchaBrotherhood.py +++ b/pyload/plugin/hook/CaptchaBrotherhood.py @@ -50,11 +50,14 @@ class CaptchaBrotherhood(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.captchabrotherhood.com/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL + "askCredits.aspx", get={"username": self.getConfig('username'), "password": self.getConfig('passkey')}) diff --git a/pyload/plugin/hook/DeathByCaptcha.py b/pyload/plugin/hook/DeathByCaptcha.py index 41d4d300b..0f0e66ea2 100644 --- a/pyload/plugin/hook/DeathByCaptcha.py +++ b/pyload/plugin/hook/DeathByCaptcha.py @@ -63,11 +63,14 @@ class DeathByCaptcha(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://api.dbcapi.me/api/" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def api_response(self, api="captcha", post=False, multipart=False): req = getRequest() req.c.setopt(HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version]) diff --git a/pyload/plugin/hook/ExpertDecoders.py b/pyload/plugin/hook/ExpertDecoders.py index f1096b8ed..0f86baa17 100644 --- a/pyload/plugin/hook/ExpertDecoders.py +++ b/pyload/plugin/hook/ExpertDecoders.py @@ -25,11 +25,14 @@ class ExpertDecoders(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - API_URL = "http://www.fasttypers.org/imagepost.ashx" + def activate(self): + if self.getConfig('ssl'): + self.API_URL = self.API_URL.replace("http://", "https://") + + def getCredits(self): res = getURL(self.API_URL, post={"key": self.getConfig('passkey'), "action": "balance"}) diff --git a/pyload/plugin/hook/ImageTyperz.py b/pyload/plugin/hook/ImageTyperz.py index a556b109a..a7c3389c1 100644 --- a/pyload/plugin/hook/ImageTyperz.py +++ b/pyload/plugin/hook/ImageTyperz.py @@ -44,8 +44,6 @@ class ImageTyperz(Hook): ("zoidberg", "zoidberg@mujmail.cz")] - interval = 0 #@TODO: Remove in 0.4.10 - SUBMIT_URL = "http://captchatypers.com/Forms/UploadFileAndGetTextNEW.ashx" RESPOND_URL = "http://captchatypers.com/Forms/SetBadImage.ashx" GETCREDITS_URL = "http://captchatypers.com/Forms/RequestBalance.ashx" diff --git a/module/plugins/hooks/MegaRapidoNet.py b/pyload/plugin/hook/MegaRapidoNet.py index fb5e77994..2f660c939 100644 --- a/module/plugins/hooks/MegaRapidoNet.py +++ b/pyload/plugin/hook/MegaRapidoNet.py @@ -2,7 +2,7 @@ import re -from module.plugins.internal.MultiHook import MultiHook +from pyload.plugin.internal.MultiHook import MultiHook class MegaRapidoNet(MultiHook): diff --git a/pyload/plugin/hook/XFileSharingPro.py b/pyload/plugin/hook/XFileSharingPro.py index 9599c8180..9560cbd08 100644 --- a/pyload/plugin/hook/XFileSharingPro.py +++ b/pyload/plugin/hook/XFileSharingPro.py @@ -23,7 +23,6 @@ class XFileSharingPro(Hook): # event_list = ["pluginConfigChanged"] - interval = 0 #@TODO: Remove in 0.4.10 regexp = {'hoster' : (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:embed-)?\w+'), 'crypter': (r'https?://(?:www\.)?(?P<DOMAIN>[\w\-.^_]{3,63}(?:\.[a-zA-Z]{2,})(?:\:\d+)?)/(?:user|folder)s?/\w+', @@ -54,7 +53,7 @@ class XFileSharingPro(Hook): use_builtin_list = self.getConfig('use_builtin_list') for type in ("hoster", "crypter"): - every_plugin = not self.getConfig("use_%s_list" % type) + every_plugin = not self.getConfig('use_%s_list' % type) if every_plugin: self.logInfo(_("Handling any %s I can!") % type) diff --git a/pyload/plugin/hoster/ExtabitCom.py b/pyload/plugin/hoster/ExtabitCom.py index dfd37b0a0..c0fa782fa 100644 --- a/pyload/plugin/hoster/ExtabitCom.py +++ b/pyload/plugin/hoster/ExtabitCom.py @@ -4,7 +4,7 @@ import re from pyload.utils import json_loads -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/FileserveCom.py b/pyload/plugin/hoster/FileserveCom.py index 18322fa00..eb80889b1 100644 --- a/pyload/plugin/hoster/FileserveCom.py +++ b/pyload/plugin/hoster/FileserveCom.py @@ -6,7 +6,7 @@ from pyload.utils import json_loads from pyload.network.RequestFactory import getURL from pyload.plugin.Hoster import Hoster from pyload.plugin.Plugin import chunks -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight from pyload.utils import parseFileSize diff --git a/pyload/plugin/hoster/FreakshareCom.py b/pyload/plugin/hoster/FreakshareCom.py index 331d7f2a3..53eb10e55 100644 --- a/pyload/plugin/hoster/FreakshareCom.py +++ b/pyload/plugin/hoster/FreakshareCom.py @@ -3,7 +3,7 @@ import re from pyload.plugin.Hoster import Hoster -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import secondsToMidnight diff --git a/pyload/plugin/hoster/Keep2ShareCc.py b/pyload/plugin/hoster/Keep2ShareCc.py index 3c2b6c570..67af087b7 100644 --- a/pyload/plugin/hoster/Keep2ShareCc.py +++ b/pyload/plugin/hoster/Keep2ShareCc.py @@ -4,7 +4,7 @@ import re from urlparse import urljoin -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/LetitbitNet.py b/pyload/plugin/hoster/LetitbitNet.py index 01767cabf..545cde27c 100644 --- a/pyload/plugin/hoster/LetitbitNet.py +++ b/pyload/plugin/hoster/LetitbitNet.py @@ -12,7 +12,7 @@ from urlparse import urljoin from pyload.utils import json_loads, json_dumps from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight diff --git a/pyload/plugin/hoster/MediafireCom.py b/pyload/plugin/hoster/MediafireCom.py index 3b39e2420..8b05a95ec 100644 --- a/pyload/plugin/hoster/MediafireCom.py +++ b/pyload/plugin/hoster/MediafireCom.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from module.plugins.internal.CaptchaService import SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster class MediafireCom(SimpleHoster): @@ -58,6 +58,3 @@ class MediafireCom(SimpleHoster): self.fail(_("Incorrect password")) return super(MediafireCom, self).handleFree(pyfile) - - -getInfo = create_getInfo(MediafireCom) diff --git a/module/plugins/hoster/MegaRapidoNet.py b/pyload/plugin/hoster/MegaRapidoNet.py index b38374646..938b201d5 100644 --- a/module/plugins/hoster/MegaRapidoNet.py +++ b/pyload/plugin/hoster/MegaRapidoNet.py @@ -2,7 +2,7 @@ from random import randint -from module.plugins.internal.MultiHoster import MultiHoster +from pyload.plugin.internal.MultiHoster import MultiHoster def random_with_N_digits(n): diff --git a/pyload/plugin/hoster/NitroflareCom.py b/pyload/plugin/hoster/NitroflareCom.py index dfe33e59c..d2bcd871d 100644 --- a/pyload/plugin/hoster/NitroflareCom.py +++ b/pyload/plugin/hoster/NitroflareCom.py @@ -2,7 +2,7 @@ import re -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/RapidgatorNet.py b/pyload/plugin/hoster/RapidgatorNet.py index 2af0001df..98a8b97c9 100644 --- a/pyload/plugin/hoster/RapidgatorNet.py +++ b/pyload/plugin/hoster/RapidgatorNet.py @@ -6,8 +6,10 @@ from pycurl import HTTPHEADER from pyload.utils import json_loads from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.CaptchaService import AdsCaptcha, ReCaptcha, SolveMedia -from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, secondsToMidnight +from pyload.plugin.captcha.AdsCaptcha import AdsCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha +from pyload.plugin.captcha.SolveMedia import SolveMedia +from pyload.plugin.internal.SimpleHoster import SimpleHoster, secondsToMidnight class RapidgatorNet(SimpleHoster): diff --git a/pyload/plugin/hoster/SoundcloudCom.py b/pyload/plugin/hoster/SoundcloudCom.py index 31aa7ba3c..524fb6e13 100644 --- a/pyload/plugin/hoster/SoundcloudCom.py +++ b/pyload/plugin/hoster/SoundcloudCom.py @@ -2,8 +2,8 @@ import re -from module.plugin.internal.SimpleHoster import SimpleHoster -from module.common.json_layer import json_loads +from pyload.plugin.internal.SimpleHoster import SimpleHoster +from pyload.utils import json_loads class SoundcloudCom(SimpleHoster): @@ -51,6 +51,3 @@ class SoundcloudCom(SimpleHoster): if http_streams: stream_name, self.link = http_streams[0 if self.getConfig('quality') == "Higher" else -1] pyfile.name += '.' + stream_name.split('_')[1].lower() - - -getInfo = create_getInfo(SoundcloudCom) diff --git a/pyload/plugin/hoster/UploadedTo.py b/pyload/plugin/hoster/UploadedTo.py index 165b29c7a..207817122 100644 --- a/pyload/plugin/hoster/UploadedTo.py +++ b/pyload/plugin/hoster/UploadedTo.py @@ -4,7 +4,7 @@ import re import time from pyload.network.RequestFactory import getURL -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/hoster/ZippyshareCom.py b/pyload/plugin/hoster/ZippyshareCom.py index 784eccb68..9b1d432cc 100644 --- a/pyload/plugin/hoster/ZippyshareCom.py +++ b/pyload/plugin/hoster/ZippyshareCom.py @@ -4,7 +4,7 @@ import re from BeautifulSoup import BeautifulSoup -from pyload.plugin.internal.CaptchaService import ReCaptcha +from pyload.plugin.captcha.ReCaptcha import ReCaptcha from pyload.plugin.internal.SimpleHoster import SimpleHoster diff --git a/pyload/plugin/internal/BasePlugin.py b/pyload/plugin/internal/BasePlugin.py index ed4da72a1..0b6e8f102 100644 --- a/pyload/plugin/internal/BasePlugin.py +++ b/pyload/plugin/internal/BasePlugin.py @@ -6,7 +6,7 @@ from urllib import unquote from urlparse import urljoin, urlparse from pyload.network.HTTPRequest import BadHeader -from pyload.plugin.internal.SimpleHoster import create_getInfo, getFileURL +from pyload.plugin.internal.SimpleHoster import getFileURL from pyload.plugin.Hoster import Hoster @@ -99,6 +99,3 @@ class BasePlugin(Hoster): self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry") self.retry(3, 60, errmsg) - - -getInfo = create_getInfo(BasePlugin) diff --git a/pyload/plugin/internal/MultiHook.py b/pyload/plugin/internal/MultiHook.py index d43956691..ab96d30ca 100644 --- a/pyload/plugin/internal/MultiHook.py +++ b/pyload/plugin/internal/MultiHook.py @@ -54,8 +54,6 @@ class MultiHook(Hook): def setup(self): - self.info = {} #@TODO: Remove in 0.4.10 - self.plugins = [] self.supported = [] self.new_supported = [] @@ -82,7 +80,7 @@ class MultiHook(Hook): self.pluginclass = getattr(self.pluginmodule, self.__name__) - def _loadAccount(self): + def loadAccount(self): self.account = self.core.accountManager.getAccountPlugin(self.pluginname) if self.account and not self.account.canUse(): @@ -94,7 +92,7 @@ class MultiHook(Hook): def activate(self): - self._loadAccount() + self.initPeriodical(threaded=True) def getURL(self, *args, **kwargs): #@TODO: Remove in 0.4.10 @@ -137,9 +135,9 @@ class MultiHook(Hook): return list() try: - configmode = self.getConfig("pluginmode", 'all') + configmode = self.getConfig('pluginmode', 'all') if configmode in ("listed", "unlisted"): - pluginlist = self.getConfig("pluginlist", '').replace('|', ',').replace(';', ',').split(',') + pluginlist = self.getConfig('pluginlist', '').replace('|', ',').replace(';', ',').split(',') configset = self._pluginSet(pluginlist) if configmode == "listed": @@ -183,24 +181,12 @@ class MultiHook(Hook): raise NotImplementedError - #: Threaded _periodical, remove in 0.4.10 and use built-in flag for that - def _periodical(self): - try: - if self.isActivated(): - self.periodical() - - except Exception, e: - self.core.log.error(_("Error executing hooks: %s") % str(e)) - if self.core.debug: - print_exc() - - self.cb = self.core.scheduler.addJob(self.interval, self._periodical) - - def periodical(self): """reload plugin list periodically""" - if self.getConfig("reload", True): - self.interval = max(self.getConfig("reloadinterval", 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) + self.loadAccount() + + if self.getConfig('reload', True): + self.interval = max(self.getConfig('reloadinterval', 12) * 60 * 60, self.MIN_RELOAD_INTERVAL) else: self.core.scheduler.removeJob(self.cb) self.cb = None diff --git a/pyload/plugin/internal/MultiHoster.py b/pyload/plugin/internal/MultiHoster.py index 036570805..e9bb483da 100644 --- a/pyload/plugin/internal/MultiHoster.py +++ b/pyload/plugin/internal/MultiHoster.py @@ -85,7 +85,7 @@ class MultiHoster(SimpleHoster): self.logWarning(_("Premium download failed")) self.retryFree() - elif self.getConfig("revertfailed", True) \ + elif self.getConfig('revertfailed', True) \ and "new_module" in self.core.pluginManager.hosterPlugins[self.__name__]: hdict = self.core.pluginManager.hosterPlugins[self.__name__] |