summaryrefslogtreecommitdiffstats
path: root/module/plugins/internal/CaptchaService.py
diff options
context:
space:
mode:
authorGravatar Walter Purcaro <vuolter@gmail.com> 2015-02-16 18:11:19 +0100
committerGravatar Walter Purcaro <vuolter@gmail.com> 2015-02-16 18:11:19 +0100
commit00e547899c7fcfd8bcfc61cd1cc5d0a8aec8cee5 (patch)
tree874064edf3723afbd30c54e14b489085e23f1ad7 /module/plugins/internal/CaptchaService.py
parentmodule temp (diff)
parent[ZippyshareCom] Update get_checksum (diff)
downloadpyload-00e547899c7fcfd8bcfc61cd1cc5d0a8aec8cee5.tar.xz
Merge branch 'stable' into 0.4.10
Conflicts: module/plugins/OCR.py module/plugins/accounts/BayfilesCom.py module/plugins/accounts/CatShareNet.py module/plugins/accounts/DebridItaliaCom.py module/plugins/accounts/FourSharedCom.py module/plugins/accounts/FshareVn.py module/plugins/accounts/Keep2ShareCc.py module/plugins/accounts/LomafileCom.py module/plugins/accounts/RapiduNet.py module/plugins/accounts/RyushareCom.py module/plugins/accounts/ShareonlineBiz.py module/plugins/addon/Checksum.py module/plugins/addon/ExternalScripts.py module/plugins/addon/ExtractArchive.py module/plugins/addon/MergeFiles.py module/plugins/addon/RestartSlow.py module/plugins/addon/SkipRev.py module/plugins/addon/UnSkipOnFail.py module/plugins/addon/UpdateManager.py module/plugins/addon/WindowsPhoneToastNotify.py module/plugins/container/CCF.py module/plugins/container/LinkList.py module/plugins/container/RSDF.py module/plugins/crypter/BitshareCom.py module/plugins/crypter/CrockoCom.py module/plugins/crypter/DataHu.py module/plugins/crypter/DepositfilesCom.py module/plugins/crypter/Dereferer.py module/plugins/crypter/DevhostStFolder.py module/plugins/crypter/DlProtectCom.py module/plugins/crypter/DontKnowMe.py module/plugins/crypter/EasybytezCom.py module/plugins/crypter/FilecloudIo.py module/plugins/crypter/FilecryptCc.py module/plugins/crypter/FilefactoryCom.py module/plugins/crypter/FilerNet.py module/plugins/crypter/FilestubeCom.py module/plugins/crypter/FiletramCom.py module/plugins/crypter/FreakhareCom.py module/plugins/crypter/FreetexthostCom.py module/plugins/crypter/FshareVn.py module/plugins/crypter/ImgurComAlbum.py module/plugins/crypter/JunocloudMe.py module/plugins/crypter/LinkSaveIn.py module/plugins/crypter/MegaRapidCz.py module/plugins/crypter/MultiUpOrg.py module/plugins/crypter/NetfolderIn.py module/plugins/crypter/NosvideoCom.py module/plugins/crypter/OneKhDe.py module/plugins/crypter/PastebinCom.py module/plugins/crypter/RapidfileshareNet.py module/plugins/crypter/RelinkUs.py module/plugins/crypter/TnyCz.py module/plugins/crypter/TurbobitNet.py module/plugins/crypter/TusfilesNet.py module/plugins/crypter/UploadableCh.py module/plugins/crypter/UploadedTo.py module/plugins/crypter/XFileSharingPro.py module/plugins/hooks/AlldebridCom.py module/plugins/hooks/BypassCaptcha.py module/plugins/hooks/Captcha9Kw.py module/plugins/hooks/CaptchaBrotherhood.py module/plugins/hooks/ClickAndLoad.py module/plugins/hooks/DeathByCaptcha.py module/plugins/hooks/DebridItaliaCom.py module/plugins/hooks/EasybytezCom.py module/plugins/hooks/ExpertDecoders.py module/plugins/hooks/FastixRu.py module/plugins/hooks/FreeWayMe.py module/plugins/hooks/ImageTyperz.py module/plugins/hooks/LinkdecrypterCom.py module/plugins/hooks/LinksnappyCom.py module/plugins/hooks/MegaDebridEu.py module/plugins/hooks/MultishareCz.py module/plugins/hooks/MyfastfileCom.py module/plugins/hooks/OverLoadMe.py module/plugins/hooks/PremiumTo.py module/plugins/hooks/PremiumizeMe.py module/plugins/hooks/RPNetBiz.py module/plugins/hooks/RealdebridCom.py module/plugins/hooks/RehostTo.py module/plugins/hooks/SimplyPremiumCom.py module/plugins/hooks/SimplydebridCom.py module/plugins/hooks/UnrestrictLi.py module/plugins/hooks/XFileSharingPro.py module/plugins/hooks/ZeveraCom.py module/plugins/hoster/AlldebridCom.py module/plugins/hoster/BayfilesCom.py module/plugins/hoster/DebridItaliaCom.py module/plugins/hoster/DepositfilesCom.py module/plugins/hoster/DodanePl.py module/plugins/hoster/ExtabitCom.py module/plugins/hoster/FastixRu.py module/plugins/hoster/FastshareCz.py module/plugins/hoster/FileParadoxIn.py module/plugins/hoster/FileSharkPl.py module/plugins/hoster/FilerNet.py module/plugins/hoster/FileserveCom.py module/plugins/hoster/FreakshareCom.py module/plugins/hoster/FreeWayMe.py module/plugins/hoster/GigapetaCom.py module/plugins/hoster/IfileIt.py module/plugins/hoster/Keep2ShareCc.py module/plugins/hoster/LetitbitNet.py module/plugins/hoster/LinksnappyCom.py module/plugins/hoster/LomafileCom.py module/plugins/hoster/MegaCoNz.py module/plugins/hoster/MegaDebridEu.py module/plugins/hoster/MegaRapidCz.py module/plugins/hoster/MyfastfileCom.py module/plugins/hoster/OverLoadMe.py module/plugins/hoster/PremiumTo.py module/plugins/hoster/PremiumizeMe.py module/plugins/hoster/RPNetBiz.py module/plugins/hoster/RapidgatorNet.py module/plugins/hoster/RealdebridCom.py module/plugins/hoster/RehostTo.py module/plugins/hoster/RyushareCom.py module/plugins/hoster/SendmywayCom.py module/plugins/hoster/ShareonlineBiz.py module/plugins/hoster/SimplyPremiumCom.py module/plugins/hoster/SimplydebridCom.py module/plugins/hoster/TusfilesNet.py module/plugins/hoster/UnibytesCom.py module/plugins/hoster/UnrestrictLi.py module/plugins/hoster/UploadedTo.py module/plugins/hoster/WebshareCz.py module/plugins/hoster/XFileSharingPro.py module/plugins/hoster/YoutubeCom.py module/plugins/hoster/ZeveraCom.py module/plugins/hoster/ZippyshareCom.py module/plugins/internal/AbstractExtractor.py module/plugins/internal/BasePlugin.py module/plugins/internal/CaptchaService.py module/plugins/internal/DeadCrypter.py module/plugins/internal/DeadHoster.py module/plugins/internal/MultiHoster.py module/plugins/internal/SimpleCrypter.py module/plugins/internal/SimpleHoster.py module/plugins/internal/UnRar.py module/plugins/internal/UnZip.py module/plugins/internal/XFSCrypter.py module/plugins/internal/XFSHoster.py
Diffstat (limited to 'module/plugins/internal/CaptchaService.py')
-rw-r--r--module/plugins/internal/CaptchaService.py522
1 files changed, 522 insertions, 0 deletions
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
new file mode 100644
index 000000000..6f2c8e06d
--- /dev/null
+++ b/module/plugins/internal/CaptchaService.py
@@ -0,0 +1,522 @@
+# -*- 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"
+ __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"
+ __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"
+ __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"
+ __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"
+ __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