diff options
Diffstat (limited to 'module/plugins/internal')
-rw-r--r-- | module/plugins/internal/CaptchaService.py | 172 | ||||
-rw-r--r-- | module/plugins/internal/MultiHook.py | 14 | ||||
-rw-r--r-- | module/plugins/internal/MultiHoster.py | 3 | ||||
-rw-r--r-- | module/plugins/internal/SimpleCrypter.py | 18 | ||||
-rw-r--r-- | module/plugins/internal/SimpleDereferer.py | 6 | ||||
-rw-r--r-- | module/plugins/internal/SimpleHoster.py | 110 | ||||
-rw-r--r-- | module/plugins/internal/UnRar.py | 2 | ||||
-rw-r--r-- | module/plugins/internal/XFSHoster.py | 30 |
8 files changed, 253 insertions, 102 deletions
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/MultiHook.py b/module/plugins/internal/MultiHook.py index a3b266679..795565d73 100644 --- a/module/plugins/internal/MultiHook.py +++ b/module/plugins/internal/MultiHook.py @@ -11,7 +11,7 @@ from module.utils import decode, remove_chars class MultiHook(Hook): __name__ = "MultiHook" __type__ = "hook" - __version__ = "0.35" + __version__ = "0.36" __config__ = [("pluginmode" , "all;listed;unlisted", "Use for plugins" , "all"), ("pluginlist" , "str" , "Plugin list (comma separated)" , "" ), @@ -48,7 +48,7 @@ class MultiHook(Hook): (r'uploaded\.net' , "uploaded.to" ), (r'uploadhero\.co' , "uploadhero.com" ), (r'zshares\.net' , "zshare.net" ), - (r'\d+.+' , "X\0" )] + (r'(\d+.+)' , "X\1" )] def setup(self): @@ -118,15 +118,15 @@ class MultiHook(Hook): def pluginsCached(self): if self.plugins: return self.plugins - + for _i in xrange(3): try: pluginset = self._pluginSet(self.getHosters() if self.plugintype == "hoster" else self.getCrypters()) - + except Exception, e: self.logError(e, "Waiting 1 minute and retry") sleep(60) - + else: break else: @@ -293,12 +293,16 @@ class MultiHook(Hook): self.logDebug("Unload MultiHook", pyfile.pluginname, hdict) self.unloadPlugin(pyfile.pluginname) pyfile.setStatus("queued") + pyfile.sync() else: retries = max(self.getConfig("retry", 10), 0) wait_time = max(self.getConfig("retryinterval", 1), 0) if 0 < retries > pyfile.plugin.retries: + self.logInfo(_("Retrying: %s") % pyfile.name) pyfile.setCustomStatus("MultiHook", "queued") + pyfile.sync() + pyfile.plugin.retries += 1 pyfile.plugin.setWait(wait_time) pyfile.plugin.wait() diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py index 8ca4d427f..ba613c997 100644 --- a/module/plugins/internal/MultiHoster.py +++ b/module/plugins/internal/MultiHoster.py @@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, r class MultiHoster(SimpleHoster): __name__ = "MultiHoster" __type__ = "hoster" - __version__ = "0.32" + __version__ = "0.33" __pattern__ = r'^unmatchable$' @@ -17,7 +17,6 @@ class MultiHoster(SimpleHoster): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - CHECK_TRAFFIC = True LOGIN_ACCOUNT = True diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 43b1347fd..2e2f2ca0d 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -2,7 +2,7 @@ import re -from urlparse import urlparse +from urlparse import urljoin, urlparse from module.plugins.Crypter import Crypter from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookies @@ -12,7 +12,7 @@ from module.utils import fixup class SimpleCrypter(Crypter, SimpleHoster): __name__ = "SimpleCrypter" __type__ = "crypter" - __version__ = "0.38" + __version__ = "0.41" __pattern__ = r'^unmatchable$' __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), #: Overrides core.config['general']['folder_per_package'] @@ -71,12 +71,12 @@ class SimpleCrypter(Crypter, SimpleHoster): #@TODO: Remove in 0.4.10 def init(self): account_name = (self.__name__ + ".py").replace("Folder.py", "").replace(".py", "") - account = self.core.accountManager.getAccountPlugin(account_name) + account = self.pyfile.m.core.accountManager.getAccountPlugin(account_name) if account and account.canUse(): self.user, data = account.selectAccount() - self.req = account.getAccountRequest(self.user) - self.premium = account.isPremium(self.user) + self.req = account.getAccountRequest(self.user) + self.premium = account.isPremium(self.user) self.account = account @@ -151,13 +151,17 @@ class SimpleCrypter(Crypter, SimpleHoster): Returns the links extracted from self.html You should override this only if it's impossible to extract links using only the LINK_PATTERN. """ - return re.findall(self.LINK_PATTERN, self.html) + parsed = urlparse(self.pyfile.url) + base = "%s://%s" % (parsed.scheme, parsed.netloc) + + return [urljoin(base, link) if not urlparse(link).scheme else link \ + for link in re.findall(self.LINK_PATTERN, self.html)] def handlePages(self, pyfile): try: pages = int(re.search(self.PAGES_PATTERN, self.html).group(1)) - except: + except Exception: pages = 1 for p in xrange(2, pages + 1): diff --git a/module/plugins/internal/SimpleDereferer.py b/module/plugins/internal/SimpleDereferer.py index 53b80f827..deef42620 100644 --- a/module/plugins/internal/SimpleDereferer.py +++ b/module/plugins/internal/SimpleDereferer.py @@ -5,13 +5,13 @@ import re from urllib import unquote from module.plugins.Crypter import Crypter -from module.plugins.internal.SimpleHoster import directLink, set_cookies +from module.plugins.internal.SimpleHoster import fileUrl, set_cookies class SimpleDereferer(Crypter): __name__ = "SimpleDereferer" __type__ = "crypter" - __version__ = "0.03" + __version__ = "0.04" __pattern__ = r'^unmatchable$' __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), @@ -45,7 +45,7 @@ class SimpleDereferer(Crypter): def decrypt(self, pyfile): - link = directLink(self, pyfile.url) + link = fileUrl(self, pyfile.url) if not link: try: diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 5a32ac943..c1982ee67 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- +import mimetypes +import os import re +from datetime import datetime, timedelta from inspect import isclass -from os.path import exists from time import time from urllib import unquote from urlparse import urljoin, urlparse @@ -106,7 +108,13 @@ def parseFileInfo(plugin, url="", html=""): info = plugin.getInfo(url, html) res = info['name'], info['size'], info['status'], info['url'] else: - res = urlparse(unquote(url)).path.split('/')[-1] or _("Unknown"), 0, 3, url + url = unquote(url) + res = ((urlparse(url).path.split('/')[-1] + or urlparse(url).query.split('=', 1)[::-1][0].split('&', 1)[0] + or _("Unknown")), + 0, + 3 if url else 8, + url) return res @@ -114,10 +122,15 @@ def parseFileInfo(plugin, url="", html=""): #@TODO: Remove in 0.4.10 #@NOTE: Every plugin must have own parseInfos classmethod to work with 0.4.10 def create_getInfo(plugin): + + def generator(list): + for x in list: + yield x + if hasattr(plugin, "parseInfos"): - fn = lambda urls: [(info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfos(urls)] + fn = lambda urls: generator((info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfos(urls)) else: - fn = lambda urls: [parseFileInfo(url) for url in urls] + fn = lambda urls: generator(parseFileInfo(url) for url in urls) return fn @@ -127,35 +140,58 @@ def timestamp(): #@TODO: Move to hoster class in 0.4.10 -def directLink(self, url, resumable=False): - link = "" +def fileUrl(self, url, follow_location=False): + link = "" + redirect = 1 + + if isinstance(follow_location, int): + redirect = max(follow_location, 1) + + elif follow_location: + redirect = 5 + + for i in xrange(redirect): + self.logDebug("Redirect #%d to: %s" % (i, url)) - for i in xrange(5 if resumable else 1): header = self.load(url, ref=True, cookies=True, just_header=True, decode=True) if 'content-disposition' in header: link = url - elif 'location' in header and header['location']: + elif 'location' in header and header['location'].strip(): location = header['location'] if not urlparse(location).scheme: - p = urlparse(url) - base = "%s://%s" % (p.scheme, p.netloc) - location = urljoin(base, location) + url_p = urlparse(url) + baseurl = "%s://%s" % (url_p.scheme, url_p.netloc) + location = urljoin(baseurl, location) + + if 'code' in header and header['code'] == 302: + link = location - if resumable: + if follow_location: url = location - self.logDebug("Redirect #%d to: %s" % (++i, location)) continue - elif 'code' in header and header['code'] == 302: - link = location + else: + extension = os.path.splitext(urlparse(url).path.split('/')[-1])[-1] - elif 'content-type' in header and header['content-type'] and "html" not in header['content-type']: - link = url + if 'content-type' in header and header['content-type'].strip(): + mimetype = header['content-type'].split(';')[0].strip() + + elif extension: + mimetype = mimetypes.guess_extension(extension, False)[0] or "application/octet-stream" + + else: + mimetype = "" + + if mimetype and (link or 'html' not in mimetype): + link = url + else: + link = "" break + else: self.logError(_("Too many redirects")) @@ -183,7 +219,7 @@ def secondsToMidnight(gmt=0): class SimpleHoster(Hoster): __name__ = "SimpleHoster" __type__ = "hoster" - __version__ = "0.94" + __version__ = "1.01" __pattern__ = r'^unmatchable$' @@ -247,7 +283,7 @@ class SimpleHoster(Hoster): MULTI_HOSTER = False #: Set to True to leech other hoster link (as defined in handleMulti method) LOGIN_ACCOUNT = False #: Set to True to require account login - directLink = directLink #@TODO: Remove in 0.4.10 + directLink = fileUrl #@TODO: Remove in 0.4.10 @classmethod @@ -328,9 +364,6 @@ class SimpleHoster(Hoster): else: online = True - if not info['pattern']: - info.pop('pattern', None) - if online: info['status'] = 2 @@ -351,6 +384,9 @@ class SimpleHoster(Hoster): hashtype = info['pattern']['T'] if 'T' in info['pattern'] else "hash" info[hashtype] = info['pattern']['H'] + if not info['pattern']: + info.pop('pattern', None) + return info @@ -439,9 +475,9 @@ class SimpleHoster(Hoster): self.invalidCaptcha() self.retry(10, reason=_("Wrong captcha")) - elif not self.lastDownload or not exists(fs_encode(self.lastDownload)): + elif not self.lastDownload or not os.path.exists(fs_encode(self.lastDownload)): self.lastDownload = "" - self.fail(self.pyfile.error or _("No file downloaded")) + self.error(self.pyfile.error or _("No file downloaded")) else: rules = {'empty file': re.compile(r'\A\Z'), @@ -553,7 +589,7 @@ class SimpleHoster(Hoster): def handleDirect(self, pyfile): - link = self.directLink(pyfile.url, self.resumeDownload) + link = self.fileUrl(pyfile.url, self.resumeDownload) if link: self.logInfo(_("Direct download link detected")) @@ -571,16 +607,12 @@ class SimpleHoster(Hoster): if not hasattr(self, 'LINK_FREE_PATTERN'): self.logError(_("Free download not implemented")) - try: - m = re.search(self.LINK_FREE_PATTERN, self.html) - if m is None: - self.error(_("Free download link not found")) - + m = re.search(self.LINK_FREE_PATTERN, self.html) + if m is None: + self.error(_("Free download link not found")) + else: self.link = m.group(1) - except Exception, e: - self.fail(e) - def handlePremium(self, pyfile): if not hasattr(self, 'LINK_PREMIUM_PATTERN'): @@ -588,16 +620,12 @@ class SimpleHoster(Hoster): self.logDebug("Handled as free download") self.handleFree(pyfile) - try: - m = re.search(self.LINK_PREMIUM_PATTERN, self.html) - if m is None: - self.error(_("Premium download link not found")) - + m = re.search(self.LINK_PREMIUM_PATTERN, self.html) + if m is None: + self.error(_("Premium download link not found")) + else: self.link = m.group(1) - except Exception, e: - self.fail(e) - def longWait(self, wait_time=None, max_tries=3): if wait_time and isinstance(wait_time, (int, long, float)): diff --git a/module/plugins/internal/UnRar.py b/module/plugins/internal/UnRar.py index 572fe95b9..296405101 100644 --- a/module/plugins/internal/UnRar.py +++ b/module/plugins/internal/UnRar.py @@ -16,7 +16,7 @@ def renice(pid, value): if os.name != "nt" and value: try: Popen(["renice", str(value), str(pid)], stdout=PIPE, stderr=PIPE, bufsize=-1) - except: + except Exception: print "Renice failed" diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py index b32f5978f..bae75c092 100644 --- a/module/plugins/internal/XFSHoster.py +++ b/module/plugins/internal/XFSHoster.py @@ -15,7 +15,7 @@ from module.utils import html_unescape class XFSHoster(SimpleHoster): __name__ = "XFSHoster" __type__ = "hoster" - __version__ = "0.35" + __version__ = "0.36" __pattern__ = r'^unmatchable$' @@ -63,10 +63,28 @@ class XFSHoster(SimpleHoster): def prepare(self): """ Initialize important variables """ if not self.HOSTER_DOMAIN: - self.fail(_("Missing HOSTER_DOMAIN")) + if self.account: + account = self.account + else: + account = self.pyfile.m.core.accountManager.getAccountPlugin(self.__name__) + + if account and hasattr(account, "HOSTER_DOMAIN") and account.HOSTER_DOMAIN: + self.HOSTER_DOMAIN = account.HOSTER_DOMAIN + else: + self.fail(_("Missing HOSTER_DOMAIN")) + + try: + self.COOKIES.index((None, "lang", "english")) + + except ValueError: + pass + + else: + self.COOKIES.remove((None, "lang", "english")) + self.COOKIES.insert((self.HOSTER_DOMAIN, "lang", "english")) if not self.LINK_PATTERN: - pattern = r'(https?://(www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<]' + pattern = r'(https?://(?:www\.)?([^/]*?%s|\d+\.\d+\.\d+\.\d+)(\:\d+)?(/d/|(/files)?/\d+/\w+/).+?)["\'<]' self.LINK_PATTERN = pattern % self.HOSTER_DOMAIN.replace('.', '\.') self.captcha = None @@ -75,7 +93,7 @@ class XFSHoster(SimpleHoster): super(XFSHoster, self).prepare() if self.DIRECT_LINK is None: - self.directDL = bool(self.premium) + self.directDL = self.premium def downloadLink(self, link): @@ -311,7 +329,7 @@ class XFSHoster(SimpleHoster): recaptcha = ReCaptcha(self) try: captcha_key = re.search(self.RECAPTCHA_PATTERN, self.html).group(1) - except: + except Exception: captcha_key = recaptcha.detect_key() else: self.logDebug("ReCaptcha key: %s" % captcha_key) @@ -323,7 +341,7 @@ class XFSHoster(SimpleHoster): solvemedia = SolveMedia(self) try: captcha_key = re.search(self.SOLVEMEDIA_PATTERN, self.html).group(1) - except: + except Exception: captcha_key = solvemedia.detect_key() else: self.logDebug("SolveMedia key: %s" % captcha_key) |