source: products/quintagroup.captcha.core/trunk/quintagroup/captcha/core/utils.py @ 3097

Last change on this file since 3097 was 3097, checked in by vmaksymiv, 13 years ago

fixed PIL imports

File size: 4.8 KB
RevLine 
[797]1import os
2import re
3import math
[2180]4try:
5    import hashlib as md5
6except ImportError:
7    import md5
[797]8from string import atoi
9from random import randint
10
11from DateTime import DateTime
12
[1954]13from quintagroup.captcha.core.data import basic_english
14from quintagroup.captcha.core.config import *
[797]15
16try:
17    import Crypto.Cipher.DES as Crypto
18except:
19    import Crypto
20
[1874]21def encrypt1(s):
[2180]22    return md5.md5(s).hexdigest().upper()
[1874]23
[797]24def getTransform(x, y, a, p, o):
25    return (math.sin( (y+o[0])*p )*a + x, math.sin( (x+o[1])*p )*a + y)
26
27def gen_captcha(**kwargs):
28    """Generate a captcha image"""
[3097]29    try:
30        from App import ImageFile
31    except ImportError:
32        import ImageFile
33    from PIL import Image
34    from PIL import ImageFont
35    from PIL import ImageDraw
36    from PIL import ImageFilter
[797]37    import random
38    from PIL import ImageFile as pyImageFile
39    import sys
40    sys.modules['ImageFile'] = pyImageFile
41    from cStringIO import StringIO
42
43    text = kwargs.get('text', None)
44    fnt_sz = kwargs.get('size', DEFAULT_IMAGE_SIZE)
45    bkground = kwargs.get('bkground', DEFAULT_BG)
46    font_color = kwargs.get('font_color', DEFAULT_FONT_COLOR)
47    distortion = kwargs.get('distortion', DEFAULT_DISTORTION)
48
49    period = distortion[0]
50    amplitude = distortion[1]
51    offset = distortion[2]
52
53    outFile = StringIO()
54
55    DATA_PATH = os.path.abspath(os.path.dirname(__file__)) + '/data'
56    FONT_PATH = DATA_PATH + '/fonts'
57
58    #select font for captcha text
59    ALL_FONTS=('Bd', 'It', 'MoBI', 'Mono', 'Se', 'BI', 'MoBd', 'MoIt', 'SeBd', '')
60    rand_font = random.choice(ALL_FONTS)
61    font = ImageFont.truetype(FONT_PATH+'/vera/Vera%s.ttf'%rand_font, fnt_sz)
62    textSize = font.getsize(text)
63
64#------------------------------render   background1 -----------------------
65    image = Image.new('RGB', (textSize[0]+7,textSize[1]+7), bkground)
66    image.paste(bkground)
67#------------------------------render       Text2 ------------------------
68    draw = ImageDraw.Draw(image)
69    alignment = (random.uniform(0,1), random.uniform(0,1))
70    x = int((image.size[0] - textSize[0]) * alignment[0] + 0.5)
71    y = int((image.size[1] - textSize[1]) * alignment[1] + 0.5)
72
73    draw.text((x,y), text, font=font, fill=font_color)
74
75#------------------------------render       Distortion -----------------------
76    r = 1
77    xPoints = image.size[0] / r + 2
78    yPoints = image.size[1] / r + 2
79
80    # Create a list of arrays with transformed points
81    xRows = []
82    yRows = []
83    for j in xrange(yPoints):
84        xRow = []
85        yRow = []
86        for i in xrange(xPoints):
87            x, y = getTransform(i*r, j*r, amplitude, period, offset)
88
89            # Clamp the edges so we don't get black undefined areas
90            x = max(0, min(image.size[0]-1, x))
91            y = max(0, min(image.size[1]-1, y))
92
93            xRow.append(x)
94            yRow.append(y)
95        xRows.append(xRow)
96        yRows.append(yRow)
97
98    # Create the mesh list, with a transformation for
99    # each square between points on the grid
100    mesh = []
101    for j in xrange(yPoints-1):
102        for i in xrange(xPoints-1):
103            mesh.append((
104                # Destination rectangle
105                (i*r, j*r,
106                 (i+1)*r, (j+1)*r),
107                # Source quadrilateral
108                (xRows[][], yRows[][],
109                 xRows[j+1][], yRows[j+1][],
110                 xRows[j+1][i+1], yRows[j+1][i+1],
111                 xRows[][i+1], yRows[][i+1]),
112                ))
113
114    img = image.transform(image.size, Image.MESH, mesh, Image.BILINEAR)
115
116    # save the image to a file
117    img.save(outFile, format='jpeg')
118    outFile.seek(0)
119    src = outFile.read()
120    size = len(src)
121    sys.modules['ImageFile'] = ImageFile
122    return {'src':src, 'size':size}
123
124
125def getWord(index):
126    words = basic_english.words.split()
127    return words[index]
128
129def getIndex(word):
130    words = basic_english.words.split()
131    try:
132        res = words.index(word)
133    except ValueError:
134        res = getLen()+1
135    return res
136
[853]137def getCaptchasCount(dynamic):
138    if dynamic:
[797]139        return len(basic_english.words.split())
[853]140    else:
141        return CAPTCHAS_COUNT
[797]142
143def formKey(num):
144    def normalize(s):
145        return (not len(s)%8 and s) or normalize(s+str(randint(0, 9)))
146
147    return normalize('%s_%i_'%(str(DateTime().timeTime()), num))
148
149def encrypt(key, s):
150    return toHex(Crypto.new(key).encrypt(s))
151
152def decrypt(key, s):
153    return Crypto.new(key).decrypt(toStr(s))
154
155def parseKey(s):
156    ps = re.match('^(.+?)_(.+?)_', s)
157    if ps is None:
158        return {'date': '', 'key': ''}
159    return {'date': ps.group(1), 'key':ps.group(2)}
160
161def toHex(s):
162    lst = []
163    for ch in s:
164        hv = hex(ord(ch)).replace('0x', '')
165        if len(hv) == 1:
166            hv = '0'+hv
167        lst.append(hv)
168
169    return reduce(lambda x,y:x+y, lst)
170
171def toStr(s):
172    return s and chr(atoi(s[:2], base=16)) + toStr(s[2:]) or ''
Note: See TracBrowser for help on using the repository browser.