source: products/quintagroup.plonecaptchas/trunk/quintagroup/plonecaptchas/utils.py @ 1692

Last change on this file since 1692 was 1692, checked in by liebster, 14 years ago

Fixed imports by Plone4

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