summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Walter Purcaro <vuolter@users.noreply.github.com> 2015-07-21 22:53:37 +0200
committerGravatar Walter Purcaro <vuolter@users.noreply.github.com> 2015-07-21 22:53:37 +0200
commit027cb529d79558de19c47da88a782b31745a65c9 (patch)
tree18ab9a8568cee2d07e6fc0dc8f9c03202245c594
parentNew __status__ magic key (diff)
downloadpyload-027cb529d79558de19c47da88a782b31745a65c9.tar.xz
New Captcha skeleton
-rw-r--r--module/plugins/crypter/DlProtectCom.py2
-rw-r--r--module/plugins/crypter/FilecryptCc.py12
-rw-r--r--module/plugins/crypter/LinkCryptWs.py6
-rw-r--r--module/plugins/crypter/LinkdecrypterCom.py2
-rw-r--r--module/plugins/crypter/LixIn.py2
-rw-r--r--module/plugins/crypter/NCryptIn.py8
-rw-r--r--module/plugins/crypter/RelinkUs.py6
-rw-r--r--module/plugins/crypter/ShareLinksBiz.py8
-rw-r--r--module/plugins/hoster/BezvadataCz.py17
-rw-r--r--module/plugins/hoster/BitshareCom.py4
-rw-r--r--module/plugins/hoster/CrockoCom.py2
-rw-r--r--module/plugins/hoster/CzshareCom.py8
-rw-r--r--module/plugins/hoster/ExtabitCom.py4
-rw-r--r--module/plugins/hoster/FastshareCz.py2
-rw-r--r--module/plugins/hoster/FileSharkPl.py13
-rw-r--r--module/plugins/hoster/FileboomMe.py6
-rw-r--r--module/plugins/hoster/FilecloudIo.py4
-rw-r--r--module/plugins/hoster/FiledropperCom.py2
-rw-r--r--module/plugins/hoster/FilerNet.py4
-rw-r--r--module/plugins/hoster/FileserveCom.py4
-rw-r--r--module/plugins/hoster/FreakshareCom.py2
-rw-r--r--module/plugins/hoster/GigapetaCom.py4
-rw-r--r--module/plugins/hoster/IfolderRu.py4
-rw-r--r--module/plugins/hoster/Keep2ShareCc.py6
-rw-r--r--module/plugins/hoster/LetitbitNet.py4
-rw-r--r--module/plugins/hoster/LuckyShareNet.py4
-rw-r--r--module/plugins/hoster/MegasharesCom.py6
-rw-r--r--module/plugins/hoster/NarodRu.py6
-rw-r--r--module/plugins/hoster/OboomCom.py8
-rw-r--r--module/plugins/hoster/RapidgatorNet.py4
-rw-r--r--module/plugins/hoster/SendspaceCom.py6
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py10
-rw-r--r--module/plugins/hoster/TurbobitNet.py6
-rw-r--r--module/plugins/hoster/UlozTo.py6
-rw-r--r--module/plugins/hoster/UloziskoSk.py2
-rw-r--r--module/plugins/hoster/UnibytesCom.py6
-rw-r--r--module/plugins/hoster/UploadheroCom.py2
-rw-r--r--module/plugins/internal/AdYouLike.py12
-rw-r--r--module/plugins/internal/AdsCaptcha.py20
-rw-r--r--module/plugins/internal/Captcha.py102
-rw-r--r--module/plugins/internal/CaptchaService.py46
-rw-r--r--module/plugins/internal/Hoster.py92
-rw-r--r--module/plugins/internal/ReCaptcha.py32
-rw-r--r--module/plugins/internal/SimpleHoster.py6
-rw-r--r--module/plugins/internal/SolveMedia.py20
-rw-r--r--module/plugins/internal/XFSHoster.py2
46 files changed, 271 insertions, 263 deletions
diff --git a/module/plugins/crypter/DlProtectCom.py b/module/plugins/crypter/DlProtectCom.py
index 4a6c4bddf..4626af105 100644
--- a/module/plugins/crypter/DlProtectCom.py
+++ b/module/plugins/crypter/DlProtectCom.py
@@ -54,7 +54,7 @@ class DlProtectCom(SimpleCrypter):
if "Security Code" in self.html:
m = re.search(r'/captcha\.php\?key=(.+?)"', self.html)
if m:
- captcha_code = self.decrypt_captcha("http://www.dl-protect.com/captcha.php?key=" + m.group(1), imgtype="gif")
+ captcha_code = self.captcha.decrypt_image("http://www.dl-protect.com/captcha.php?key=" + m.group(1), input_type="gif")
post_req['secure'] = captcha_code
self.html = self.load(self.pyfile.url, post=post_req)
diff --git a/module/plugins/crypter/FilecryptCc.py b/module/plugins/crypter/FilecryptCc.py
index 24f03d175..23636f3b7 100644
--- a/module/plugins/crypter/FilecryptCc.py
+++ b/module/plugins/crypter/FilecryptCc.py
@@ -92,17 +92,17 @@ class FilecryptCc(Crypter):
if m: #: Normal captcha
self.log_debug("Captcha-URL: %s" % m.group(1))
- captcha_code = self.decrypt_captcha(urlparse.urljoin(self.base_url, m.group(1)),
- forceUser=True,
- imgtype="gif")
+ captcha_code = self.captcha.decrypt_image(urlparse.urljoin(self.base_url, m.group(1)),
+ input_type="gif",
+ try_ocr=False)
self.site_with_links = self.load(self.pyfile.url,
post={'recaptcha_response_field': captcha_code})
elif m2: #: Circle captcha
self.log_debug("Captcha-URL: %s" % m2.group(1))
- captcha_code = self.decrypt_captcha('%s%s?c=abc' %(self.base_url, m2.group(1)),
- result_type='positional')
+ captcha_code = self.captcha.decrypt_image('%s%s?c=abc' %(self.base_url, m2.group(1)),
+ output_type='positional')
self.site_with_links = self.load(self.pyfile.url,
post={'button.x': captcha_code[0], 'button.y': captcha_code[1]})
@@ -120,7 +120,7 @@ class FilecryptCc(Crypter):
self.site_with_links = self.html
if "recaptcha_image" in self.site_with_links or "data-sitekey" in self.site_with_links:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py
index c06c8d4fe..5195c47c3 100644
--- a/module/plugins/crypter/LinkCryptWs.py
+++ b/module/plugins/crypter/LinkCryptWs.py
@@ -133,7 +133,7 @@ class LinkCryptWs(Crypter):
def unlock_captcha_protection(self):
captcha_url = re.search(r'<form.*?id\s*?=\s*?"captcha"[^>]*?>.*?<\s*?input.*?src="(.+?)"', self.html, re.I | re.S).group(1)
- captcha_code = self.decrypt_captcha(captcha_url, forceUser=True, imgtype="gif", result_type='positional')
+ captcha_code = self.captcha.decrypt_image(captcha_url, input_type="gif", output_type='positional', try_ocr=False)
self.html = self.load(self.pyfile.url, post={'x': captcha_code[0], 'y': captcha_code[1]})
@@ -167,10 +167,10 @@ class LinkCryptWs(Crypter):
def handle_captcha_errors(self):
if self.captcha:
if "Your choice was wrong!" in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
else:
- self.correct_captcha()
+ self.captcha.correct()
def handle_link_source(self, type):
diff --git a/module/plugins/crypter/LinkdecrypterCom.py b/module/plugins/crypter/LinkdecrypterCom.py
index d9d95f76e..1936425f2 100644
--- a/module/plugins/crypter/LinkdecrypterCom.py
+++ b/module/plugins/crypter/LinkdecrypterCom.py
@@ -52,7 +52,7 @@ class LinkdecrypterCom(Crypter):
msg = m.group(1) if m else ""
self.log_info(_("Captcha protected link"), result_type, msg)
- captcha = self.decrypt_captcha(captcha_url, result_type=result_type)
+ captcha = self.captcha.decrypt_image(captcha_url, output_type=result_type)
if result_type == "positional":
captcha = "%d|%d" % captcha
self.html = self.load('http://linkdecrypter.com/', post={'captcha': captcha})
diff --git a/module/plugins/crypter/LixIn.py b/module/plugins/crypter/LixIn.py
index e78d6d8df..67037ae79 100644
--- a/module/plugins/crypter/LixIn.py
+++ b/module/plugins/crypter/LixIn.py
@@ -48,7 +48,7 @@ class LixIn(Crypter):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
self.log_debug("Trying captcha")
- captcharesult = self.decrypt_captcha(urlparse.urljoin("http://lix.in/", m.group(1)))
+ captcharesult = self.captcha.decrypt_image(urlparse.urljoin("http://lix.in/", m.group(1)))
self.html = self.load(url,
post={'capt': captcharesult, 'submit': "submit", 'tiny': id})
else:
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 2de8d1ecb..bc3f6624f 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -146,7 +146,7 @@ class NCryptIn(Crypter):
if "anicaptcha" in form:
self.log_debug("Captcha protected")
captchaUri = re.search(r'src="(/temp/anicaptcha/.+?)"', form).group(1)
- captcha = self.decrypt_captcha("http://ncrypt.in" + captchaUri)
+ captcha = self.captcha.decrypt_image("http://ncrypt.in" + captchaUri)
self.log_debug("Captcha resolved [%s]" % captcha)
postData['captcha'] = captcha
@@ -164,7 +164,7 @@ class NCryptIn(Crypter):
if "circlecaptcha" in form:
self.log_debug("CircleCaptcha protected")
captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php"
- coords = self.decrypt_captcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
+ coords = self.captcha.decrypt_image(captcha_img_url, input_type="png", output_type='positional', try_ocr=False)
self.log_debug("Captcha resolved, coords [%s]" % str(coords))
postData['circle.x'] = coords[0]
postData['circle.y'] = coords[1]
@@ -182,10 +182,10 @@ class NCryptIn(Crypter):
if self.protection_type == "captcha":
if "The securitycheck was wrong!" in self.cleaned_html:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
else:
- self.correct_captcha()
+ self.captcha.correct()
def handle_link_source(self, link_source_type):
diff --git a/module/plugins/crypter/RelinkUs.py b/module/plugins/crypter/RelinkUs.py
index c2b72ae0e..f95da1b26 100644
--- a/module/plugins/crypter/RelinkUs.py
+++ b/module/plugins/crypter/RelinkUs.py
@@ -142,7 +142,7 @@ class RelinkUs(Crypter):
def unlock_captcha_protection(self):
self.log_debug("Request user positional captcha resolving")
captcha_img_url = self.CAPTCHA_IMG_URL + "?id=%s" % self.fileid
- coords = self.decrypt_captcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
+ coords = self.captcha.decrypt_image(captcha_img_url, input_type="png", output_type='positional', try_ocr=False)
self.log_debug("Captcha resolved, coords [%s]" % str(coords))
captcha_post_url = self.CAPTCHA_SUBMIT_URL + "?id=%s" % self.fileid
captcha_post_data = {'button.x': coords[0], 'button.y': coords[1], 'captcha': 'submit'}
@@ -178,10 +178,10 @@ class RelinkUs(Crypter):
if self.captcha:
if self.CAPTCHA_ERROR_ROKEN in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
else:
- self.correct_captcha()
+ self.captcha.correct()
def handle_link_source(self, source):
diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py
index d717431a6..894b6d010 100644
--- a/module/plugins/crypter/ShareLinksBiz.py
+++ b/module/plugins/crypter/ShareLinksBiz.py
@@ -117,13 +117,13 @@ class ShareLinksBiz(Crypter):
m = re.search(r'<img src="/captcha.gif\?d=(.*?)&amp;PHPSESSID=(.*?)&amp;legend=1"', self.html)
captchaUrl = self.base_url + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2))
self.log_debug("Waiting user for correct position")
- coords = self.decrypt_captcha(captchaUrl, forceUser=True, imgtype="gif", result_type='positional')
+ coords = self.captcha.decrypt_image(captchaUrl, input_type="gif", output_type='positional', try_ocr=False)
self.log_debug("Captcha resolved, coords [%s]" % str(coords))
#: Resolve captcha
href = self._resolve_coords(coords, captchaMap)
if href is None:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(wait_time=5)
url = self.base_url + href
self.html = self.load(url)
@@ -153,10 +153,10 @@ class ShareLinksBiz(Crypter):
if self.captcha:
if "Your choice was wrong" in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(wait_time=5)
else:
- self.correct_captcha()
+ self.captcha.correct()
def get_package_info(self):
diff --git a/module/plugins/hoster/BezvadataCz.py b/module/plugins/hoster/BezvadataCz.py
index be705d528..523e87541 100644
--- a/module/plugins/hoster/BezvadataCz.py
+++ b/module/plugins/hoster/BezvadataCz.py
@@ -8,7 +8,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class BezvadataCz(SimpleHoster):
__name__ = "BezvadataCz"
__type__ = "hoster"
- __version__ = "0.28"
+ __version__ = "0.29"
__status__ = "stable"
__pattern__ = r'http://(?:www\.)?bezvadata\.cz/stahnout/.+'
@@ -48,17 +48,12 @@ class BezvadataCz(SimpleHoster):
if m is None:
self.error(_("Wrong captcha image"))
- #: Captcha image is contained in html page as base64encoded data but decryptCaptcha() expects image url
- self.load, proper_load = self.loadcaptcha, self.load
- try:
- inputs['captcha'] = self.decrypt_captcha(m.group(1), imgtype='png')
- finally:
- self.load = proper_load
+ inputs['captcha'] = self.captcha.decrypt(m.group(1).decode('base64'), input_type='png')
if '<img src="data:image/png;base64' in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
self.fail(_("No valid captcha code entered"))
@@ -89,8 +84,4 @@ class BezvadataCz(SimpleHoster):
return super(BezvadataCz, self).check_errors()
- def loadcaptcha(self, data, *args, **kwargs):
- return data.decode('base64')
-
-
getInfo = create_getInfo(BezvadataCz)
diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py
index a928e64f6..7573c6e2a 100644
--- a/module/plugins/hoster/BitshareCom.py
+++ b/module/plugins/hoster/BitshareCom.py
@@ -149,12 +149,12 @@ class BitshareCom(SimpleHoster):
def handle_captcha_errors(self, res):
self.log_debug("Result of captcha resolving [%s]" % res)
if "SUCCESS" in res:
- self.correct_captcha()
+ self.captcha.correct()
return True
elif "ERROR:SESSION ERROR" in res:
self.retry()
- self.invalid_captcha()
+ self.captcha.invalid()
getInfo = create_getInfo(BitshareCom)
diff --git a/module/plugins/hoster/CrockoCom.py b/module/plugins/hoster/CrockoCom.py
index d2fb51fb4..9b62a9f9e 100644
--- a/module/plugins/hoster/CrockoCom.py
+++ b/module/plugins/hoster/CrockoCom.py
@@ -59,7 +59,7 @@ class CrockoCom(SimpleHoster):
self.download(action, post=inputs)
if self.check_download({'captcha': recaptcha.KEY_AJAX_PATTERN}):
- self.invalid_captcha()
+ self.captcha.invalid()
else:
break
else:
diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py
index 96eff828a..71f217c94 100644
--- a/module/plugins/hoster/CzshareCom.py
+++ b/module/plugins/hoster/CzshareCom.py
@@ -105,17 +105,17 @@ class CzshareCom(SimpleHoster):
#: Get and decrypt captcha
captcha_url = 'http://sdilej.cz/captcha.php'
for _i in xrange(5):
- inputs['captchastring2'] = self.decrypt_captcha(captcha_url)
+ inputs['captchastring2'] = self.captcha.decrypt_image(captcha_url)
self.html = self.load(parsed_url, post=inputs)
if u"<li>Zadaný ověřovací kód nesouhlasí!</li>" in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
elif re.search(self.MULTIDL_PATTERN, self.html):
self.wait(5 * 60, 12, _("Download limit reached"))
else:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
self.fail(_("No valid captcha code entered"))
@@ -154,7 +154,7 @@ class CzshareCom(SimpleHoster):
self.wait(5 * 60, 12, _("Download limit reached"))
elif check == "captcha":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
return super(CzshareCom, self).checkFile()
diff --git a/module/plugins/hoster/ExtabitCom.py b/module/plugins/hoster/ExtabitCom.py
index 73633fd50..3b0367467 100644
--- a/module/plugins/hoster/ExtabitCom.py
+++ b/module/plugins/hoster/ExtabitCom.py
@@ -55,10 +55,10 @@ class ExtabitCom(SimpleHoster):
get_data['capture'], get_data['challenge'] = recaptcha.challenge(captcha_key)
res = json_loads(self.load("http://extabit.com/file/%s/" % fileID, get=get_data))
if "ok" in res:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.fail(_("Invalid captcha"))
else:
diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py
index b18a937bc..abe2ef2d6 100644
--- a/module/plugins/hoster/FastshareCz.py
+++ b/module/plugins/hoster/FastshareCz.py
@@ -55,7 +55,7 @@ class FastshareCz(SimpleHoster):
self.error(_("FREE_URL_PATTERN not found"))
baseurl = "http://www.fastshare.cz"
- captcha = self.decrypt_captcha(urlparse.urljoin(baseurl, captcha_src))
+ captcha = self.captcha.decrypt_image(urlparse.urljoin(baseurl, captcha_src))
self.download(urlparse.urljoin(baseurl, action), post={'code': captcha, 'btn.x': 77, 'btn.y': 18})
diff --git a/module/plugins/hoster/FileSharkPl.py b/module/plugins/hoster/FileSharkPl.py
index 2f6898f15..901890433 100644
--- a/module/plugins/hoster/FileSharkPl.py
+++ b/module/plugins/hoster/FileSharkPl.py
@@ -9,7 +9,7 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
class FileSharkPl(SimpleHoster):
__name__ = "FileSharkPl"
__type__ = "hoster"
- __version__ = "0.12"
+ __version__ = "0.13"
__status__ = "stable"
__pattern__ = r'http://(?:www\.)?fileshark\.pl/pobierz/\d+/\w+'
@@ -100,19 +100,10 @@ class FileSharkPl(SimpleHoster):
if m is None:
self.retry(reason=_("Captcha image not found"))
- tmp_load = self.load
- self.load = self._decode64 #: work-around: injects decode64 inside decryptCaptcha
-
- inputs['form[captcha]'] = self.decrypt_captcha(m.group(1), imgtype='jpeg')
+ inputs['form[captcha]'] = self.captcha.decrypt(m.group(1).decode('base64'), input_type='jpeg')
inputs['form[start]'] = ""
- self.load = tmp_load
-
self.download(link, post=inputs, disposition=True)
- def _decode64(self, data, *args, **kwargs):
- return data.decode('base64')
-
-
getInfo = create_getInfo(FileSharkPl)
diff --git a/module/plugins/hoster/FileboomMe.py b/module/plugins/hoster/FileboomMe.py
index 97414cbf1..8d0f5d89c 100644
--- a/module/plugins/hoster/FileboomMe.py
+++ b/module/plugins/hoster/FileboomMe.py
@@ -56,7 +56,7 @@ class FileboomMe(SimpleHoster):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
- captcha = self.decrypt_captcha(urljoin(pyfile.url, m.group(1)))
+ captcha = self.captcha.decrypt_image(urljoin(pyfile.url, m.group(1)))
self.html = self.load(post_url,
post={'CaptchaForm[code]' : captcha,
@@ -65,7 +65,7 @@ class FileboomMe(SimpleHoster):
'uniqueId' : uniqueId})
if 'The verification code is incorrect' in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.check_errors()
@@ -79,7 +79,7 @@ class FileboomMe(SimpleHoster):
self.link = urljoin(pyfile.url, m.group(0))
else:
- self.invalid_captcha()
+ self.captcha.invalid()
break
diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py
index 67e5c1053..d010af624 100644
--- a/module/plugins/hoster/FilecloudIo.py
+++ b/module/plugins/hoster/FilecloudIo.py
@@ -88,9 +88,9 @@ class FilecloudIo(SimpleHoster):
res = json_loads(res)
if "retry" in res and res['retry']:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
self.fail(_("Incorrect captcha"))
diff --git a/module/plugins/hoster/FiledropperCom.py b/module/plugins/hoster/FiledropperCom.py
index b508c2734..dede02dac 100644
--- a/module/plugins/hoster/FiledropperCom.py
+++ b/module/plugins/hoster/FiledropperCom.py
@@ -34,7 +34,7 @@ class FiledropperCom(SimpleHoster):
if m is None:
self.fail("Captcha not found")
- captcha_code = self.decrypt_captcha("http://www.filedropper.com/%s" % m.group(1))
+ captcha_code = self.captcha.decrypt_image("http://www.filedropper.com/%s" % m.group(1))
m = re.search(r'method="post" action="(.+?)"', self.html)
if m is None:
diff --git a/module/plugins/hoster/FilerNet.py b/module/plugins/hoster/FilerNet.py
index bed686a49..61b3a9635 100644
--- a/module/plugins/hoster/FilerNet.py
+++ b/module/plugins/hoster/FilerNet.py
@@ -59,9 +59,9 @@ class FilerNet(SimpleHoster):
if 'location' in self.req.http.header.lower():
self.link = re.search(r'location: (\S+)', self.req.http.header, re.I).group(1)
- self.correct_captcha()
+ self.captcha.correct()
else:
- self.invalid_captcha()
+ self.captcha.invalid()
getInfo = create_getInfo(FilerNet)
diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py
index 6f796ca69..117ee1f4c 100644
--- a/module/plugins/hoster/FileserveCom.py
+++ b/module/plugins/hoster/FileserveCom.py
@@ -167,9 +167,9 @@ class FileserveCom(Hoster):
'recaptcha_response_field' : response,
'recaptcha_shortencode_field': self.file_id}))
if not res['success']:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
self.fail(_("Invalid captcha"))
diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py
index 929baba66..ba088027a 100644
--- a/module/plugins/hoster/FreakshareCom.py
+++ b/module/plugins/hoster/FreakshareCom.py
@@ -61,7 +61,7 @@ class FreakshareCom(Hoster):
self.fail(_("File not downloadable"))
elif check == "wrong_captcha":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
elif check == "downloadserver":
diff --git a/module/plugins/hoster/GigapetaCom.py b/module/plugins/hoster/GigapetaCom.py
index e4562be59..3fcf4ee32 100644
--- a/module/plugins/hoster/GigapetaCom.py
+++ b/module/plugins/hoster/GigapetaCom.py
@@ -39,7 +39,7 @@ class GigapetaCom(SimpleHoster):
for _i in xrange(5):
self.check_errors()
- captcha = self.decrypt_captcha(captcha_url)
+ captcha = self.captcha.decrypt_image(captcha_url)
self.html = self.load(pyfile.url, post={
'captcha_key': captcha_key,
'captcha': captcha,
@@ -50,7 +50,7 @@ class GigapetaCom(SimpleHoster):
self.link = m.group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10
break
elif "Entered figures don&#96;t coincide with the picture" in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.fail(_("No valid captcha code entered"))
diff --git a/module/plugins/hoster/IfolderRu.py b/module/plugins/hoster/IfolderRu.py
index 5cd2c6618..457bd6962 100644
--- a/module/plugins/hoster/IfolderRu.py
+++ b/module/plugins/hoster/IfolderRu.py
@@ -49,13 +49,13 @@ class IfolderRu(SimpleHoster):
captcha_url = "http://ints.rusfolder.com/random/images/?session=%s" % session_id
for _i in xrange(5):
action, inputs = self.parse_html_form('id="download-step-one-form"')
- inputs['confirmed_number'] = self.decrypt_captcha(captcha_url, cookies=True)
+ inputs['confirmed_number'] = self.captcha.decrypt_image(captcha_url, cookies=True)
inputs['action'] = '1'
self.log_debug(inputs)
self.html = self.load(url, post=inputs)
if self.WRONG_CAPTCHA_PATTERN in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
break
else:
diff --git a/module/plugins/hoster/Keep2ShareCc.py b/module/plugins/hoster/Keep2ShareCc.py
index a4faa72d0..4fa3f121f 100644
--- a/module/plugins/hoster/Keep2ShareCc.py
+++ b/module/plugins/hoster/Keep2ShareCc.py
@@ -101,7 +101,7 @@ class Keep2ShareCc(SimpleHoster):
self.log_debug("CAPTCHA_PATTERN found %s" % m)
if m:
captcha_url = urlparse.urljoin("http://keep2s.cc/", m.group(1))
- post_data['CaptchaForm[code]'] = self.decrypt_captcha(captcha_url)
+ post_data['CaptchaForm[code]'] = self.captcha.decrypt_image(captcha_url)
else:
recaptcha = ReCaptcha(self)
response, challenge = recaptcha.challenge()
@@ -111,9 +111,9 @@ class Keep2ShareCc(SimpleHoster):
self.html = self.load(self.pyfile.url, post=post_data)
if 'verification code is incorrect' not in self.html:
- self.correct_captcha()
+ self.captcha.correct()
else:
- self.invalid_captcha()
+ self.captcha.invalid()
getInfo = create_getInfo(Keep2ShareCc)
diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py
index 63c57c9a5..92bb5ab62 100644
--- a/module/plugins/hoster/LetitbitNet.py
+++ b/module/plugins/hoster/LetitbitNet.py
@@ -100,14 +100,14 @@ class LetitbitNet(SimpleHoster):
self.log_debug(res)
if not res:
- self.invalid_captcha()
+ self.captcha.invalid()
if res == "error_free_download_blocked":
self.log_warning(_("Daily limit reached"))
self.wait(seconds_to_midnight(gmt=2), True)
if res == "error_wrong_captcha":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry()
elif res.startswith('['):
diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py
index ab07cd11e..e5ae3f1c3 100644
--- a/module/plugins/hoster/LuckyShareNet.py
+++ b/module/plugins/hoster/LuckyShareNet.py
@@ -59,10 +59,10 @@ class LuckyShareNet(SimpleHoster):
self.log_debug("JSON: " + rep)
if 'link' in rep:
json.update(self.parse_json(rep))
- self.correct_captcha()
+ self.captcha.correct()
break
elif 'Verification failed' in rep:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.error(_("Unable to get downlaod link"))
diff --git a/module/plugins/hoster/MegasharesCom.py b/module/plugins/hoster/MegasharesCom.py
index 830036cdd..65c41c23f 100644
--- a/module/plugins/hoster/MegasharesCom.py
+++ b/module/plugins/hoster/MegasharesCom.py
@@ -56,7 +56,7 @@ class MegasharesCom(SimpleHoster):
for _i in xrange(5):
random_num = re.search(self.REACTIVATE_NUM_PATTERN, self.html).group(1)
- verifyinput = self.decrypt_captcha("http://d01.megashares.com/index.php",
+ verifyinput = self.captcha.decrypt_image("http://d01.megashares.com/index.php",
get={'secgfx': "gfx", 'random_num': random_num})
self.log_info(_("Reactivating passport %s: %s %s") % (passport_num, random_num, verifyinput))
@@ -70,10 +70,10 @@ class MegasharesCom(SimpleHoster):
'rsrnd[]' : str(int(time.time() * 1000))})
if 'Thank you for reactivating your passport.' in res:
- self.correct_captcha()
+ self.captcha.correct()
self.retry()
else:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.fail(_("Failed to reactivate passport"))
diff --git a/module/plugins/hoster/NarodRu.py b/module/plugins/hoster/NarodRu.py
index f88b5e2c7..f54fbf71e 100644
--- a/module/plugins/hoster/NarodRu.py
+++ b/module/plugins/hoster/NarodRu.py
@@ -43,18 +43,18 @@ class NarodRu(SimpleHoster):
post_data = {'action': "sendcapcha"}
captcha_url, post_data['key'] = m.groups()
- post_data['rep'] = self.decrypt_captcha(captcha_url)
+ post_data['rep'] = self.captcha.decrypt_image(captcha_url)
self.html = self.load(pyfile.url, post=post_data)
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
self.link = urlparse.urljoin("http://narod.ru", m.group(1))
- self.correct_captcha()
+ self.captcha.correct()
break
elif u'<b class="error-msg"><strong>Ошиблись?</strong>' in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
self.error(_("Download link"))
diff --git a/module/plugins/hoster/OboomCom.py b/module/plugins/hoster/OboomCom.py
index aabd8c774..f5624439f 100644
--- a/module/plugins/hoster/OboomCom.py
+++ b/module/plugins/hoster/OboomCom.py
@@ -87,15 +87,15 @@ class OboomCom(Hoster):
if result[0] == 200:
self.download_token = result[1]
self.download_auth = result[2]
- self.correct_captcha()
+ self.captcha.correct()
self.wait(30)
break
elif result[0] == 400:
if result[1] == "incorrect-captcha-sol":
- self.invalid_captcha()
+ self.captcha.invalid()
elif result[1] == "captcha-timeout":
- self.invalid_captcha()
+ self.captcha.invalid()
elif result[1] == "forbidden":
self.retry(5, 15 * 60, _("Service unavailable"))
@@ -107,7 +107,7 @@ class OboomCom(Hoster):
self.wait()
self.retry(5)
else:
- self.invalid_captcha()
+ self.captcha.invalid()
self.fail(_("Received invalid captcha 5 times"))
diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py
index c87d3b83b..7b364e150 100644
--- a/module/plugins/hoster/RapidgatorNet.py
+++ b/module/plugins/hoster/RapidgatorNet.py
@@ -140,9 +140,9 @@ class RapidgatorNet(SimpleHoster):
'adcopy_response' : response})
if "The verification code is incorrect" in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.correct_captcha()
+ self.captcha.correct()
else:
self.error(_("Download link"))
diff --git a/module/plugins/hoster/SendspaceCom.py b/module/plugins/hoster/SendspaceCom.py
index 77e714cae..18e66033f 100644
--- a/module/plugins/hoster/SendspaceCom.py
+++ b/module/plugins/hoster/SendspaceCom.py
@@ -35,20 +35,20 @@ class SendspaceCom(SimpleHoster):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
if 'captcha_hash' in params:
- self.correct_captcha()
+ self.captcha.correct()
self.link = m.group(1)
break
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
if 'captcha_hash' in params:
- self.invalid_captcha()
+ self.captcha.invalid()
captcha_url1 = "http://www.sendspace.com/" + m.group(1)
m = re.search(self.USER_CAPTCHA_PATTERN, self.html)
captcha_url2 = "http://www.sendspace.com/" + m.group(1)
params = {'captcha_hash': m.group(2),
'captcha_submit': 'Verify',
- 'captcha_answer': self.decrypt_captcha(captcha_url1) + " " + self.decrypt_captcha(captcha_url2)}
+ 'captcha_answer': self.captcha.decrypt_image(captcha_url1) + " " + self.captcha.decrypt_image(captcha_url2)}
else:
params = {'download': "Regular Download"}
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 7e1c7c70c..13e4f8f87 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -80,12 +80,12 @@ class ShareonlineBiz(SimpleHoster):
'recaptcha_challenge_field': challenge,
'recaptcha_response_field' : response})
if not res == '0':
- self.correct_captcha()
+ self.captcha.correct()
return res
else:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.invalid_captcha()
+ self.captcha.invalid()
self.fail(_("No valid captcha solution received"))
@@ -111,11 +111,11 @@ class ShareonlineBiz(SimpleHoster):
'fail' : re.compile(r"<title>Share-Online")})
if check == "cookie":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(5, 60, _("Cookie failure"))
elif check == "fail":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(5, 5 * 60, _("Download failed"))
return super(ShareonlineBiz, self).checkFile()
diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py
index 1df2d1673..f70a985df 100644
--- a/module/plugins/hoster/TurbobitNet.py
+++ b/module/plugins/hoster/TurbobitNet.py
@@ -81,15 +81,15 @@ class TurbobitNet(SimpleHoster):
if m is None:
self.error(_("captcha"))
captcha_url = m.group(1)
- inputs['captcha_response'] = self.decrypt_captcha(captcha_url)
+ inputs['captcha_response'] = self.captcha.decrypt_image(captcha_url)
self.log_debug(inputs)
self.html = self.load(self.url, post=inputs)
if '<div class="captcha-error">Incorrect, try again!<' in self.html:
- self.invalid_captcha()
+ self.captcha.invalid()
else:
- self.correct_captcha()
+ self.captcha.correct()
break
else:
self.fail(_("Invalid captcha"))
diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py
index 9df9c2866..27b5843d9 100644
--- a/module/plugins/hoster/UlozTo.py
+++ b/module/plugins/hoster/UlozTo.py
@@ -60,7 +60,7 @@ class UlozTo(SimpleHoster):
#: Old version - last seen 9.12.2013
self.log_debug('Using "old" version')
- captcha_value = self.decrypt_captcha("http://img.uloz.to/captcha/%s.png" % inputs['captcha_id'])
+ captcha_value = self.captcha.decrypt_image("http://img.uloz.to/captcha/%s.png" % inputs['captcha_id'])
self.log_debug("CAPTCHA ID: " + inputs['captcha_id'] + ", CAPTCHA VALUE: " + captcha_value)
inputs.update({'captcha_id': inputs['captcha_id'], 'captcha_key': inputs['captcha_key'], 'captcha_value': captcha_value})
@@ -73,7 +73,7 @@ class UlozTo(SimpleHoster):
self.log_debug("xapca = " + str(xapca))
data = json_loads(xapca)
- captcha_value = self.decrypt_captcha(str(data['image']))
+ captcha_value = self.captcha.decrypt_image(str(data['image']))
self.log_debug("CAPTCHA HASH: " + data['hash'], "CAPTCHA SALT: " + str(data['salt']), "CAPTCHA VALUE: " + captcha_value)
inputs.update({'timestamp': data['timestamp'], 'salt': data['salt'], 'hash': data['hash'], 'captcha_value': captcha_value})
@@ -130,7 +130,7 @@ class UlozTo(SimpleHoster):
})
if check == "wrong_captcha":
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(reason=_("Wrong captcha code"))
elif check == "offline":
diff --git a/module/plugins/hoster/UloziskoSk.py b/module/plugins/hoster/UloziskoSk.py
index b881e853a..58e3b685a 100644
--- a/module/plugins/hoster/UloziskoSk.py
+++ b/module/plugins/hoster/UloziskoSk.py
@@ -59,7 +59,7 @@ class UloziskoSk(SimpleHoster):
self.error(_("CAPTCHA_PATTERN not found"))
captcha_url = urlparse.urljoin("http://www.ulozisko.sk", m.group(1))
- captcha = self.decrypt_captcha(captcha_url, cookies=True)
+ captcha = self.captcha.decrypt_image(captcha_url, cookies=True)
self.log_debug("CAPTCHA_URL:" + captcha_url + ' CAPTCHA:' + captcha)
diff --git a/module/plugins/hoster/UnibytesCom.py b/module/plugins/hoster/UnibytesCom.py
index 5b4295cb2..96b2fb031 100644
--- a/module/plugins/hoster/UnibytesCom.py
+++ b/module/plugins/hoster/UnibytesCom.py
@@ -52,10 +52,10 @@ class UnibytesCom(SimpleHoster):
m = re.search(self.LINK_FREE_PATTERN, self.html)
if m:
self.link = m.group(1)
- self.correct_captcha()
+ self.captcha.correct()
break
else:
- self.invalid_captcha()
+ self.captcha.invalid()
last_step = post_data['step']
action, post_data = self.parse_html_form('id="stepForm"')
@@ -65,7 +65,7 @@ class UnibytesCom(SimpleHoster):
self.wait(m.group(1) if m else 60, False)
elif last_step in ("captcha", "last"):
- post_data['captcha'] = self.decrypt_captcha(urlparse.urljoin(domain, "/captcha.jpg"))
+ post_data['captcha'] = self.captcha.decrypt_image(urlparse.urljoin(domain, "/captcha.jpg"))
else:
self.fail(_("No valid captcha code entered"))
diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py
index 54b9f229c..8a0b3a032 100644
--- a/module/plugins/hoster/UploadheroCom.py
+++ b/module/plugins/hoster/UploadheroCom.py
@@ -44,7 +44,7 @@ class UploadheroCom(SimpleHoster):
if m is None:
self.error(_("Captcha not found"))
- captcha = self.decrypt_captcha(urlparse.urljoin("http://uploadhero.co", m.group(1)))
+ captcha = self.captcha.decrypt_image(urlparse.urljoin("http://uploadhero.co", m.group(1)))
self.html = self.load(pyfile.url,
get={'code': captcha})
diff --git a/module/plugins/internal/AdYouLike.py b/module/plugins/internal/AdYouLike.py
index fcb9b8372..d14babb51 100644
--- a/module/plugins/internal/AdYouLike.py
+++ b/module/plugins/internal/AdYouLike.py
@@ -3,10 +3,10 @@
import re
from module.common.json_layer import json_loads
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class AdYouLike(Captcha):
+class AdYouLike(CaptchaService):
__name__ = "AdYouLike"
__type__ = "captcha"
__version__ = "0.07"
@@ -21,8 +21,8 @@ class AdYouLike(Captcha):
CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.AYL_PATTERN, html)
n = re.search(self.CALLBACK_PATTERN, html)
@@ -35,8 +35,8 @@ class AdYouLike(Captcha):
return None
- def challenge(self, key=None, html=None):
- ayl, callback = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ ayl, callback = key or self.retrieve_key(data)
#: {'adyoulike':{'key':"P~zQ~O0zV0WTiAzC-iw0navWQpCLoYEP"},
#: 'all':{'element_id':"ayl_private_cap_92300",'lang':"fr",'env':"prod"}}
diff --git a/module/plugins/internal/AdsCaptcha.py b/module/plugins/internal/AdsCaptcha.py
index b99697a84..f487042e2 100644
--- a/module/plugins/internal/AdsCaptcha.py
+++ b/module/plugins/internal/AdsCaptcha.py
@@ -3,10 +3,10 @@
import random
import re
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class AdsCaptcha(Captcha):
+class AdsCaptcha(CaptchaService):
__name__ = "AdsCaptcha"
__type__ = "captcha"
__version__ = "0.10"
@@ -21,8 +21,8 @@ class AdsCaptcha(Captcha):
PUBLICKEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?.*?PublicKey=([\w-]+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.PUBLICKEY_PATTERN, html)
n = re.search(self.CAPTCHAID_PATTERN, html)
@@ -35,8 +35,8 @@ class AdsCaptcha(Captcha):
return None
- def challenge(self, key=None, html=None):
- PublicKey, CaptchaId = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ PublicKey, CaptchaId = key or self.retrieve_key(data)
html = self.plugin.load("http://api.adscaptcha.com/Get.aspx",
get={'CaptchaId': CaptchaId,
@@ -54,10 +54,10 @@ class AdsCaptcha(Captcha):
def result(self, server, challenge):
- result = self.plugin.decryptCaptcha("%sChallenge.aspx" % server,
- get={'cid': challenge, 'dummy': random.random()},
- cookies=True,
- imgtype="jpg")
+ result = self.decrypt_image("%sChallenge.aspx" % server,
+ get={'cid': challenge, 'dummy': random.random()},
+ cookies=True,
+ input_type="jpg")
self.log_debug("Result: %s" % result)
diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py
index 814c36756..af7f66ed5 100644
--- a/module/plugins/internal/Captcha.py
+++ b/module/plugins/internal/Captcha.py
@@ -6,24 +6,28 @@ from module.plugins.internal.Plugin import Plugin
class Captcha(Plugin):
__name__ = "Captcha"
__type__ = "captcha"
- __version__ = "0.31"
+ __version__ = "0.01"
__status__ = "stable"
- __description__ = """Base captcha service plugin"""
+ __description__ = """Base anti-captcha plugin"""
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- def __init__(self, plugin):
+ def __init__(self, plugin): #@TODO: pass pyfile instead plugin, so store plugin's html in its associated pyfile as data
self.pyload = plugin.core
self.info = {} #: Provide information in dict here
self.plugin = plugin
- self.key = None #: Last key detected
+ self.task = None #: captchaManager task
self.init()
+ def _log(self, type, args):
+ return super(Captcha, self)._log(type, (self.plugin.__name__,) + args)
+
+
def init(self):
"""
Initialize additional data structures
@@ -31,29 +35,87 @@ class Captcha(Plugin):
pass
- #@TODO: Recheck in 0.4.10
- def retrieve_key(self, html):
- if self.detect_key(html):
- return self.key
+ def decrypt_image(self, url, get={}, post={}, ref=False, cookies=False, decode=False,
+ input_type='png', output_type='textual', try_ocr=True):
+ image = self.load(url, get=get, post=post, ref=ref, cookies=cookies, decode=decode)
+ return self.decrypt(image, input_type, output_type, try_ocr)
+
+
+ def decrypt(self, data, input_type='png', output_type='textual', try_ocr=True):
+ """
+ Loads a captcha and decrypts it with ocr, plugin, user input
+
+ :param url: url of captcha image
+ :param get: get part for request
+ :param post: post part for request
+ :param cookies: True if cookies should be enabled
+ :param input_type: Type of the Image
+ :param output_type: 'textual' if text is written on the captcha\
+ or 'positional' for captcha where the user have to click\
+ on a specific region on the captcha
+ :param try_ocr: if True, ocr is not used
+
+ :return: result of decrypting
+ """
+ id = ("%.2f" % time.time())[-6:].replace(".", "")
+
+ with open(os.path.join("tmp", "tmpCaptcha_%s_%s.%s" % (self.plugin.__name__, id, input_type)), "wb") as tmpCaptcha:
+ tmpCaptcha.write(img)
+
+ has_plugin = self.plugin.__name__ in self.pyload.pluginManager.ocrPlugins
+
+ if self.pyload.captcha:
+ Ocr = self.pyload.pluginManager.loadClass("ocr", self.plugin.__name__)
else:
- self.fail(_("%s key not found") % self.__name__)
+ Ocr = None
+ if Ocr and try_ocr:
+ time.sleep(random.randint(3000, 5000) / 1000.0)
+ if self.pyfile.abort:
+ self.abort()
- #@TODO: Recheck in 0.4.10
- def retrieve_html(self):
- if hasattr(self.plugin, "html") and self.plugin.html:
- return self.plugin.html
+ ocr = Ocr(self.pyfile)
+ result = ocr.get_captcha(tmpCaptcha.name)
else:
- self.fail(_("%s html not found") % self.__name__)
+ captchaManager = self.pyload.captchaManager
+ task = captchaManager.newTask(img, input_type, tmpCaptcha.name, output_type)
+ self.task = task
+ captchaManager.handleCaptcha(task)
+
+ while task.isWaiting():
+ if self.pyfile.abort:
+ captchaManager.removeTask(task)
+ self.abort()
+ time.sleep(1)
+
+ captchaManager.removeTask(task)
+
+ if task.error and has_plugin: #: Ignore default error message since the user could use try_ocr
+ self.fail(_("Pil and tesseract not installed and no Client connected for captcha decrypting"))
+ elif task.error:
+ self.fail(task.error)
+ elif not task.result:
+ self.fail(_("No captcha result obtained in appropiate time by any of the plugins"))
+
+ result = task.result
+ self.log_debug("Received captcha result: %s" % result)
+ if not self.pyload.debug:
+ try:
+ os.remove(tmpCaptcha.name)
+ except Exception:
+ pass
- def detect_key(self, html=None):
- raise NotImplementedError
+ return result
- def challenge(self, key=None, html=None):
- raise NotImplementedError
+ def invalid(self):
+ self.log_error(_("Invalid captcha"))
+ if self.task:
+ self.task.invalid()
- def result(self, server, challenge):
- raise NotImplementedError
+ def correct(self):
+ self.log_info(_("Correct captcha"))
+ if self.task:
+ self.task.correct()
diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py
new file mode 100644
index 000000000..05af8ccec
--- /dev/null
+++ b/module/plugins/internal/CaptchaService.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+from module.plugins.internal.Plugin import Plugin
+
+
+class Captcha(Plugin):
+ __name__ = "Captcha"
+ __type__ = "captcha"
+ __version__ = "0.31"
+ __status__ = "stable"
+
+ __description__ = """Base anti-captcha service plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ def init(self):
+ self.key = None #: Last key detected
+
+
+ #@TODO: Recheck in 0.4.10
+ def retrieve_key(self, data):
+ if self.detect_key(data):
+ return self.key
+ else:
+ self.fail(_("%s key not found") % self.__name__)
+
+
+ #@TODO: Recheck in 0.4.10, html is now pyfile.data
+ def retrieve_data(self):
+ if hasattr(self.plugin, "html") and self.plugin.html:
+ return self.plugin.html
+ else:
+ self.fail(_("%s data not found") % self.__name__)
+
+
+ def detect_key(self, data=None):
+ raise NotImplementedError
+
+
+ def challenge(self, key=None, data=None):
+ raise NotImplementedError
+
+
+ def result(self, server, challenge):
+ raise NotImplementedError
diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py
index 35e6ef23e..af3e80acf 100644
--- a/module/plugins/internal/Hoster.py
+++ b/module/plugins/internal/Hoster.py
@@ -12,6 +12,7 @@ if os.name != "nt":
import grp
import pwd
+from module.plugins.internal import Captcha
from module.plugins.internal.Plugin import (Plugin, Abort, Fail, Reconnect, Retry, Skip
chunks, fixurl as _fixurl, replace_patterns, seconds_to_midnight,
set_cookies, parse_html_form, parse_html_tag_attr_value,
@@ -122,8 +123,8 @@ class Hoster(Plugin):
#: Js engine, see `JsEngine`
self.js = self.pyload.js
- #: Captcha task
- self.c_task = None
+ #: Captcha stuff
+ self.captcha = Captcha(self)
#: Some plugins store html code here
self.html = None
@@ -257,7 +258,7 @@ class Hoster(Plugin):
time.sleep(1)
else:
while pyfile.waitUntil > time.time():
- self.thread.m.reconnecting.wait(2)
+ self.thread.m.reconnecting.wait(1)
if pyfile.abort:
self.abort()
@@ -329,89 +330,6 @@ class Hoster(Plugin):
raise Retry(reason)
- def invalid_captcha(self):
- self.log_error(_("Invalid captcha"))
- if self.c_task:
- self.c_task.invalid()
-
-
- def correct_captcha(self):
- self.log_info(_("Correct captcha"))
- if self.c_task:
- self.c_task.correct()
-
-
- def decrypt_captcha(self, url, get={}, post={}, cookies=False, forceUser=False,
- imgtype='jpg', result_type='textual'):
- """
- Loads a captcha and decrypts it with ocr, plugin, user input
-
- :param url: url of captcha image
- :param get: get part for request
- :param post: post part for request
- :param cookies: True if cookies should be enabled
- :param forceUser: if True, ocr is not used
- :param imgtype: Type of the Image
- :param result_type: 'textual' if text is written on the captcha\
- or 'positional' for captcha where the user have to click\
- on a specific region on the captcha
-
- :return: result of decrypting
- """
- img = self.load(url, get=get, post=post, cookies=cookies)
-
- id = ("%.2f" % time.time())[-6:].replace(".", "")
-
- with open(os.path.join("tmp", "tmpCaptcha_%s_%s.%s" % (self.__name__, id, imgtype)), "wb") as tmpCaptcha:
- tmpCaptcha.write(img)
-
- has_plugin = self.__name__ in self.pyload.pluginManager.ocrPlugins
-
- if self.pyload.captcha:
- Ocr = self.pyload.pluginManager.loadClass("ocr", self.__name__)
- else:
- Ocr = None
-
- if Ocr and not forceUser:
- time.sleep(random.randint(3000, 5000) / 1000.0)
- if self.pyfile.abort:
- self.abort()
-
- ocr = Ocr(self.pyfile)
- result = ocr.get_captcha(tmpCaptcha.name)
- else:
- captchaManager = self.pyload.captchaManager
- task = captchaManager.newTask(img, imgtype, tmpCaptcha.name, result_type)
- self.c_task = task
- captchaManager.handleCaptcha(task)
-
- while task.isWaiting():
- if self.pyfile.abort:
- captchaManager.removeTask(task)
- self.abort()
- time.sleep(1)
-
- captchaManager.removeTask(task)
-
- if task.error and has_plugin: #: Ignore default error message since the user could use OCR
- self.fail(_("Pil and tesseract not installed and no Client connected for captcha decrypting"))
- elif task.error:
- self.fail(task.error)
- elif not task.result:
- self.fail(_("No captcha result obtained in appropiate time by any of the plugins"))
-
- result = task.result
- self.log_debug("Received captcha result: %s" % result)
-
- if not self.pyload.debug:
- try:
- os.remove(tmpCaptcha.name)
- except Exception:
- pass
-
- return result
-
-
def fixurl(self, url):
url = _fixurl(url)
@@ -447,7 +365,7 @@ class Hoster(Plugin):
if self.pyload.debug:
self.log_debug("DOWNLOAD URL " + url, *["%s=%s" % (key, val) for key, val in locals().iteritems() if key not in ("self", "url")])
- self.correct_captcha()
+ self.captcha.correct()
self.check_for_same_files()
self.pyfile.setStatus("downloading")
diff --git a/module/plugins/internal/ReCaptcha.py b/module/plugins/internal/ReCaptcha.py
index 4d04c07db..b4f9ef1eb 100644
--- a/module/plugins/internal/ReCaptcha.py
+++ b/module/plugins/internal/ReCaptcha.py
@@ -7,10 +7,10 @@ import urlparse
from base64 import b64encode
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class ReCaptcha(Captcha):
+class ReCaptcha(CaptchaService):
__name__ = "ReCaptcha"
__type__ = "captcha"
__version__ = "0.18"
@@ -27,8 +27,8 @@ class ReCaptcha(Captcha):
KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.KEY_V2_PATTERN, html) or re.search(self.KEY_V1_PATTERN, html)
if m:
@@ -40,15 +40,15 @@ class ReCaptcha(Captcha):
return None
- def challenge(self, key=None, html=None, version=None):
- key = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None, version=None):
+ key = key or self.retrieve_key(data)
if version in (1, 2):
return getattr(self, "_challenge_v%s" % version)(key)
else:
return self.challenge(key,
- version=2 if re.search(self.KEY_V2_PATTERN, html or self.retrieve_html()) else 1)
+ version=2 if re.search(self.KEY_V2_PATTERN, html or self.retrieve_data()) else 1)
def _challenge_v1(self, key):
@@ -81,11 +81,11 @@ class ReCaptcha(Captcha):
self.fail(_("ReCaptcha second challenge pattern not found"))
self.log_debug("Second challenge: %s" % challenge)
- result = self.plugin.decryptCaptcha("%simage" % server,
- get={'c': challenge},
- cookies=True,
- forceUser=True,
- imgtype="jpg")
+ result = self.decrypt("%simage" % server,
+ get={'c': challenge},
+ cookies=True,
+ input_type="jpg",
+ try_ocr=False)
self.log_debug("Result: %s" % result)
@@ -170,10 +170,10 @@ class ReCaptcha(Captcha):
self.log_debug("Token #3: %s" % token3.group(1))
millis_captcha_loading = int(round(time.time() * 1000))
- captcha_response = self.plugin.decryptCaptcha("https://www.google.com/recaptcha/api2/payload",
- get={'c':token3.group(1), 'k':key},
- cookies=True,
- forceUser=True)
+ captcha_response = self.decrypt_image("https://www.google.com/recaptcha/api2/payload",
+ get={'c':token3.group(1), 'k':key},
+ cookies=True,
+ try_ocr=False)
response = b64encode('{"response":"%s"}' % captcha_response)
self.log_debug("Result: %s" % response)
diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py
index 9d1ebc0bf..5960794cc 100644
--- a/module/plugins/internal/SimpleHoster.py
+++ b/module/plugins/internal/SimpleHoster.py
@@ -301,8 +301,8 @@ class SimpleHoster(Hoster):
def check_file(self):
lastDownload = fs_encode(self.last_download)
- if self.c_task and not self.last_download:
- self.invalid_captcha()
+ if self.captcha.task and not self.last_download:
+ self.captcha.invalid()
self.retry(10, reason=_("Wrong captcha"))
elif self.check_download({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')},
@@ -396,7 +396,7 @@ class SimpleHoster(Hoster):
self.fail(_("Connection from your current IP address is not allowed"))
elif re.search('captcha|code', errmsg, re.I):
- self.invalid_captcha()
+ self.captcha.invalid()
self.retry(10, reason=_("Wrong captcha"))
elif re.search('countdown|expired', errmsg, re.I):
diff --git a/module/plugins/internal/SolveMedia.py b/module/plugins/internal/SolveMedia.py
index 5d701a5a2..ce4ebb007 100644
--- a/module/plugins/internal/SolveMedia.py
+++ b/module/plugins/internal/SolveMedia.py
@@ -3,10 +3,10 @@
import re
from module.plugins.internal.Plugin import Fail
-from module.plugins.internal.Captcha import Captcha
+from module.plugins.internal.CaptchaService import CaptchaService
-class SolveMedia(Captcha):
+class SolveMedia(CaptchaService):
__name__ = "SolveMedia"
__type__ = "captcha"
__version__ = "0.15"
@@ -20,8 +20,8 @@ class SolveMedia(Captcha):
KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(?:no)?script\?k=(.+?)["\']'
- def detect_key(self, html=None):
- html = html or self.retrieve_html()
+ def detect_key(self, data=None):
+ html = data or self.retrieve_data()
m = re.search(self.KEY_PATTERN, html)
if m:
@@ -33,8 +33,8 @@ class SolveMedia(Captcha):
return None
- def challenge(self, key=None, html=None):
- key = key or self.retrieve_key(html)
+ def challenge(self, key=None, data=None):
+ key = key or self.retrieve_key(data)
html = self.plugin.load("http://api.solvemedia.com/papi/challenge.noscript",
get={'k': key})
@@ -95,10 +95,10 @@ class SolveMedia(Captcha):
def result(self, server, challenge):
- result = self.plugin.decryptCaptcha(server,
- get={'c': challenge},
- cookies=True,
- imgtype="gif")
+ result = self.decrypt_image(server,
+ get={'c': challenge},
+ cookies=True,
+ input_type="gif")
self.log_debug("Result: %s" % result)
diff --git a/module/plugins/internal/XFSHoster.py b/module/plugins/internal/XFSHoster.py
index 09799aa28..ec9a18a48 100644
--- a/module/plugins/internal/XFSHoster.py
+++ b/module/plugins/internal/XFSHoster.py
@@ -221,7 +221,7 @@ class XFSHoster(SimpleHoster):
m = re.search(self.CAPTCHA_PATTERN, self.html)
if m:
captcha_url = m.group(1)
- inputs['code'] = self.decrypt_captcha(captcha_url)
+ inputs['code'] = self.captcha.decrypt_image(captcha_url)
return
m = re.search(self.CAPTCHA_BLOCK_PATTERN, self.html, re.S)