source: CMESS/captcha/trunk/com/zms/captcha/PILCaptcha.py @ 362

Revision 362, 3.9 KB checked in by mike, 3 years ago (diff)
  • added ReCaptcha?-service
  • added PILCaptcha-service
Line 
1###################################################################################
2# Externe Methode "captcha.py"
3
4# Python imports
5import os
6import random
7import sys
8import time
9import whrandom
10from cStringIO import StringIO
11from string import ascii_uppercase, ascii_lowercase, digits
12
13# Zope imports
14from DateTime import DateTime
15import OFS
16
17# PIL Imports
18from PIL import Image, ImageFont, ImageDraw, ImageFilter, ImageOps
19
20# parameters
21chars = ascii_uppercase + ascii_lowercase + digits
22_xstep = 5
23_ystep = 5
24_imageSize = (201,61)
25_bgColor = (255,255,255) # White
26_gridInk = (200,200,200)
27_fontInk = (100,100,100)
28_fontSize = 24
29# set in cb_start callback
30_fontPath = sys.path[0] + "/com/zms/captcha/Gastada.ttf"
31
32def getRandomId():
33   """ create unique ID with timestamp + 4 random chars
34   """
35   ts = str(time.time())
36   for i in range(4):
37     ts += whrandom.choice(chars)
38   return ts
39
40def generateImage(folder_path, char_count = 5, font_size = 24, REQUEST=None):
41     """ create random image with grey on grey
42     """
43
44     zfolder            = folder_path
45     _fontSize  = font_size
46
47     # create random chars for the image
48     txt = ''
49     for i in range(char_count):
50         txt += whrandom.choice(ascii_uppercase)
51
52     # set txt to session
53     if REQUEST:
54       REQUEST.SESSION['sess_captcha'] = txt
55
56     try:
57         # recent PIL version with support for truetype fonts
58         font = ImageFont.truetype(_fontPath, _fontSize)
59     except IOError:
60         font = ImageFont.load_default()
61     except AttributeError:
62         # old PIL version, fallback to pil fonts
63         font = ImageFont.load(_fontPath)
64
65     img = Image.new("RGB", _imageSize, _bgColor)
66     draw = ImageDraw.Draw(img)
67
68     xsize, ysize = img.size
69
70     # Do we want the grid start at 0,0 or want some offset?
71     x, y = 0,0
72
73     while x <= xsize:
74         try:
75             # recent PIL version
76             draw.line(((x, 0), (x, ysize)), fill=_gridInk)
77         except TypeError:
78             # old PIL version
79             draw.setink(_gridInk)
80             draw.line(((x, 0), (x, ysize)))
81         x = x + _xstep
82     while y <= ysize:
83         try:
84             draw.line(((0, y), (xsize, y)), fill=_gridInk)
85         except TypeError:
86             draw.setink(_gridInk)
87             draw.line(((0, y), (xsize, y)))
88         y = y + _ystep
89
90     try:
91         draw.text((10, 4), txt, font=font, fill=_fontInk)
92     except TypeError:
93         draw.setink(_fontInk)
94         draw.text((10, 4), txt, font=font)
95
96
97     file_name = 'testpic.jpg'
98     fmt='JPEG'
99
100     imgData = StringIO()
101     img.save(imgData, fmt)
102     binarydata = imgData.getvalue()
103     size = len(binarydata)
104     # add Zope Image to ZODB;  taken from OFS/Image.py
105     id = getRandomId()
106     title = ''
107     if REQUEST is not None:
108       title = REQUEST.get('REMOTE_ADDR', '') + ' - ' + REQUEST.get('HTTP_USER_AGENT', '')
109     content_type = 'image/jpeg'
110
111     # First, we create the image without data
112     #zfolder = getattr(self, _ZOPEFOLDERPATH)
113     zfolder._setObject(id, OFS.Image.Image(id, title, '', content_type, ''))
114
115     # Now we "upload" the data.  By doing this in two steps, we
116     # can use a database trick to make the upload more efficient.
117     zope_img = zfolder._getOb(id)
118     zope_img.update_data(binarydata, content_type, size)
119     #zfolder.manage_addFile(id=id, title=file_name, file=binarydata)
120
121     # delete old images
122     img_ids_to_delete = []
123     for i in zfolder.objectValues(['Image']):
124         mod_datetime = DateTime(i.bobobase_modification_time())
125         if int((DateTime() - mod_datetime) * 3600) > 200:
126           # longer than 200 minutes
127           img_ids_to_delete.append(i.getId())
128     zfolder.manage_delObjects(img_ids_to_delete)
129
130     return zope_img
131
132# / Externe Methode "captcha.py"
133###################################################################################
Note: See TracBrowser for help on using the repository browser.