From c600bbc3ab7c6fe22d213108086a44ad8f929ca4 Mon Sep 17 00:00:00 2001 From: fragonib Date: Mon, 30 May 2011 23:29:34 +0200 Subject: Support for positional captchas --- module/CaptchaManager.py | 24 ++++-- module/plugins/Plugin.py | 39 ++++----- module/web/json_app.py | 8 +- module/web/templates/default/base.html | 46 +--------- module/web/templates/default/captcha.html | 134 +++++++++++++++++++++++------- pyLoadCore.py | 6 +- 6 files changed, 152 insertions(+), 105 deletions(-) diff --git a/module/CaptchaManager.py b/module/CaptchaManager.py index 7672aa645..539e80744 100644 --- a/module/CaptchaManager.py +++ b/module/CaptchaManager.py @@ -29,8 +29,8 @@ class CaptchaManager(): self.ids = 0 #only for internal purpose - def newTask(self, img, type, temp): - task = CaptchaTask(self.ids, img, type, temp) + def newTask(self, img, format, file, result_type): + task = CaptchaTask(self.ids, img, format, file, result_type) self.ids += 1 return task @@ -81,11 +81,12 @@ class CaptchaManager(): class CaptchaTask(): - def __init__(self, id, img, type, temp): + def __init__(self, id, img, format, file, result_type='textual'): self.id = str(id) self.captchaImg = img - self.captchaType = type - self.captchaFile = temp + self.captchaFormat = format + self.captchaFile = file + self.captchaResultType = result_type self.handler = [] #the hook plugins that will take care of the solution self.result = None self.waitUntil = None @@ -95,10 +96,17 @@ class CaptchaTask(): self.data = {} #handler can store data here def getCaptcha(self): - return self.captchaImg, self.captchaType + return self.captchaImg, self.captchaFormat, self.captchaResultType - def setResult(self, result): - self.result = result + def setResult(self, text): + if self.captchaResultType == 'textual': + self.result = text + if self.captchaResultType == 'positional': + try: + parts = text.split(',') + self.result = (int(parts[0]), int(parts[1])) + except: + self.result = None def getResult(self): try: diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py index 51ad2459b..b27b99170 100644 --- a/module/plugins/Plugin.py +++ b/module/plugins/Plugin.py @@ -241,19 +241,18 @@ class Plugin(object): if self.cTask: self.cTask.correct() - def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype="jpg"): + def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype='jpg', result_type='textual'): """ loads the catpcha and decrypt it or ask the user for input """ + + img = self.load(url, get=get, post=post, cookies=cookies) - content = self.load(url, get=get, post=post, cookies=cookies) - - id = ("%.2f" % time())[-6:].replace(".", "") - temp = open(join("tmp", "tmpCaptcha_%s_%s.%s" % (self.__name__, id, imgtype)), "wb") - - temp.write(content) - temp.close() + id = ("%.2f" % time())[-6:].replace(".","") + temp_file = open(join("tmp", "tmpCaptcha_%s_%s.%s" % (self.__name__, id, imgtype)), "wb") + temp_file.write(img) + temp_file.close() has_plugin = self.core.pluginManager.captchaPlugins.has_key(self.__name__) - + if self.core.captcha: Ocr = self.core.pluginManager.getCaptchaPlugin(self.__name__) else: @@ -262,15 +261,16 @@ class Plugin(object): if Ocr and not forceUser: sleep(randint(3000, 5000) / 1000.0) if self.pyfile.abort: raise Abort - + ocr = Ocr() - result = ocr.get_captcha(temp.name) + result = ocr.get_captcha(temp_file.name) else: + captchaManager = self.core.captchaManager - task = captchaManager.newTask(content, imgtype, temp.name) + task = captchaManager.newTask(img, imgtype, temp_file.name, result_type) self.cTask = task captchaManager.handleCaptcha(task) - + while task.isWaiting(): if self.pyfile.abort: captchaManager.removeTask(task) @@ -286,15 +286,16 @@ class Plugin(object): 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) + self.log.debug("Received captcha result: %s" % str(result)) if not self.core.debug: - try: - remove(temp.name) - except: - pass - + try: + remove(temp_file.name) + except: + pass + return result diff --git a/module/web/json_app.py b/module/web/json_app.py index 39cd81f5f..4b9c91634 100644 --- a/module/web/json_app.py +++ b/module/web/json_app.py @@ -317,17 +317,17 @@ def edit_package(): def set_captcha(): if request.environ.get('REQUEST_METHOD', "GET") == "POST": try: - PYLOAD.set_captcha_result(request.forms["cap_id"], request.forms["cap_text"]) + PYLOAD.set_captcha_result(request.forms["cap_id"], request.forms["cap_result"]) except: pass - id, binary, typ = PYLOAD.get_captcha_task() + id, binary, format, result_type = PYLOAD.get_captcha_task() if id: binary = base64.standard_b64encode(str(binary)) - src = "data:image/%s;base64,%s" % (typ, binary) + src = "data:image/%s;base64,%s" % (format, binary) - return {'captcha': True, 'src': src, 'id': id} + return {'captcha': True, 'id': id, 'src': src, 'result_type' : result_type} else: return {'captcha': False} diff --git a/module/web/templates/default/base.html b/module/web/templates/default/base.html index fd22abbd4..40f002a14 100644 --- a/module/web/templates/default/base.html +++ b/module/web/templates/default/base.html @@ -79,15 +79,6 @@ document.addEvent("domready", function(){ show_cap(); }); - $('cap_reset').addEvent('click', function(){ - hide_cap() - }); - - $('cap_form').addEvent('submit', function(e){ - submit_cap(); - e.stop() - }); - jsonStatus.startTimer(); }); @@ -127,6 +118,7 @@ function LoadJsonToContent(data) $("reconnect").setStyle('background-color', "#fc6e26"); } } + function bg_show(){ $("add_bg").setStyle('display', 'block'); add_bg.start('opacity',0.8); @@ -151,6 +143,7 @@ function out(){ $('add_box').setStyle('display', 'none'); }); } + function show_cap(){ bg_show(); $("cap_box").setStyle('display', 'block'); @@ -164,44 +157,11 @@ function hide_cap(){ }); } -function load_cap(method, post){ - new Request.JSON({ - url: "/json/set_captcha", - onSuccess: function(data){ - if (data.captcha){ - $('cap_img').set('src', data.src); - $('cap_span').setStyle('display', 'block'); - $$('#cap_form p')[0].set('text', '{{_("Please read the text on the captcha.")}}'); - $('cap_id').set('value', data.id); - } else{ - $('cap_img').set('src', ''); - $('cap_span').setStyle('display', 'none'); - $$('#cap_form p')[0].set('text', '{{_("No Captchas to read.")}}'); - } - }, - secure: false, - async: true, - method: method - }).send(post); -} - -function submit_cap(){ - load_cap("post", "cap_id="+ $('cap_id').get('value') +"&cap_text=" + $('cap_text').get('value') ); - $('cap_text').set('value', ''); - return false; -} - - -function AddBox() -{ +function AddBox(){ if ($("add_box").getStyle("display") == "hidden" || $("add_box").getStyle("display") == "none" || $("add_box").getStyle("opacity" == 0)) - { show(); - } else - { out(); - } } diff --git a/module/web/templates/default/captcha.html b/module/web/templates/default/captcha.html index b3be3deca..0165fed10 100644 --- a/module/web/templates/default/captcha.html +++ b/module/web/templates/default/captcha.html @@ -1,35 +1,113 @@ - - - -
-
-

{{_("Captcha reading")}}

-

{{_("Please read the text on the captcha.")}}

- - - - - - - - - - + + - - - - - -
+ +
+ + +

{{_("Captcha reading")}}

+

{{_("Please read the text on the captcha.")}}

+ +
+ + + + + + + + + + + +
+ +
+ +
- +
+ + + + +
+ +
+ +
\ No newline at end of file diff --git a/pyLoadCore.py b/pyLoadCore.py index 593fb046e..a4311b75b 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -775,10 +775,10 @@ class ServerMethods(): task = self.core.captchaManager.getTask() if task: task.setWatingForUser(exclusive=exclusive) - c = task.getCaptcha() - return str(task.id), c[0], str(c[1]) + captcha_info = task.getCaptcha() + return (task.id,) + captcha_info else: - return None, None, None + return None, None, None, None def get_task_status(self, tid): self.core.lastClientConnected = time() -- cgit v1.2.3