diff options
Diffstat (limited to 'module')
-rw-r--r-- | module/plugins/accounts/CatShareNet.py | 7 | ||||
-rw-r--r-- | module/plugins/hooks/AndroidPhoneNotify.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/ExternalScripts.py | 6 | ||||
-rw-r--r-- | module/plugins/hooks/ExtractArchive.py | 42 | ||||
-rw-r--r-- | module/plugins/hooks/LinkdecrypterCom.py | 9 | ||||
-rw-r--r-- | module/plugins/hooks/SkipRev.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/UpdateManager.py | 4 | ||||
-rw-r--r-- | module/plugins/hooks/WindowsPhoneToastNotify.py | 4 | ||||
-rw-r--r-- | module/plugins/hoster/CatShareNet.py | 9 | ||||
-rw-r--r-- | module/plugins/hoster/WebshareCz.py | 4 | ||||
-rw-r--r-- | module/plugins/hoster/ZippyshareCom.py | 4 | ||||
-rw-r--r-- | module/plugins/internal/CaptchaService.py | 172 | ||||
-rw-r--r-- | module/plugins/internal/SimpleHoster.py | 23 |
13 files changed, 203 insertions, 89 deletions
diff --git a/module/plugins/accounts/CatShareNet.py b/module/plugins/accounts/CatShareNet.py index 90cdfe013..2552521e4 100644 --- a/module/plugins/accounts/CatShareNet.py +++ b/module/plugins/accounts/CatShareNet.py @@ -19,11 +19,13 @@ class CatShareNet(Account): PREMIUM_PATTERN = r'class="nav-collapse collapse pull-right">[\s\w<>=-."/:]*\sz.</a></li>\s*<li><a href="/premium">.*\s*<span style="color: red">(.*?)</span>[\s\w<>/]*href="/logout"' VALID_UNTIL_PATTERN = r'<div class="span6 pull-right">[\s\w<>=-":;]*<span style="font-size:13px;">.*?<strong>(.*?)</strong></span>' + TRAFFIC_PATTERN = r'<a href="/premium">([0-9.]+ [kMG]B)' def loadAccountInfo(self, user, req): premium = False validuntil = -1 + trafficleft = -1 html = req.load("http://catshare.net/", decode=True) @@ -39,10 +41,13 @@ class CatShareNet(Account): expiredate = m.group(1) if "-" not in expiredate: validuntil = mktime(strptime(expiredate, "%d.%m.%Y")) + m = re.search(TRAFFIC_PATTERN, html) + if m: + trafficleft = int(self.parseTraffic(m.group(1))) except Exception: pass - return {'premium': premium, 'trafficleft': -1, 'validuntil': validuntil} + return {'premium': premium, 'trafficleft': trafficleft, 'validuntil': validuntil} def login(self, user, data, req): diff --git a/module/plugins/hooks/AndroidPhoneNotify.py b/module/plugins/hooks/AndroidPhoneNotify.py index 18e1cce66..fbc2acd5c 100644 --- a/module/plugins/hooks/AndroidPhoneNotify.py +++ b/module/plugins/hooks/AndroidPhoneNotify.py @@ -9,7 +9,7 @@ from module.plugins.Hook import Hook class AndroidPhoneNotify(Hook): __name__ = "AndroidPhoneNotify" __type__ = "hook" - __version__ = "0.02" + __version__ = "0.03" __config__ = [("apikey" , "str" , "API key" , "" ), ("notifycaptcha" , "bool", "Notify captcha request" , True ), @@ -51,7 +51,7 @@ class AndroidPhoneNotify(Hook): self.notify(_("Package finished"), pypack.name) - def allDownloadsProcessed(self, thread): + def allDownloadsProcessed(self): if not self.getConfig("notifyprocessed"): return False diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index f4d2cb69c..b2b4548a2 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -13,7 +13,7 @@ from module.utils import save_join class ExternalScripts(Hook): __name__ = "ExternalScripts" __type__ = "hook" - __version__ = "0.26" + __version__ = "0.27" __config__ = [("activated", "bool", "Activated", True)] @@ -136,11 +136,11 @@ class ExternalScripts(Hook): self.callScript(script) - def allDownloadsFinished(self, thread): + def allDownloadsFinished(self): for script in chain(self.scripts['all_downloads_finished'], self.scripts['all_dls_finished']): self.callScript(script) - def allDownloadsProcessed(self, thread): + def allDownloadsProcessed(self): for script in chain(self.scripts['all_downloads_processed'], self.scripts['all_dls_processed']): self.callScript(script) diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index 2e9efa2b0..bdbaf64af 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -58,7 +58,7 @@ from module.utils import save_join, uniqify class ExtractArchive(Hook): __name__ = "ExtractArchive" __type__ = "hook" - __version__ = "1.03" + __version__ = "1.04" __config__ = [("activated" , "bool" , "Activated" , True ), ("fullpath" , "bool" , "Extract full path" , True ), @@ -158,7 +158,7 @@ class ExtractArchive(Hook): @threaded - def allDownloadsProcessed(self, thread): + def allDownloadsProcessed(self): local = copy(self.queue) self.queue[:] = [] @@ -302,36 +302,36 @@ class ExtractArchive(Hook): try: progress = lambda x: pyfile.setProgress(x) - encrypted = False + encrypted = True #@TODO: set to `False` passwords = self.getPasswords() - try: - self.logInfo(basename(plugin.file), "Verifying...") + # try: + # self.logInfo(basename(plugin.file), "Verifying...") - tmp_password = plugin.password - plugin.password = "" #: Force verifying without password + # tmp_password = plugin.password + # plugin.password = "" #: Force verifying without password - plugin.verify() + # plugin.verify() - except PasswordError: - encrypted = True + # except PasswordError: + # encrypted = True - except CRCError: - self.logWarning(basename(plugin.file), _("Archive damaged")) + # except CRCError: + # self.logWarning(basename(plugin.file), _("Archive damaged")) - if not self.getConfig("repair"): - raise CRCError + # if not self.getConfig("repair"): + # raise CRCError - elif plugin.repair(): - self.logInfo(basename(plugin.file), _("Successfully repaired")) + # elif plugin.repair(): + # self.logInfo(basename(plugin.file), _("Successfully repaired")) - elif not self.getConfig("keepbroken"): - raise ArchiveError(_("Broken archive")) + # elif not self.getConfig("keepbroken"): + # raise ArchiveError(_("Broken archive")) - else: - self.logInfo(basename(plugin.file), _("All OK")) + # else: + # self.logInfo(basename(plugin.file), _("All OK")) - plugin.password = tmp_password + # plugin.password = tmp_password if not encrypted: plugin.extract(progress) diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py index d4924a687..f85a598bc 100644 --- a/module/plugins/hooks/LinkdecrypterCom.py +++ b/module/plugins/hooks/LinkdecrypterCom.py @@ -8,7 +8,7 @@ from module.plugins.internal.MultiHook import MultiHook class LinkdecrypterCom(MultiHook): __name__ = "LinkdecrypterCom" __type__ = "hook" - __version__ = "1.01" + __version__ = "1.02" __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ), @@ -21,8 +21,5 @@ class LinkdecrypterCom(MultiHook): def getCrypters(self): - try: - html = self.getURL("http://linkdecrypter.com/") - return re.search(r'>Supported\(\d+\)</b>: <i>(.+?) \+ RSDF', html).group(1).split(', ') - except Exception: - return list() + return re.search(r'>Supported\(\d+\)</b>: <i>(.[\w.\-, ]+)', + self.getURL("http://linkdecrypter.com/").replace("(g)", "")).group(1).split(', ') diff --git a/module/plugins/hooks/SkipRev.py b/module/plugins/hooks/SkipRev.py index 6b4e715da..51d385bb4 100644 --- a/module/plugins/hooks/SkipRev.py +++ b/module/plugins/hooks/SkipRev.py @@ -18,7 +18,7 @@ def _setup(self): class SkipRev(Hook): __name__ = "SkipRev" __type__ = "hook" - __version__ = "0.23" + __version__ = "0.24" __config__ = [("tokeep", "int", "Number of rev files to keep for package (-1 to auto)", -1)] @@ -34,7 +34,7 @@ class SkipRev(Hook): def _pyname(self, pyfile): if hasattr(pyfile.pluginmodule, "getInfo"): - return next(getattr(pyfile.pluginmodule, "getInfo")([pyfile.url]))[0] + return getattr(pyfile.pluginmodule, "getInfo")([pyfile.url]).next()[0] else: self.logWarning("Unable to grab file name") return urlparse(unquote(pyfile.url)).path.split('/')[-1] diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 03b9ba6a4..b6a8bac7c 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -16,14 +16,14 @@ from module.utils import save_join class UpdateManager(Hook): __name__ = "UpdateManager" __type__ = "hook" - __version__ = "0.42" + __version__ = "0.43" __config__ = [("activated" , "bool" , "Activated" , True ), ("mode" , "pyLoad + plugins;plugins only", "Check updates for" , "pyLoad + plugins"), ("interval" , "int" , "Check interval in hours" , 8 ), ("autorestart" , "bool" , "Automatically restart pyLoad when required" , True ), ("reloadplugins", "bool" , "Monitor plugins for code changes in debug mode", True ), - ("nodebugupdate", "bool" , "Don't check for updates in debug mode" , True )] + ("nodebugupdate", "bool" , "Don't check for updates in debug mode" , False )] __description__ = """ Check for updates """ __license__ = "GPLv3" diff --git a/module/plugins/hooks/WindowsPhoneToastNotify.py b/module/plugins/hooks/WindowsPhoneToastNotify.py index 886d4ca6a..20686ee36 100644 --- a/module/plugins/hooks/WindowsPhoneToastNotify.py +++ b/module/plugins/hooks/WindowsPhoneToastNotify.py @@ -10,7 +10,7 @@ from module.plugins.Hook import Hook class WindowsPhoneToastNotify(Hook): __name__ = "WindowsPhoneToastNotify" __type__ = "hook" - __version__ = "0.04" + __version__ = "0.05" __config__ = [("id" , "str" , "Push ID" , "" ), ("url" , "str" , "Push url" , "" ), @@ -53,7 +53,7 @@ class WindowsPhoneToastNotify(Hook): self.notify(_("Package finished"), pypack.name) - def allDownloadsProcessed(self, thread): + def allDownloadsProcessed(self): if not self.getConfig("notifyprocessed"): return False diff --git a/module/plugins/hoster/CatShareNet.py b/module/plugins/hoster/CatShareNet.py index f2ddd64a0..19598a092 100644 --- a/module/plugins/hoster/CatShareNet.py +++ b/module/plugins/hoster/CatShareNet.py @@ -28,6 +28,7 @@ class CatShareNet(SimpleHoster): IP_BLOCKED_PATTERN = ur'>Nasz serwis wykrył że Twój adres IP nie pochodzi z Polski.<' SECONDS_PATTERN = 'var\scount\s=\s(\d+);' LINK_FREE_PATTERN = r'<form action="(.+?)" method="GET">' + LINK_PREMIUM_PATTERN = r'<form action="(.+?)" method="GET">' def setup(self): @@ -41,6 +42,14 @@ class CatShareNet(SimpleHoster): self.fail(_("Only connections from Polish IP address are allowed")) return super(CatShareNet, self).getFileInfo() + def handlePremium(self): + m = re.search(self.LINK_PREMIUM_PATTERN, self.html) + if m is None: + self.fail(_("File not found")) + + dl_link = m.group(1) + self.download(dl_link, disposition=True) + def handleFree(self, pyfile): m = re.search(self.SECONDS_PATTERN, self.html) diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py index e3424fc21..98187d46a 100644 --- a/module/plugins/hoster/WebshareCz.py +++ b/module/plugins/hoster/WebshareCz.py @@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class WebshareCz(SimpleHoster): __name__ = "WebshareCz" __type__ = "hoster" - __version__ = "0.15" + __version__ = "0.16" __pattern__ = r'https?://(?:www\.)?webshare\.cz/(?:#/)?file/(?P<ID>\w+)' @@ -21,7 +21,7 @@ class WebshareCz(SimpleHoster): @classmethod def getInfo(cls, url="", html=""): - info = super(WebshareCz, self).getInfo(url, html) + info = super(WebshareCz, cls).getInfo(url, html) if url: info['pattern'] = re.match(cls.__pattern__, url).groupdict() diff --git a/module/plugins/hoster/ZippyshareCom.py b/module/plugins/hoster/ZippyshareCom.py index 2648f532f..39c8d36d6 100644 --- a/module/plugins/hoster/ZippyshareCom.py +++ b/module/plugins/hoster/ZippyshareCom.py @@ -10,9 +10,9 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class ZippyshareCom(SimpleHoster): __name__ = "ZippyshareCom" __type__ = "hoster" - __version__ = "0.66" + __version__ = "0.67" - __pattern__ = r'(?P<HOST>http://www\d{0,2}\.zippyshare\.com)/v(?:/|iew\.jsp.*key=)(?P<KEY>\d+)' + __pattern__ = r'(?P<HOST>http://www\d{0,2}\.zippyshare\.com)/v(?:/|iew\.jsp.*key=)(?P<KEY>[\w^_]+)' __description__ = """Zippyshare.com hoster plugin""" __license__ = "GPLv3" diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py index b429fd6e0..be6a056fc 100644 --- a/module/plugins/internal/CaptchaService.py +++ b/module/plugins/internal/CaptchaService.py @@ -1,16 +1,17 @@ # -*- coding: utf-8 -*- import re +import time +import base64 -from base64 import urlsafe_b64encode -from random import random +from random import random,randint from module.common.json_layer import json_loads class CaptchaService: __name__ = "CaptchaService" - __version__ = "0.16" + __version__ = "0.17" __description__ = """Base captcha service plugin""" __license__ = "GPLv3" @@ -55,14 +56,14 @@ class CaptchaService: class ReCaptcha(CaptchaService): __name__ = "ReCaptcha" - __version__ = "0.09" + __version__ = "0.08" __description__ = """ReCaptcha captcha service plugin""" __license__ = "GPLv3" __authors__ = [("pyLoad Team", "admin@pyload.org")] - KEY_PATTERN = r'(?:class="g-recaptcha"\s+data-sitekey="|recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=)([\w-]+)' + KEY_PATTERN = r'recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=([\w-]+)' KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\']([\w-]+)' @@ -85,7 +86,7 @@ class ReCaptcha(CaptchaService): return None - def challenge(self, key=None, userverify=False): + def challenge(self, key=None): if not key: if self.detect_key(): key = self.key @@ -98,30 +99,14 @@ class ReCaptcha(CaptchaService): try: challenge = re.search("challenge : '(.+?)',", html).group(1) server = re.search("server : '(.+?)',", html).group(1) - - except AttributeError: + except: errmsg = _("ReCaptcha challenge pattern not found") self.plugin.fail(errmsg) - raise AttributeError(errmsg) + raise ValueError(errmsg) self.plugin.logDebug("ReCaptcha challenge: %s" % challenge) - response = challenge, self.result(server, challenge) - - return self.userverify(*response) if userverify else response - - - def userverify(self, challenge, result): - response = self.plugin.req.load("https://www.google.com/recaptcha/api2/userverify", - post={'c' : challenge, - 'response': urlsafe_b64encode('{"response":"%s"}' % result)}) - try: - return re.search(r'"uvresp","(.+?)"', response).group(1) - - except AttributeError: - errmsg = _("ReCaptcha userverify response not found") - self.plugin.fail(errmsg) - raise AttributeError(errmsg) + return challenge, self.result(server, challenge) def result(self, server, challenge): @@ -136,6 +121,123 @@ class ReCaptcha(CaptchaService): return result +class ReCaptchaV2(CaptchaService): + __name__ = "ReCaptchaV2" + __version__ = "0.01" + + __description__ = """ReCaptchaV2 captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + KEY_PATTERN = r'data-sitekey="(.*?)">' + + + 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_PATTERN, html) + if m: + self.key = m.group(1).strip() + self.plugin.logDebug("ReCaptcha key: %s" % self.key) + return self.key + else: + self.plugin.logDebug("ReCaptcha key not found") + return None + + + def collectApiInfo(self): + html = self.plugin.req.load("http://www.google.com/recaptcha/api.js",cookies=True) + a = re.search("po.src = '(.*?)';",html).group(1) + vers = a.split("/")[5] + self.plugin.logDebug("API version: %s" %vers) + language = a.split("__")[1].split(".")[0] + self.plugin.logDebug("API language: %s" %language) + + html = self.plugin.req.load("https://apis.google.com/js/api.js",cookies=True) + b = re.search('"h":"(.*?)","',html).group(1) + jsh = b.decode('unicode-escape') + self.plugin.logDebug("API jsh-string: %s" %jsh) + + return vers,language,jsh + + def prepareTimeAndRpc(self): + html = self.plugin.req.load("http://www.google.com/recaptcha/api2/demo",cookies=True) + + millis = int(round(time.time() * 1000)) + self.plugin.logDebug("Systemtime in milliseconds: %s" %str(millis)) + + rand = randint(1,99999999) + a = "0.%s"%str(rand*2147483647) + rpc = int(100000000*float(a)) + self.plugin.logDebug("Self-generated rpc-token: %s" %str(rpc)) + + return millis,rpc + + def doTheCaptcha(self, host): + self.plugin.logDebug("Parent host: %s" %host) + botguardstring = "!A" + sitekey = self.detect_key() + vers,language,jsh = self.collectApiInfo() + millis,rpc = self.prepareTimeAndRpc() + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/anchor", + get={"k":sitekey, + "hl":language, + "v":vers, + "usegapi":"1", + "jsh":jsh+"#id=IO_"+str(millis), + "parent":"http://"+host, + "pfname":"", + "rpctoken":rpc}, + cookies=True) + recaptchatoken = re.search('id="recaptcha-token" value="(.*?)">',html) + self.plugin.logDebug("Captchatoken #1: %s" %recaptchatoken.group(1)) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/frame", get={"c":recaptchatoken.group(1), + "hl":language, + "v":vers, + "bg":botguardstring, + "usegapi":"1", + "jsh":jsh}, + cookies=True) + html = html.decode('unicode-escape') + recaptchatoken2 = re.search('"finput","(.*?)",',html) + self.plugin.logDebug("Captchatoken #2: %s" %recaptchatoken2.group(1)) + recaptchatoken3 = re.search('."asconf".\s.\s,"(.*?)".',html) + self.plugin.logDebug("Captchatoken #3: %s" %recaptchatoken3.group(1)) + + html = self.plugin.req.load("https://www.google.com/recaptcha/api2/reload", post={"c":recaptchatoken2.group(1), + "reason":"fi", + "fbg":recaptchatoken3.group(1)}, + cookies=True) + recaptchatoken4 = re.search('"rresp","(.*?)",',html) + self.plugin.logDebug("Captchatoken #4: %s" %recaptchatoken4.group(1)) + + millis_captcha_loading = int(round(time.time() * 1000)) + captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload", get={"c":recaptchatoken4.group(1)},forceUser=True) + respone_encoded = base64.b64encode('{"response":"%s"}' %captcha_response) + self.plugin.logDebug("Encoded result: %s" %respone_encoded) + + 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", cookies=True, post={"c":recaptchatoken4.group(1), + "response":respone_encoded, + "t":timeToSolve, + "ct":timeToSolveMore, + "bg":botguardstring}) + recaptchatoken5 = re.search('"uvresp","(.*?)",',html) + self.plugin.logDebug("Captchatoken #5: %s" %recaptchatoken5.group(1)) + + return recaptchatoken5.group(1) + + class AdsCaptcha(CaptchaService): __name__ = "AdsCaptcha" __version__ = "0.06" @@ -184,11 +286,10 @@ class AdsCaptcha(CaptchaService): try: challenge = re.search("challenge: '(.+?)',", html).group(1) server = re.search("server: '(.+?)',", html).group(1) - - except AttributeError: + except: errmsg = _("AdsCaptcha challenge pattern not found") self.plugin.fail(errmsg) - raise AttributeError(errmsg) + raise ValueError(errmsg) self.plugin.logDebug("AdsCaptcha challenge: %s" % challenge) @@ -232,11 +333,10 @@ class SolveMedia(CaptchaService): 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: + except: errmsg = _("SolveMedia challenge pattern not found") self.plugin.fail(errmsg) - raise AttributeError(errmsg) + raise ValueError(errmsg) self.plugin.logDebug("SolveMedia challenge: %s" % challenge) @@ -305,11 +405,10 @@ class AdYouLike(CaptchaService): 'callback': callback}) try: challenge = json_loads(re.search(callback + r'\s*\((.+?)\)', html).group(1)) - - except AttributeError: + except: errmsg = _("AdYouLike challenge pattern not found") self.plugin.fail(errmsg) - raise AttributeError(errmsg) + raise ValueError(errmsg) self.plugin.logDebug("AdYouLike challenge: %s" % challenge) @@ -336,11 +435,10 @@ class AdYouLike(CaptchaService): try: instructions_visual = challenge['translations'][server['all']['lang']]['instructions_visual'] result = re.search(u'«(.+?)»', instructions_visual).group(1).strip() - - except AttributeError: + except: errmsg = _("AdYouLike result not found") self.plugin.fail(errmsg) - raise AttributeError(errmsg) + raise ValueError(errmsg) result = {'_ayl_captcha_engine' : "adyoulike", '_ayl_env' : server['all']['env'], diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 2b87c5996..4d7329541 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -137,6 +137,8 @@ def directLink(self, url, resumable=False): link = "" for i in xrange(5 if resumable else 1): + self.logDebug("Redirect #%d to: %s" % (i, url)) + header = self.load(url, ref=True, cookies=True, just_header=True, decode=True) if 'content-disposition' in header: @@ -150,18 +152,21 @@ def directLink(self, url, resumable=False): base = "%s://%s" % (parsed.scheme, parsed.netloc) location = urljoin(base, location) - if resumable: - url = location - self.logDebug("Redirect #%d to: %s" % (++i, location)) - continue - - elif 'code' in header and header['code'] == 302: + if 'code' in header and header['code'] == 302: link = location - elif 'content-type' in header and header['content-type'] and "html" not in header['content-type']: - link = url + url = location + continue + + elif 'content-type' in header: + if "html" not in header['content-type']: + link = url + + elif link: + link = "" break + else: self.logError(_("Too many redirects")) @@ -189,7 +194,7 @@ def secondsToMidnight(gmt=0): class SimpleHoster(Hoster): __name__ = "SimpleHoster" __type__ = "hoster" - __version__ = "0.99" + __version__ = "1.00" __pattern__ = r'^unmatchable$' |