summaryrefslogtreecommitdiffstats
path: root/module/plugins/captcha
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins/captcha')
-rw-r--r--module/plugins/captcha/AdYouLike.py92
-rw-r--r--module/plugins/captcha/AdsCaptcha.py64
-rw-r--r--module/plugins/captcha/CircleCaptcha.py707
-rw-r--r--module/plugins/captcha/GigasizeCom.py11
-rw-r--r--module/plugins/captcha/LinksaveIn.py29
-rw-r--r--module/plugins/captcha/NetloadIn.py11
-rw-r--r--module/plugins/captcha/OCR.py319
-rw-r--r--module/plugins/captcha/ReCaptcha.py197
-rw-r--r--module/plugins/captcha/ShareonlineBiz.py17
-rw-r--r--module/plugins/captcha/SolveMedia.py105
10 files changed, 848 insertions, 704 deletions
diff --git a/module/plugins/captcha/AdYouLike.py b/module/plugins/captcha/AdYouLike.py
new file mode 100644
index 000000000..f91b5805c
--- /dev/null
+++ b/module/plugins/captcha/AdYouLike.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.common.json_layer import json_loads
+from module.plugins.internal.CaptchaService import CaptchaService
+
+
+class AdYouLike(CaptchaService):
+ __name__ = "AdYouLike"
+ __type__ = "captcha"
+ __version__ = "0.07"
+ __status__ = "testing"
+
+ __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, data=None):
+ html = data or self.retrieve_data()
+
+ 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.log_debug("Ayl: %s | Callback: %s" % self.key)
+ return self.key #: Key is the tuple(ayl, callback)
+ else:
+ self.log_warning(_("Ayl or callback pattern not found"))
+ return None
+
+
+ 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"}}
+ ayl = json_loads(ayl)
+
+ html = self.plugin.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:
+ self.fail(_("AdYouLike challenge pattern not found"))
+
+ self.log_debug("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:
+ self.fail(_("AdYouLike result not found"))
+
+ result = {'_ayl_captcha_engine' : "adyoulike",
+ '_ayl_env' : server['all']['env'],
+ '_ayl_tid' : challenge['tid'],
+ '_ayl_token_challenge': challenge['token'],
+ '_ayl_response' : response}
+
+ self.log_debug("Result: %s" % result)
+
+ return result
diff --git a/module/plugins/captcha/AdsCaptcha.py b/module/plugins/captcha/AdsCaptcha.py
new file mode 100644
index 000000000..613283e53
--- /dev/null
+++ b/module/plugins/captcha/AdsCaptcha.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+
+import random
+import re
+
+from module.plugins.internal.CaptchaService import CaptchaService
+
+
+class AdsCaptcha(CaptchaService):
+ __name__ = "AdsCaptcha"
+ __type__ = "captcha"
+ __version__ = "0.10"
+ __status__ = "testing"
+
+ __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, data=None):
+ html = data or self.retrieve_data()
+
+ 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.log_debug("Key: %s | ID: %s" % self.key)
+ return self.key
+ else:
+ self.log_warning(_("Key or id pattern not found"))
+ return None
+
+
+ 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,
+ 'PublicKey': PublicKey})
+ try:
+ challenge = re.search("challenge: '(.+?)',", html).group(1)
+ server = re.search("server: '(.+?)',", html).group(1)
+
+ except AttributeError:
+ self.fail(_("AdsCaptcha challenge pattern not found"))
+
+ self.log_debug("Challenge: %s" % challenge)
+
+ return self.result(server, challenge), challenge
+
+
+ def result(self, server, challenge):
+ result = self.decrypt("%sChallenge.aspx" % server,
+ get={'cid': challenge, 'dummy': random.random()},
+ cookies=True,
+ input_type="jpg")
+
+ self.log_debug("Result: %s" % result)
+
+ return result
diff --git a/module/plugins/captcha/CircleCaptcha.py b/module/plugins/captcha/CircleCaptcha.py
index d4f08018d..dc04a04c8 100644
--- a/module/plugins/captcha/CircleCaptcha.py
+++ b/module/plugins/captcha/CircleCaptcha.py
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
+#
+#@TODO: Recheck all
from __future__ import division
@@ -9,7 +11,7 @@ import math
import operator
import urllib
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class ImageSequence:
@@ -29,7 +31,8 @@ class ImageSequence:
class CircleCaptcha(OCR):
__name__ = "CircleCaptcha"
__type__ = "ocr"
- __version__ = "1.00"
+ __version__ = "1.04"
+ __status__ = "testing"
__description__ = """Circle captcha ocr plugin"""
__license__ = "GPLv3"
@@ -43,11 +46,11 @@ class CircleCaptcha(OCR):
BLACKCOLOR = 5
- def cleanImage(self, im, pix):
+ def clean_image(self, im, pix):
cleandeep = 1
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(1,int(im.size[0]))
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(1, int(im.size[0]))
howmany = 0
curcolor = self.BACKGROUND
@@ -55,184 +58,184 @@ class CircleCaptcha(OCR):
jump = True
howmany = 0
for x in imagewidth:
- curpix = pix[x,y]
+ curpix = pix[x, y]
if curpix > self.BACKGROUND:
if howmany <= cleandeep and howmany > 0:
- # clean pixel
- for ic in range(1,cleandeep+1):
+ #: Clean pixel
+ for ic in xrange(1, cleandeep+1):
if x -ic > 0:
- pix[x-ic,y] = self.BACKGROUND
+ pix[x-ic, y] = self.BACKGROUND
jump = False
howmany = 0
curcolor = curpix
- # print (x, y), jump,2
+ # self.log_debug(x, y, jump, 2)
else:
if howmany == 0:
- # found pixel
+ #: Found pixel
jump = True
howmany = howmany + 1
curcolor = curpix
- # print (x, y), jump,2
+ # self.log_debug(x, y, jump, 2)
else:
howmany = howmany + 1
if howmany == 1:
- # clean pixel
- pix[x-1,y] = self.BACKGROUND
+ #: Clean pixel
+ pix[x-1, y] = self.BACKGROUND
curcolor = self.BACKGROUND
for x in imagewidth:
jump = True
howmany = 0
for y in imageheight:
- curpix = pix[x,y]
- # if jump == True:
+ curpix = pix[x, y]
+ # if jump is True:
if curpix > self.BACKGROUND:
if howmany <= cleandeep and howmany > 0:
- # clean pixel
- for ic in range(1,cleandeep+1):
- # raw_input('2'+str(ic))
+ #: Clean pixel
+ for ic in xrange(1, cleandeep+1):
+ #: raw_input('2'+str(ic))
if y-ic > 0:
- pix[x,y-ic] = self.BACKGROUND
+ pix[x, y-ic] = self.BACKGROUND
jump = False
howmany = 0
curcolor = curpix
- # print (x, y), jump
+ # self.log_debug(x, y, jump)
else:
if howmany == 0:
- # found pixel
+ #: Found pixel
jump = True
howmany = howmany + 1
curcolor = curpix
- # print (x, y), jump
+ # self.log_debug(x, y, jump)
else:
howmany = howmany + 1
if howmany == 1:
- # clean pixel
- pix[x-1,y] = self.BACKGROUND
+ #: Clean pixel
+ pix[x-1, y] = self.BACKGROUND
- # return -1
+ #: return -1
- def findFirstPixelX(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(curx+1,int(im.size[0]))
+ def find_first_pixel_x(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(curx+1, int(im.size[0]))
jump = True
- newx = (-1,-1)
+ newx = (-1, -1)
blackfound = 0
for x in imagewidth:
- curpix = pix[x,cury]
+ curpix = pix[x, cury]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- # found first pixel white
+ #: Found first pixel white
jump = False
- continue;
+ continue
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- if jump == False:
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ if jump is False:
+ #: Found pixel
curcolor = curpix
newx = x, curcolor
- break;
+ break
return newx
- def findLastPixelX(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
- imageheight = range(1,int(im.size[1]))
- imagewidth = range(curx+1,int(im.size[0]))
- newx = (-1,-1)
+ def find_last_pixel_x(self, im, pix, curx, cury, color = -1, ExitWithBlack = False):
+ imageheight = xrange(1, int(im.size[1]))
+ imagewidth = xrange(curx+1, int(im.size[0]))
+ newx = (-1, -1)
blackfound = 0
for x in imagewidth:
- curpix = pix[x,cury]
+ curpix = pix[x, cury]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- if newx != (-1,-1):
- # found last pixel and the first white
- break;
+ if newx != (-1, -1):
+ #: Found last pixel and the first white
+ break
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ #: Found pixel
curcolor = curpix
newx = x, curcolor
return newx
- def findLastPixelY(self, im, pix, curx, cury, DownToUp, color = -1, ExitWithBlack = False):
- if DownToUp == False:
- imageheight = range(int(cury)+1,int(im.size[1])-1)
+ def find_last_pixel_y(self, im, pix, curx, cury, DownToUp, color = -1, ExitWithBlack = False):
+ if DownToUp is False:
+ imageheight = xrange(int(cury)+1, int(im.size[1])-1)
else:
- imageheight = range(int(cury)-1,1,-1)
- imagewidth = range(int(curx),int(im.size[0]))
- newy = (-1,-1)
+ imageheight = xrange(int(cury)-1, 1, -1)
+ imagewidth = xrange(int(curx), int(im.size[0]))
+ newy = (-1, -1)
blackfound = 0
for y in imageheight:
- curpix = pix[curx,y]
+ curpix = pix[curx, y]
if curpix < self.BLACKCOLOR:
blackfound = blackfound + 1
- if ExitWithBlack == True and blackfound >= 3:
- break; #exit if found black
+ if ExitWithBlack is True and blackfound >= 3:
+ break #: Exit if found black
else:
- continue;
+ continue
if curpix >= self.BACKGROUND:
- if newy != (-1,-1):
- # found last pixel and the first white
- break;
+ if newy != (-1, -1):
+ #: Found last pixel and the first white
+ break
- if (curpix < self.BACKGROUND and color == -1) or (curpix == color and color > -1):
- # found pixel
+ if (curpix < self.BACKGROUND and color == -1) or (curpix is color and color > -1):
+ #: Found pixel
curcolor = curpix
newy = y, color
return newy
- def findCircle(self, pix, x1, y1, x2, y2, x3, y3):
- # trasposizione coordinate
- # A(0,0) B(x2-x1,y2-y1) C(x3-x1,y3-y1)
- # x**2+y**2+ax+bx+c=0
- p1 = (0,0)
- p2 = (x2-x1,y2-y1)
- p3 = (x3-x1,y3-y1)
+ def find_circle(self, pix, x1, y1, x2, y2, x3, y3):
+ #: Trasposizione coordinate
+ #: A(0, 0) B(x2-x1, y2-y1) C(x3-x1, y3-y1)
+ #: x**2+y**2+ax+bx+c=0
+ p1 = (0, 0)
+ p2 = (x2-x1, y2-y1)
+ p3 = (x3-x1, y3-y1)
- # 1
+ #: 1
c=0
- # 2
- # p2[0]**2+a*p2[0]+c=0
- # a*p2[0]=-1*(p2[0]**2-c)
- # a=(-1*(p2[0]**2-c))/p2[0]
+ #: 2
+ #: p2[0]**2+a*p2[0]+c=0
+ #: a*p2[0]=-1*(p2[0]**2-c)
+ #: a=(-1*(p2[0]**2-c))/p2[0]
a=(-1*(p2[0]**2-c))/p2[0]
- # 3
- # p3[0]**2+p3[1]**2+a*p3[0]+b*p3[1]+c=0
- # b*p3[1]=-(p3[0]**2+p3[1]**2+a*p3[0]+c)
- # b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
+ #: 3
+ #: p3[0]**2+p3[1]**2+a*p3[0]+b*p3[1]+c=0
+ #: b*p3[1]=-(p3[0]**2+p3[1]**2+a*p3[0]+c)
+ #: b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
b=(-1 * (p3[0]**2+p3[1]**2+a*p3[0]+c)) / p3[1]
r=math.floor(math.sqrt((-1*(a/2))**2+(-1*(b/2))**2))
cx=math.floor((-1*(a/2))+x1)
cy=math.floor((-1*(b/2))+y1)
- return cx,cy,r
+ return cx, cy, r
- def verifyCircleNew(self, im, pix, c):
+ def verify_circle_new(self, im, pix, c):
"""
This is the MAIN function to recognize the circle
returns:
@@ -241,9 +244,8 @@ class CircleCaptcha(OCR):
-1 -> Not found circle
-2 -> Found black position then leave position
"""
-
- imageheight = range(int(c[1]-c[2]),int(c[1]+c[2]))
- imagewidth = range(int(c[0]-c[2]),int(c[0]+c[2]))
+ imageheight = xrange(int(c[1]-c[2]), int(c[1]+c[2]))
+ imagewidth = xrange(int(c[0]-c[2]), int(c[0]+c[2]))
min_ray = 15
max_ray = 30
@@ -253,68 +255,73 @@ class CircleCaptcha(OCR):
missing = 0
missingconsecutive = 0
missinglist = []
- minX = 0; maxX = 0; minY = 0; maxY = 0
+
+ minX = 0
+ maxX = 0
+ minY = 0
+ maxY = 0
+
pointsofcircle = []
if (c[2] < min_ray) or (c[2] > max_ray):
return -1
- # check cardinal points (at least 3) (if found i have to leave this position)
- if pix[c[0] + c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0] - c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] + c[2]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] - c[2]] < self.BLACKCOLOR:
- return -2;
+ #: Check cardinal points (at least 3) (if found i have to leave this position)
+ if pix[c[0] + c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0] - c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] + c[2]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] - c[2]] < self.BLACKCOLOR:
+ return -2
cardinalpoints = 0
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0] - c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],True) == 1:
+ if self.verify_point(im, pix, c[0] - c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] + c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],True) == 1:
+ if self.verify_point(im, pix, c[0], c[1] + c[2], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] - c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],False) == -1:
- return -2;
+ if self.verify_point(im, pix, c[0], c[1] - c[2], False) == -1:
+ return -2
if cardinalpoints < 3:
- return -1;
+ return -1
for x in imagewidth:
- # Pitagora
+ #: Pitagora
y = int(round(c[1]- math.sqrt(c[2]**2-(c[0]-x)**2)))
y2= int(round(c[1]+ math.sqrt(c[2]**2-(c[0]-x)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x,y2,exactfind) == 0:
+ if self.verify_point(im, pix, x, y2, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y2))
+ missinglist.append((x, y2))
else:
- pointsofcircle.append((x,y2))
+ pointsofcircle.append((x, y2))
- if self.verifyPoint(im, pix, x,y2,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y2, False) == -1:
+ return -2
- def verifyCircle(self, im, pix, c):
+ def verify_circle(self, im, pix, c):
"""
This is the MAIN function to recognize the circle
returns:
@@ -323,9 +330,8 @@ class CircleCaptcha(OCR):
-1 -> Not found circle
-2 -> Found black position then leave position
"""
-
- imageheight = range(int(c[1]-c[2]),int(c[1]+c[2]))
- imagewidth = range(int(c[0]-c[2]),int(c[0]+c[2]))
+ imageheight = xrange(int(c[1]-c[2]), int(c[1]+c[2]))
+ imagewidth = xrange(int(c[0]-c[2]), int(c[0]+c[2]))
min_ray = 15
max_ray = 30
@@ -335,119 +341,124 @@ class CircleCaptcha(OCR):
missing = 0
missingconsecutive = 0
missinglist = []
- minX = 0; maxX = 0; minY = 0; maxY = 0
+
+ minX = 0
+ maxX = 0
+ minY = 0
+ maxY = 0
+
pointsofcircle = []
if (c[2] < min_ray) or (c[2] > max_ray):
return -1
- # check cardinal points (at least 3) (if found i have to leave this position)
- if pix[c[0] + c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0] - c[2],c[1]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] + c[2]] < self.BLACKCOLOR:
- return -2;
- if pix[c[0],c[1] - c[2]] < self.BLACKCOLOR:
- return -2;
+ #: Check cardinal points (at least 3) (if found i have to leave this position)
+ if pix[c[0] + c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0] - c[2], c[1]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] + c[2]] < self.BLACKCOLOR:
+ return -2
+ if pix[c[0], c[1] - c[2]] < self.BLACKCOLOR:
+ return -2
cardinalpoints = 0
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] + c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],True) == 1:
+ if self.verify_point(im, pix, c[0] + c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0] - c[2], c[1], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0] - c[2],c[1],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],True) == 1:
+ if self.verify_point(im, pix, c[0] - c[2], c[1], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] + c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] + c[2],False) == -1:
- return -2;
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],True) == 1:
+ if self.verify_point(im, pix, c[0], c[1] + c[2], False) == -1:
+ return -2
+ if self.verify_point(im, pix, c[0], c[1] - c[2], True) == 1:
cardinalpoints = cardinalpoints + 1
- if self.verifyPoint(im, pix,c[0],c[1] - c[2],False) == -1:
- return -2;
+ if self.verify_point(im, pix, c[0], c[1] - c[2], False) == -1:
+ return -2
if cardinalpoints < 3:
- return -1;
+ return -1
for x in imagewidth:
- # Pitagora
+ #: Pitagora
y = int(round(c[1]- math.sqrt(c[2]**2-(c[0]-x)**2)))
y2= int(round(c[1]+ math.sqrt(c[2]**2-(c[0]-x)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x,y2,exactfind) == 0:
+ if self.verify_point(im, pix, x, y2, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y2))
+ missinglist.append((x, y2))
else:
- pointsofcircle.append((x,y2))
+ pointsofcircle.append((x, y2))
- if self.verifyPoint(im, pix, x,y2,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y2, False) == -1:
+ return -2
for y in imageheight:
- # Pitagora
+ #: Pitagora
x = int(round(c[0]- math.sqrt(c[2]**2-(c[1]-y)**2)))
x2= int(round(c[0]+ math.sqrt(c[2]**2-(c[1]-y)**2)))
howmany = howmany + 2
- if self.verifyPoint(im, pix, x,y,exactfind) == 0:
+ if self.verify_point(im, pix, x, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x,y))
+ missinglist.append((x, y))
else:
- pointsofcircle.append((x,y))
+ pointsofcircle.append((x, y))
- if self.verifyPoint(im, pix, x,y,False) == -1:
- return -2;
+ if self.verify_point(im, pix, x, y, False) == -1:
+ return -2
- if self.verifyPoint(im, pix, x2,y,exactfind) == 0:
+ if self.verify_point(im, pix, x2, y, exactfind) == 0:
missing = missing + 1
- missinglist.append((x2,y))
+ missinglist.append((x2, y))
else:
- pointsofcircle.append((x2,y))
+ pointsofcircle.append((x2, y))
- if self.verifyPoint(im, pix, x2,y,exactfind) == -1:
- return -2;
+ if self.verify_point(im, pix, x2, y, exactfind) == -1:
+ return -2
for p in missinglist:
- # left and bottom
- if (self.verifyPoint(im, pix, p[0]-1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]+1,exactfind) == 1):
+ #: Left and bottom
+ if (self.verify_point(im, pix, p[0]-1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]+1, exactfind) == 1):
missing = missing - 1
- elif (self.verifyPoint(im, pix, p[0]-1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]-1,exactfind) == 1):
+ elif (self.verify_point(im, pix, p[0]-1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]-1, exactfind) == 1):
missing = missing - 1
- # right and bottom
- elif (self.verifyPoint(im, pix, p[0]+1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]+1,exactfind) == 1):
+ #: Right and bottom
+ elif (self.verify_point(im, pix, p[0]+1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]+1, exactfind) == 1):
missing = missing - 1
- # right and up
- elif (self.verifyPoint(im, pix, p[0]+1, p[1],exactfind) == 1 and \
- self.verifyPoint(im, pix, p[0], p[1]-1,exactfind) == 1):
+ #: Right and up
+ elif (self.verify_point(im, pix, p[0]+1, p[1], exactfind) == 1
+ and self.verify_point(im, pix, p[0], p[1]-1, exactfind) == 1):
missing = missing - 1
- if (p[0], p[1]+1) in missinglist or \
- (p[0], p[1]-1) in missinglist or \
- (p[0]+1, p[1]) in missinglist or \
- (p[0]-1, p[1]) in missinglist or \
- (p[0]+1, p[1]+1) in missinglist or \
- (p[0]-1, p[1]+1) in missinglist or \
- (p[0]+1, p[1]-1) in missinglist or \
- (p[0]-1, p[1]-1) in missinglist or \
- self.verifyPoint(im, pix, p[0], p[1],False) == 1:
+ if ((p[0], p[1]+1) in missinglist
+ or (p[0], p[1]-1) in missinglist
+ or (p[0]+1, p[1]) in missinglist
+ or (p[0]-1, p[1]) in missinglist
+ or (p[0]+1, p[1]+1) in missinglist
+ or (p[0]-1, p[1]+1) in missinglist
+ or (p[0]+1, p[1]-1) in missinglist
+ or (p[0]-1, p[1]-1) in missinglist
+ or self.verify_point(im, pix, p[0], p[1], False) == 1):
missingconsecutive = missingconsecutive + 1
# else:
- # pix[p[0], p[1]] = 0
+ # pix[p[0], p[1]] = 0
if missing / howmany > 0:
indice = c[2] * (missing / howmany)
@@ -461,80 +472,79 @@ class CircleCaptcha(OCR):
minY = min(missinglist, key=operator.itemgetter(1))[1]
maxY = max(missinglist, key=operator.itemgetter(1))[1]
- # Assial Simmetric
- if self._DEBUG == True:
- print "Center: " + str(c)
- print "Missing: " + str(missing)
- print "Howmany: " + str(howmany)
- print "Ratio: " + str(missing / howmany)
- print "Missing consecutives: " + str(missingconsecutive)
- print "Missing X lenght: " + str(minX) + ":" + str(maxX)
- print "Missing Y lenght: " + str(minY) + ":" + str(maxY)
- print "Ratio without consecutives: " + str((missing - missingconsecutive) / howmany)
- print "List missing: " + str(missinglist)
+ #: Assial Simmetric
+ if self.pyload.debug:
+ self.log_debug("Center: " + str(c),
+ "Missing: " + str(missing),
+ "Howmany: " + str(howmany),
+ "Ratio: " + str(missing / howmany),
+ "Missing consecutives: " + str(missingconsecutive),
+ "Missing X lenght: " + str(minX) + ":" + str(maxX),
+ "Missing Y lenght: " + str(minY) + ":" + str(maxY),
+ "Ratio without consecutives: " + str((missing - missingconsecutive) / howmany),
+ "List missing: " + str(missinglist))
- # Lenght of missing cannot be over 75% of diameter
+ #: Lenght of missing cannot be over 75% of diameter
if maxX - minX >= c[2] * 2 * 0.75:
- return -1;
+ return -1
if maxY - minY >= c[2] * 2 * 0.75:
- # raw_input('tro')
- return -1;
+ #: raw_input('tro')
+ return -1
"""
- # Lenght of missing cannot be less 10% of diameter
+ #: Lenght of missing cannot be less 10% of diameter
if maxX - minX < c[2] * 2 * 0.10 and maxY - minY < c[2] * 2 * 0.10:
- return -1;
+ return -1
"""
-
if missing / howmany > 0.25 or \
missingconsecutive >= (howmany / 4) * 2 or \
howmany < 80:
- return -1;
+ return -1
# elif missing / howmany < 0.10:
elif missing == 0:
self.pointsofcirclefound.extend(pointsofcircle)
- return 1;
+ return 1
elif (missing - missingconsecutive) / howmany < 0.20:
- return 0;
+ return 0
else:
self.pointsofcirclefound.extend(pointsofcircle)
- return 1;
+ return 1
- def verifyPoint(self, im, pix, x,y,exact,color = -1):
- # Verify point
+ def verify_point(self, im, pix, x, y, exact, color = -1):
+ #: Verify point
result = 0
if x < 0 or x >= im.size[0]:
- return result;
+ return result
if y < 0 or y >= im.size[1]:
- return result;
+ return result
- curpix = pix[x,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
else:
result = -1
- # Verify around
- if (exact == False):
+ #: Verify around
+ if exact is False:
if x + 1 < im.size[0]:
- curpix = pix[x+1,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x+1, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
if curpix <= self.BLACKCOLOR:
result = -1
if x > 0:
- curpix = pix[x-1,y]
- if (curpix == color and color > -1) or (curpix < self.BACKGROUND and color == -1):
+ curpix = pix[x-1, y]
+ if (curpix is color and color > -1) or (curpix < self.BACKGROUND and color == -1):
if curpix > self.BLACKCOLOR:
result = 1
if curpix <= self.BLACKCOLOR:
result = -1
- # print str((x,y)) + " = " + str(result);
+ # self.log_debug(str((x, y)) + " = " + str(result))
return result
@@ -543,22 +553,23 @@ class CircleCaptcha(OCR):
mypalette = None
for im in ImageSequence(img):
im.save("orig.png", "png")
- if mypalette != None:
+ if mypalette is not None:
im.putpalette(mypalette)
mypalette = im.getpalette()
im = im.convert('L')
- if self._DEBUG == True:
+ if self.pyload.debug:
iDebugSaveFile = iDebugSaveFile + 1
- # if iDebugSaveFile < 7: continue;
+ # if iDebugSaveFile < 7:
+ # continue
im.save("output" + str(iDebugSaveFile) + ".png", "png")
raw_input('frame: '+ str(im))
pix = im.load()
- stepheight = range(1,im.size[1],2)
- # stepheight = range(45,47)
- imagewidth = range(1,im.size[0])
+ stepheight = xrange(1, im.size[1], 2)
+ #: stepheight = xrange(45, 47)
+ imagewidth = xrange(1, im.size[0])
lstPoints = [] # Declares an empty list for the points
lstX = [] # CoordinateX
lstY = [] # CoordinateY
@@ -566,209 +577,211 @@ class CircleCaptcha(OCR):
min_distance = 10
max_diameter = 70
- if self._DEBUG == True:
+ if self.pyload.debug:
imdebug = im.copy()
draw = ImageDraw.Draw(imdebug)
pixcopy = imdebug.load()
- # Clean image for powerfull search
- self.cleanImage(im, pix)
+ #: Clean image for powerfull search
+ self.clean_image(im, pix)
im.save("cleaned" + str(iDebugSaveFile) + ".png", "png")
found = set()
findnewcircle = True
- # finding all the circles
+ #: Finding all the circles
for y1 in stepheight:
x1 = 1
curcolor = -1
- for k in range(1,100):
+ for k in xrange(1, 100):
findnewcircle = False
- retval = self.findFirstPixelX(im, pix, x1, y1, -1, False)
+ retval = self.find_first_pixel_x(im, pix, x1, y1, -1, False)
x1 = retval[0]
curcolor = retval[1]
if x1 == -2:
- break;
+ break
if x1 == -1:
- break;
- if self._DEBUG == True: print "x1, y1 -> " + str((x1,y1)) + ": " + str(pix[x1,y1])
-
- if (x1,y1) in self.pointsofcirclefound:
- if self._DEBUG == True: print 'found ' + str((x1,y1))
- continue;
-
- if self._DEBUG == True: pixcopy[x1,y1] = 45 #(255,0,0,255)
- # found 1 pixel, seeking x2,y2
+ break
+ if self.pyload.debug:
+ self.log_debug("x1, y1 -> " + str((x1, y1)) + ": " + str(pix[x1, y1]))
+
+ if (x1, y1) in self.pointsofcirclefound:
+ if self.pyload.debug:
+ self.log_debug("Found " + str((x1, y1)))
+ continue
+
+ if self.pyload.debug:
+ pixcopy[x1, y1] = 45 #(255, 0, 0, 255)
+ #: found 1 pixel, seeking x2, y2
x2 = x1
y2 = y1
- for i in range(1,100):
- retval = self.findLastPixelX(im, pix, x2, y2, -1, True)
+ for i in xrange(1, 100):
+ retval = self.find_last_pixel_x(im, pix, x2, y2, -1, True)
x2 = retval[0]
if x1 == -2:
findnewcircle = True
- break;
+ break
if x2 == -1:
- break;
- if self._DEBUG == True: print "x2, y2 -> " + str((x2,y1)) + ": " + str(pix[x2,y1])
+ break
+ if self.pyload.debug:
+ self.log_debug("x2, y2 -> " + str((x2, y1)) + ": " + str(pix[x2, y1]))
if abs(x2 - x1) < min_distance:
- continue;
+ continue
if abs(x2 - x1) > (im.size[1] * 2 / 3):
- break;
+ break
if abs(x2 - x1) > max_diameter:
- break;
+ break
- if self._DEBUG == True: pixcopy[x2,y2] = 65 #(0,255,0,255)
- # found 2 pixel, seeking x3,y3
- # verify cord
+ if self.pyload.debug:
+ pixcopy[x2, y2] = 65 #(0, 255, 0, 255)
+ #: found 2 pixel, seeking x3, y3
+ #: Verify cord
- for invert in range(0,2):
+ for invert in xrange(0, 2):
x3 = math.floor(x2 - ((x2 - x1) / 2))
y3 = y1
- for j in range(1,50):
- retval = self.findLastPixelY(im, pix, x3, y3, True if invert == 1 else False, -1, True)
- # print (x3, y3,retval[0],invert)
+ for j in xrange(1, 50):
+ retval = self.find_last_pixel_y(im, pix, x3, y3, True if invert == 1 else False, -1, True)
+ # self.log_debug(x3, y3, retval[0], invert)
y3 = retval[0]
if y3 == -2:
findnewcircle = True
- break;
+ break
if y3 == -1:
- break;
+ break
- if self._DEBUG == True: print "x3, y3 -> " + str((x3,y3)) + ": " + str(pix[x3,y3])
- # verify cord
+ if self.pyload.debug:
+ self.log_debug("x3, y3 -> " + str((x3, y3)) + ": " + str(pix[x3, y3]))
+ #: Verify cord
if abs(y3 - y2) < min_distance:
- continue;
+ continue
if abs(y3 - y2) > (im.size[1] * 2 / 3):
- break;
+ break
if abs(y3 - y2) > max_diameter:
- break;
+ break
- if self._DEBUG == True: pixcopy[x3,y3] = 85
- # found 3 pixel. try circle
- c = self.findCircle(pix, x1,y1,x2,y2,x3,y3)
+ if self.pyload.debug:
+ pixcopy[x3, y3] = 85
+ #: found 3 pixel. try circle
+ c = self.find_circle(pix, x1, y1, x2, y2, x3, y3)
if c[0] + c[2] >= im.size[0] or c[1] + c[2] >= im.size[1] or c[0] - c[2] <= 0 or c[1] - c[2] <= 0:
- continue;
+ continue
- if self._DEBUG == True: pixcopy[c[0],c[1]] = 0
- # (x-r, y-r, x+r, y+r)
- verified = self.verifyCircle(im, pix, c)
+ if self.pyload.debug:
+ pixcopy[c[0], c[1]] = 0
+ #: (x-r, y-r, x+r, y+r)
+ verified = self.verify_circle(im, pix, c)
if verified == -1:
verified = -1
elif verified == 0:
- found.add(((c[0],c[1],c[2]),verified))
+ found.add(((c[0], c[1], c[2]), verified))
findnewcircle = True
elif verified == 1:
- found.add(((c[0],c[1],c[2]),verified))
+ found.add(((c[0], c[1], c[2]), verified))
findnewcircle = True
- if self._DEBUG == True:
+ if self.pyload.debug:
_pause = ""
# if verified == -1:
- # draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=0)
+ # draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=0)
# _pause = "NOTDOUND"
# imdebug.save("debug.png", "png")
if verified == 0:
- draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=120)
+ draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=120)
_pause = "OPENED"
if verified == 1:
- draw.ellipse((c[0]-c[2],c[1]-c[2],c[0]+c[2],c[1]+c[2]),outline=65)
+ draw.ellipse((c[0]-c[2], c[1]-c[2], c[0]+c[2], c[1]+c[2]), outline=65)
_pause = "CLOSED"
imdebug.save("debug.png", "png")
if _pause != "":
valore = raw_input('Found ' + _pause + ' CIRCLE circle press [Enter] = continue / [q] for Quit: ' + str(verified))
- if valore == 'q':
- sys.exit();
+ if valore == "q":
+ sys.exit()
- if findnewcircle == True:
- break;
- if findnewcircle == True:
- break;
- if findnewcircle == True:
- break;
+ if findnewcircle is True:
+ break
+ if findnewcircle is True:
+ break
+ if findnewcircle is True:
+ break
- if self._DEBUG == True:
- print 'Howmany opened circle? ' + str(len(found)) + ' ' + str(found)
+ if self.pyload.debug:
+ self.log_debug('Howmany opened circle? ' + str(len(found)) + ' ' + str(found))
- # clean results
+ #: Clean results
for c in found:
verify = c[1]
if verify == 0:
p = c[0]
- if (
- ((p[0], p[1]+1,p[2]),1) in found or \
- ((p[0], p[1]-1,p[2]),1) in found or \
- ((p[0]+1, p[1],p[2]),1) in found or \
- ((p[0]-1, p[1],p[2]),1) in found or \
- ((p[0]+1, p[1]+1,p[2]),1) in found or \
- ((p[0]-1, p[1]+1,p[2]),1) in found or \
- ((p[0]+1, p[1]-1,p[2]),1) in found or \
- ((p[0]-1, p[1]-1,p[2]),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]), 1) in found
+ or ((p[0], p[1]-1, p[2]), 1) in found
+ or ((p[0]+1, p[1], p[2]), 1) in found
+ or ((p[0]-1, p[1], p[2]), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]), 1) in found):
+
+ #: Delete nearly circle
verify = -1
- if (
- ((p[0], p[1]+1,p[2]+1),1) in found or \
- ((p[0], p[1]-1,p[2]+1),1) in found or \
- ((p[0]+1, p[1],p[2]+1),1) in found or \
- ((p[0]-1, p[1],p[2]+1),1) in found or \
- ((p[0]+1, p[1]+1,p[2]+1),1) in found or \
- ((p[0]-1, p[1]+1,p[2]+1),1) in found or \
- ((p[0]+1, p[1]-1,p[2]+1),1) in found or \
- ((p[0]-1, p[1]-1,p[2]+1),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]+1), 1) in found
+ or ((p[0], p[1]-1, p[2]+1), 1) in found
+ or ((p[0]+1, p[1], p[2]+1), 1) in found
+ or ((p[0]-1, p[1], p[2]+1), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]+1), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]+1), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]+1), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]+1), 1) in found):
+
+ #: Delete nearly circle
verify = -1
- if (
- ((p[0], p[1]+1,p[2]-1),1) in found or \
- ((p[0], p[1]-1,p[2]-1),1) in found or \
- ((p[0]+1, p[1],p[2]-1),1) in found or \
- ((p[0]-1, p[1],p[2]-1),1) in found or \
- ((p[0]+1, p[1]+1,p[2]-1),1) in found or \
- ((p[0]-1, p[1]+1,p[2]-1),1) in found or \
- ((p[0]+1, p[1]-1,p[2]-1),1) in found or \
- ((p[0]-1, p[1]-1,p[2]-1),1) in found \
- ):
-
- # delete nearly circle
+ if (((p[0], p[1]+1, p[2]-1), 1) in found
+ or ((p[0], p[1]-1, p[2]-1), 1) in found
+ or ((p[0]+1, p[1], p[2]-1), 1) in found
+ or ((p[0]-1, p[1], p[2]-1), 1) in found
+ or ((p[0]+1, p[1]+1, p[2]-1), 1) in found
+ or ((p[0]-1, p[1]+1, p[2]-1), 1) in found
+ or ((p[0]+1, p[1]-1, p[2]-1), 1) in found
+ or ((p[0]-1, p[1]-1, p[2]-1), 1) in found):
+
+ #: Delete nearly circle
verify = -1
# if verify == 0:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 90 #(255,255,0)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 90 #(255, 255, 0)
# im.save("output.png", "png")
- # return c[0][0],c[0][1]
+ # return c[0][0], c[0][1]
# elif verify == 1:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 40 #(255,0,0)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 40 #(255, 0, 0)
# im.save("output.png", "png")
# else:
- # if self._DEBUG == True:
- # pix[c[0][0],c[0][1]] = 180 #(0,0,255)
+ # if self.pyload.debug:
+ # pix[c[0][0], c[0][1]] = 180 #(0, 0, 255)
# im.save("output.png", "png")
- if self._DEBUG == True:
+ if self.pyload.debug:
im.save("output.png", "png")
- # Return coordinates of opened circle (eg (x,y))
+ #: Return coordinates of opened circle (eg (x, y))
def decrypt_from_web(self, url):
file = cStringIO.StringIO(urllib.urlopen(url).read())
img = Image.open(file)
- coords = self.decrypt(img);
- print "Coords: " + str(coords)
+ coords = self.decrypt(img)
+ self.log_info(_("Coords: %s") % coords)
- # Return coordinates of opened circle (eg (x,y))
+ #: Return coordinates of opened circle (eg (x, y))
def decrypt_from_file(self, filename):
- coords = self.decrypt(Image.open(filename)); #Can be many different formats.
- print "Coords: " + str(coords)
+ coords = self.decrypt(Image.open(filename)) #: Can be many different formats.
+ self.log_info(_("Coords: %s") % coords)
##DEBUG
@@ -778,4 +791,4 @@ class CircleCaptcha(OCR):
# coords = x.decrypt_from_file("decripter/captx.html2.gif")
# coords = x.decrypt_from_web("http://ncrypt.in/classes/captcha/circlecaptcha.php")
# b = datetime.datetime.now()
-# print 'Elapsed time: ' + str((b-a).seconds) + ' seconds'
+# self.log_debug("Elapsed time: %s seconds" % (b-a).seconds)
diff --git a/module/plugins/captcha/GigasizeCom.py b/module/plugins/captcha/GigasizeCom.py
index 52c41729b..12f123c41 100644
--- a/module/plugins/captcha/GigasizeCom.py
+++ b/module/plugins/captcha/GigasizeCom.py
@@ -1,23 +1,20 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class GigasizeCom(OCR):
__name__ = "GigasizeCom"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Gigasize.com ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.threshold(2.8)
self.run_tesser(True, False, False, True)
diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/captcha/LinksaveIn.py
index 95b107977..4d2e2bc34 100644
--- a/module/plugins/captcha/LinksaveIn.py
+++ b/module/plugins/captcha/LinksaveIn.py
@@ -2,27 +2,28 @@
try:
from PIL import Image
+
except ImportError:
import Image
import glob
import os
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class LinksaveIn(OCR):
__name__ = "LinksaveIn"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Linksave.in ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
+ def init(self):
self.data_dir = os.path.dirname(os.path.abspath(__file__)) + os.sep + "LinksaveIn" + os.sep
@@ -31,7 +32,7 @@ class LinksaveIn(OCR):
frame_nr = 0
lut = im.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
new = Image.new("RGB", im.size)
@@ -51,7 +52,7 @@ class LinksaveIn(OCR):
new.save(self.data_dir+"unblacked.png")
self.image = new.copy()
self.pixels = self.image.load()
- self.result_captcha = ''
+ self.result_captcha = ""
def get_bg(self):
@@ -63,11 +64,11 @@ class LinksaveIn(OCR):
bg = Image.open(bgpath)
bglut = bg.resize((256, 1))
- bglut.putdata(range(256))
+ bglut.putdata(xrange(256))
bglut = list(bglut.convert("RGB").getdata())
lut = img.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
bgpix = bg.load()
@@ -80,11 +81,11 @@ class LinksaveIn(OCR):
cstat[rgb_c] += 1
except Exception:
cstat[rgb_c] = 1
- if rgb_bg == rgb_c:
+ if rgb_bg is rgb_c:
stat[bgpath] += 1
max_p = 0
bg = ""
- for bgpath, value in stat.iteritems():
+ for bgpath, value in stat.items():
if max_p < value:
bg = bgpath
max_p = value
@@ -96,11 +97,11 @@ class LinksaveIn(OCR):
img = self.image.convert("P")
bglut = bg.resize((256, 1))
- bglut.putdata(range(256))
+ bglut.putdata(xrange(256))
bglut = list(bglut.convert("RGB").getdata())
lut = img.resize((256, 1))
- lut.putdata(range(256))
+ lut.putdata(xrange(256))
lut = list(lut.convert("RGB").getdata())
bgpix = bg.load()
@@ -110,7 +111,7 @@ class LinksaveIn(OCR):
for y in xrange(bg.size[1]):
rgb_bg = bglut[bgpix[x, y]]
rgb_c = lut[pix[x, y]]
- if rgb_c == rgb_bg:
+ if rgb_c is rgb_bg:
orgpix[x, y] = (255, 255, 255)
@@ -136,7 +137,7 @@ class LinksaveIn(OCR):
self.pixels = self.image.load()
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
bg = self.get_bg()
self.substract_bg(bg)
diff --git a/module/plugins/captcha/NetloadIn.py b/module/plugins/captcha/NetloadIn.py
index 1fb258c47..50174684d 100644
--- a/module/plugins/captcha/NetloadIn.py
+++ b/module/plugins/captcha/NetloadIn.py
@@ -1,23 +1,20 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class NetloadIn(OCR):
__name__ = "NetloadIn"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Netload.in ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("pyLoad Team", "admin@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.to_greyscale()
self.clean(3)
diff --git a/module/plugins/captcha/OCR.py b/module/plugins/captcha/OCR.py
deleted file mode 100644
index 1874ba07d..000000000
--- a/module/plugins/captcha/OCR.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from __future__ import with_statement
-
-try:
- from PIL import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin
-
-except ImportError:
- import Image, GifImagePlugin, JpegImagePlugin, PngImagePlugin, TiffImagePlugin
-
-import logging
-import os
-import subprocess
-#import tempfile
-
-from module.utils import save_join
-
-
-class OCR(object):
- __name__ = "OCR"
- __type__ = "ocr"
- __version__ = "0.11"
-
- __description__ = """OCR base plugin"""
- __license__ = "GPLv3"
- __authors__ = [("pyLoad Team", "admin@pyload.org")]
-
-
- def __init__(self):
- self.logger = logging.getLogger("log")
-
-
- def load_image(self, image):
- self.image = Image.open(image)
- self.pixels = self.image.load()
- self.result_captcha = ''
-
-
- def unload(self):
- """delete all tmp images"""
- pass
-
-
- def threshold(self, value):
- self.image = self.image.point(lambda a: a * value + 10)
-
-
- def run(self, command):
- """Run a command"""
-
- popen = subprocess.Popen(command, bufsize = -1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- popen.wait()
- output = popen.stdout.read() +" | "+ popen.stderr.read()
- popen.stdout.close()
- popen.stderr.close()
- self.logger.debug("Tesseract ReturnCode %s Output: %s" % (popen.returncode, output))
-
-
- def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True):
- #tmpTif = tempfile.NamedTemporaryFile(suffix=".tif")
- try:
- tmpTif = open(save_join("tmp", "tmpTif_%s.tif" % self.__name__), "wb")
- tmpTif.close()
-
- #tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt")
- tmpTxt = open(save_join("tmp", "tmpTxt_%s.txt" % self.__name__), "wb")
- tmpTxt.close()
-
- except IOError, e:
- self.logError(e)
- return
-
- self.logger.debug("save tiff")
- self.image.save(tmpTif.name, 'TIFF')
-
- if os.name == "nt":
- tessparams = [os.path.join(pypath, "tesseract", "tesseract.exe")]
- else:
- tessparams = ["tesseract"]
-
- tessparams.extend( [os.path.abspath(tmpTif.name), os.path.abspath(tmpTxt.name).replace(".txt", "")] )
-
- if subset and (digits or lowercase or uppercase):
- #tmpSub = tempfile.NamedTemporaryFile(suffix=".subset")
- with open(save_join("tmp", "tmpSub_%s.subset" % self.__name__), "wb") as tmpSub:
- tmpSub.write("tessedit_char_whitelist ")
-
- if digits:
- tmpSub.write("0123456789")
- if lowercase:
- tmpSub.write("abcdefghijklmnopqrstuvwxyz")
- if uppercase:
- tmpSub.write("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
-
- tmpSub.write("\n")
- tessparams.append("nobatch")
- tessparams.append(os.path.abspath(tmpSub.name))
-
- self.logger.debug("run tesseract")
- self.run(tessparams)
- self.logger.debug("read txt")
-
- try:
- with open(tmpTxt.name, 'r') as f:
- self.result_captcha = f.read().replace("\n", "")
- except Exception:
- self.result_captcha = ""
-
- self.logger.debug(self.result_captcha)
- try:
- os.remove(tmpTif.name)
- os.remove(tmpTxt.name)
- if subset and (digits or lowercase or uppercase):
- os.remove(tmpSub.name)
- except Exception:
- pass
-
-
- def get_captcha(self, name):
- raise NotImplementedError
-
-
- def to_greyscale(self):
- if self.image.mode != 'L':
- self.image = self.image.convert('L')
-
- self.pixels = self.image.load()
-
-
- def eval_black_white(self, limit):
- self.pixels = self.image.load()
- w, h = self.image.size
- for x in xrange(w):
- for y in xrange(h):
- if self.pixels[x, y] > limit:
- self.pixels[x, y] = 255
- else:
- self.pixels[x, y] = 0
-
-
- def clean(self, allowed):
- pixels = self.pixels
-
- w, h = self.image.size
-
- for x in xrange(w):
- for y in xrange(h):
- if pixels[x, y] == 255:
- continue
- # No point in processing white pixels since we only want to remove black pixel
- count = 0
-
- try:
- if pixels[x-1, y-1] != 255:
- count += 1
- if pixels[x-1, y] != 255:
- count += 1
- if pixels[x-1, y + 1] != 255:
- count += 1
- if pixels[x, y + 1] != 255:
- count += 1
- if pixels[x + 1, y + 1] != 255:
- count += 1
- if pixels[x + 1, y] != 255:
- count += 1
- if pixels[x + 1, y-1] != 255:
- count += 1
- if pixels[x, y-1] != 255:
- count += 1
- except Exception:
- pass
-
- # not enough neighbors are dark pixels so mark this pixel
- # to be changed to white
- if count < allowed:
- pixels[x, y] = 1
-
- # second pass: this time set all 1's to 255 (white)
- for x in xrange(w):
- for y in xrange(h):
- if pixels[x, y] == 1:
- pixels[x, y] = 255
-
- self.pixels = pixels
-
-
- def derotate_by_average(self):
- """rotate by checking each angle and guess most suitable"""
-
- w, h = self.image.size
- pixels = self.pixels
-
- for x in xrange(w):
- for y in xrange(h):
- if pixels[x, y] == 0:
- pixels[x, y] = 155
-
- highest = {}
- counts = {}
-
- for angle in xrange(-45, 45):
-
- tmpimage = self.image.rotate(angle)
-
- pixels = tmpimage.load()
-
- w, h = self.image.size
-
- for x in xrange(w):
- for y in xrange(h):
- if pixels[x, y] == 0:
- pixels[x, y] = 255
-
-
- count = {}
-
- for x in xrange(w):
- count[x] = 0
- for y in xrange(h):
- if pixels[x, y] == 155:
- count[x] += 1
-
- sum = 0
- cnt = 0
-
- for x in count.values():
- if x != 0:
- sum += x
- cnt += 1
-
- avg = sum / cnt
- counts[angle] = cnt
- highest[angle] = 0
- for x in count.values():
- if x > highest[angle]:
- highest[angle] = x
-
- highest[angle] = highest[angle] - avg
-
- hkey = 0
- hvalue = 0
-
- for key, value in highest.iteritems():
- if value > hvalue:
- hkey = key
- hvalue = value
-
- self.image = self.image.rotate(hkey)
- pixels = self.image.load()
-
- for x in xrange(w):
- for y in xrange(h):
- if pixels[x, y] == 0:
- pixels[x, y] = 255
-
- if pixels[x, y] == 155:
- pixels[x, y] = 0
-
- self.pixels = pixels
-
-
- def split_captcha_letters(self):
- captcha = self.image
- started = False
- letters = []
- width, height = captcha.size
- bottomY, topY = 0, height
- pixels = captcha.load()
-
- for x in xrange(width):
- black_pixel_in_col = False
- for y in xrange(height):
- if pixels[x, y] != 255:
- if not started:
- started = True
- firstX = x
- lastX = x
-
- if y > bottomY:
- bottomY = y
- if y < topY:
- topY = y
- if x > lastX:
- lastX = x
-
- black_pixel_in_col = True
-
- if black_pixel_in_col is False and started is True:
- rect = (firstX, topY, lastX, bottomY)
- new_captcha = captcha.crop(rect)
-
- w, h = new_captcha.size
- if w > 5 and h > 5:
- letters.append(new_captcha)
-
- started = False
- bottomY, topY = 0, height
-
- return letters
-
-
- def correct(self, values, var=None):
- if var:
- result = var
- else:
- result = self.result_captcha
-
- for key, item in values.iteritems():
-
- if key.__class__ == str:
- result = result.replace(key, item)
- else:
- for expr in key:
- result = result.replace(expr, item)
-
- if var:
- return result
- else:
- self.result_captcha = result
diff --git a/module/plugins/captcha/ReCaptcha.py b/module/plugins/captcha/ReCaptcha.py
new file mode 100644
index 000000000..5931159c5
--- /dev/null
+++ b/module/plugins/captcha/ReCaptcha.py
@@ -0,0 +1,197 @@
+# -*- coding: utf-8 -*-
+
+import random
+import re
+import time
+import urlparse
+
+from base64 import b64encode
+
+from module.plugins.internal.CaptchaService import CaptchaService
+
+
+class ReCaptcha(CaptchaService):
+ __name__ = "ReCaptcha"
+ __type__ = "captcha"
+ __version__ = "0.18"
+ __status__ = "testing"
+
+ __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_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)'
+ KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'
+
+
+ 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:
+ self.key = m.group(1).strip()
+ self.log_debug("Key: %s" % self.key)
+ return self.key
+ else:
+ self.log_warning(_("Key pattern not found"))
+ return None
+
+
+ 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, data or self.retrieve_data()) else 1)
+
+
+ def _challenge_v1(self, key):
+ html = self.plugin.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:
+ self.fail(_("ReCaptcha challenge pattern not found"))
+
+ self.log_debug("Challenge: %s" % challenge)
+
+ return self.result(server, challenge, key)
+
+
+ def result(self, server, challenge, key):
+ self.plugin.load("http://www.google.com/recaptcha/api/js/recaptcha.js")
+ html = self.plugin.load("http://www.google.com/recaptcha/api/reload",
+ get={'c' : challenge,
+ 'k' : key,
+ 'reason': "i",
+ 'type' : "image"})
+
+ try:
+ challenge = re.search('\(\'(.+?)\',',html).group(1)
+
+ except AttributeError:
+ self.fail(_("ReCaptcha second challenge pattern not found"))
+
+ self.log_debug("Second challenge: %s" % challenge)
+ result = self.decrypt(urlparse.urljoin(server, "image"),
+ get={'c': challenge},
+ cookies=True,
+ input_type="jpg")
+
+ self.log_debug("Result: %s" % result)
+
+ return result, challenge
+
+
+ def _collect_api_info(self):
+ html = self.plugin.load("http://www.google.com/recaptcha/api.js")
+ a = re.search(r'po.src = \'(.*?)\';', html).group(1)
+ vers = a.split("/")[5]
+
+ self.log_debug("API version: %s" % vers)
+
+ language = a.split("__")[1].split(".")[0]
+
+ self.log_debug("API language: %s" % language)
+
+ html = self.plugin.load("https://apis.google.com/js/api.js")
+ b = re.search(r'"h":"(.*?)","', html).group(1)
+ jsh = b.decode('unicode-escape')
+
+ self.log_debug("API jsh-string: %s" % jsh)
+
+ return vers, language, jsh
+
+
+ def _prepare_time_and_rpc(self):
+ self.plugin.load("http://www.google.com/recaptcha/api2/demo")
+
+ millis = int(round(time.time() * 1000))
+
+ self.log_debug("Time: %s" % millis)
+
+ rand = random.randint(1, 99999999)
+ a = "0.%s" % str(rand * 2147483647)
+ rpc = int(100000000 * float(a))
+
+ self.log_debug("Rpc-token: %s" % rpc)
+
+ return millis, rpc
+
+
+ def _challenge_v2(self, key, parent=None):
+ if parent is None:
+ try:
+ parent = urlparse.urljoin("http://", urlparse.urlparse(self.plugin.pyfile.url).netloc)
+
+ except Exception:
+ parent = ""
+
+ botguardstring = "!A"
+ vers, language, jsh = self._collect_api_info()
+ millis, rpc = self._prepare_time_and_rpc()
+
+ html = self.plugin.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.log_debug("Token #1: %s" % token1.group(1))
+
+ html = self.plugin.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.log_debug("Token #2: %s" % token2.group(1))
+
+ token3 = re.search(r'"rresp","(.*?)",', html)
+ self.log_debug("Token #3: %s" % token3.group(1))
+
+ millis_captcha_loading = int(round(time.time() * 1000))
+ captcha_response = self.decrypt("https://www.google.com/recaptcha/api2/payload",
+ get={'c':token3.group(1), 'k':key},
+ cookies=True,
+ ocr=False,
+ timeout=30)
+ response = b64encode('{"response":"%s"}' % captcha_response)
+
+ self.log_debug("Result: %s" % response)
+
+ timeToSolve = int(round(time.time() * 1000)) - millis_captcha_loading
+ timeToSolveMore = timeToSolve + int(float("0." + str(random.randint(1, 99999999))) * 500)
+
+ html = self.plugin.load("https://www.google.com/recaptcha/api2/userverify",
+ post={'k' : key,
+ 'c' : token3.group(1),
+ 'response': response,
+ 't' : timeToSolve,
+ 'ct' : timeToSolveMore,
+ 'bg' : botguardstring})
+
+ token4 = re.search(r'"uvresp","(.*?)",', html)
+ self.log_debug("Token #4: %s" % token4.group(1))
+
+ result = token4.group(1)
+
+ return result, None
diff --git a/module/plugins/captcha/ShareonlineBiz.py b/module/plugins/captcha/ShareonlineBiz.py
index 6fad66600..edf14df87 100644
--- a/module/plugins/captcha/ShareonlineBiz.py
+++ b/module/plugins/captcha/ShareonlineBiz.py
@@ -1,30 +1,27 @@
# -*- coding: utf-8 -*-
-from module.plugins.captcha.OCR import OCR
+from module.plugins.internal.OCR import OCR
class ShareonlineBiz(OCR):
__name__ = "ShareonlineBiz"
__type__ = "ocr"
- __version__ = "0.11"
+ __version__ = "0.14"
+ __status__ = "testing"
__description__ = """Shareonline.biz ocr plugin"""
__license__ = "GPLv3"
__authors__ = [("RaNaN", "RaNaN@pyload.org")]
- def __init__(self):
- OCR.__init__(self)
-
-
- def get_captcha(self, image):
+ def recognize(self, image):
self.load_image(image)
self.to_greyscale()
self.image = self.image.resize((160, 50))
self.pixels = self.image.load()
self.threshold(1.85)
- #self.eval_black_white(240)
- #self.derotate_by_average()
+ # self.eval_black_white(240)
+ # self.derotate_by_average()
letters = self.split_captcha_letters()
@@ -36,4 +33,4 @@ class ShareonlineBiz(OCR):
return final
- #tesseract at 60%
+ #: Tesseract at 60%
diff --git a/module/plugins/captcha/SolveMedia.py b/module/plugins/captcha/SolveMedia.py
new file mode 100644
index 000000000..870b5fc10
--- /dev/null
+++ b/module/plugins/captcha/SolveMedia.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.internal.Plugin import Fail
+from module.plugins.internal.CaptchaService import CaptchaService
+
+
+class SolveMedia(CaptchaService):
+ __name__ = "SolveMedia"
+ __type__ = "captcha"
+ __version__ = "0.15"
+ __status__ = "testing"
+
+ __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, data=None):
+ html = data or self.retrieve_data()
+
+ m = re.search(self.KEY_PATTERN, html)
+ if m:
+ self.key = m.group(1).strip()
+ self.log_debug("Key: %s" % self.key)
+ return self.key
+ else:
+ self.log_warning(_("Key pattern not found"))
+ return None
+
+
+ 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})
+
+ for i in xrange(1, 11):
+ try:
+ magic = re.search(r'name="magic" value="(.+?)"', html).group(1)
+
+ except AttributeError:
+ self.log_warning(_("Magic pattern not found"))
+ magic = None
+
+ try:
+ challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="(.+?)">',
+ html).group(1)
+
+ except AttributeError:
+ self.fail(_("SolveMedia challenge pattern not found"))
+
+ else:
+ self.log_debug("Challenge: %s" % challenge)
+
+ try:
+ result = self.result("http://api.solvemedia.com/papi/media", challenge)
+
+ except Fail, e:
+ self.log_warning(e)
+ self.plugin.invalidCaptcha()
+ result = None
+
+ html = self.plugin.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' : self.plugin.pyfile.url})
+ try:
+ redirect = re.search(r'URL=(.+?)">', html).group(1)
+
+ except AttributeError:
+ self.fail(_("SolveMedia verify pattern not found"))
+
+ else:
+ if "error" in html:
+ self.log_warning(_("Captcha code was invalid"))
+ self.log_debug("Retry #%d" % i)
+ html = self.plugin.load(redirect)
+ else:
+ break
+
+ else:
+ self.fail(_("SolveMedia max retries exceeded"))
+
+ return result, challenge
+
+
+ def result(self, server, challenge):
+ result = self.decrypt(server,
+ get={'c': challenge},
+ cookies=True,
+ input_type="gif")
+
+ self.log_debug("Result: %s" % result)
+
+ return result