root/qPloneCaptchas/tags/1.1.0/utils.py

Revision 784 (checked in by crchemist, 2 years ago)

Added translation of portal_status_message for all plones.

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