Permalink
Browse files

First import of the tw2.captcha plugin

  • Loading branch information...
1 parent 57146fe commit 725c7fa5deb49d6709bae04acc3a59ab9e217d27 @pypingou pypingou committed Mar 1, 2012
View
@@ -0,0 +1,3 @@
+include README.rst
+recursive-include tw2/captcha/templates *
+recursive-include tw2/captcha/static *
View
@@ -0,0 +1,61 @@
+from setuptools import setup, find_packages
+
+f = open('README.rst')
+long_description = f.read().strip()
+long_description = long_description.split('split here', 1)[1]
+f.close()
+
+install_requires=[
+ "tw2.core",
+]
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] < 7:
+ install_requires.extend([
+ "ordereddict",
+ ])
+
+setup(
+ name='tw2.captcha',
+ version='0.0.1',
+ description='toscawidgets2 captcha plugin',
+ long_description=long_description,
+ author='Pierre-Yves Chibon',
+ author_email='pingou@pingoured.fr',
+ url='http://github.com/pypingou/tw2.captcha',
+ install_requires=[
+ "tw2.core",
+ "pycrypto",
+ "PIL",
+ ],
+ packages=find_packages(exclude=['ez_setup']),
+ namespace_packages = ['tw2'],
+ zip_safe=False,
+ include_package_data=True,
+ entry_points="""
+ [tw2.widgets]
+ # Register your widgets so they can be listed in the WidgetBrowser
+ tw2.captcha = tw2.captcha
+ [tw2.captcha.jpeg_generators]
+ mcdermott = tw2.captcha.plugins.image.mcdermott:generate_jpeg
+ vanasco_dowty = tw2.captcha.plugins.image.vanasco_dowty:generate_jpeg
+ fred = tw2.captcha.plugins.image.fred:generate_jpeg
+ [tw2.captcha.text_generators]
+ random_ascii = tw2.captcha.plugins.text.random_ascii:generate_text
+ random_equation = tw2.captcha.plugins.text.random_equation:generate_text
+ fivelettername = tw2.captcha.plugins.text.fivelettername:generate_text
+ """,
+ keywords = [
+ 'toscawidgets.widgets',
+ ],
+ classifiers = [
+ 'Development Status :: 3 - Alpha',
+ 'Environment :: Web Environment',
+ 'Environment :: Web Environment :: ToscaWidgets',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Topic :: Software Development :: Widget Sets',
+ 'Intended Audience :: Developers',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ ],
+)
View
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
@@ -0,0 +1,4 @@
+dev/
+*.pyc
+*~
+
@@ -0,0 +1,9 @@
+"""
+A captcha w2 widgets.
+
+Get this source from http://github.com/pypingou/tw2.captcha
+"""
+
+from widgets import (
+ Captcha,
+)
View
@@ -0,0 +1,61 @@
+from datetime import datetime
+import calendar
+import cPickle
+
+
+class Captcha(object):
+ """Pertinent data about a Captcha.
+
+ Exposed properties are:
+ plaintext: (read/write) a string representing the text of the captcha
+ (i.e. what is it supposed to say)
+ created: (read only) the UTC date when the captcha was created. This
+ data is updated when the plaintext property is updated.
+
+ Exposed methods:
+ serialize(): returns a binary representation of the object
+ deseralize(obj): creates a Captcha object given the output of the
+ serialize() method. This is a classmethod.
+ """
+
+ _plaintext = None
+ _created = None # stored as UTC
+
+ def __init__(self, plaintext=''):
+ super(Captcha, self).__init__()
+ self.plaintext = plaintext
+ self.label = None
+
+ def get_plaintext(self):
+ return self._plaintext
+
+ def set_plaintext(self, text):
+ self._plaintext = text
+ self._created = datetime.utcnow()
+
+ plaintext = property(get_plaintext, set_plaintext)
+ # def get_created(self):
+ # return self._created
+
+ c = lambda s: s._created
+
+ created = property(lambda s: s._created)
+
+ def serialize(self):
+ """Get a serialized binary representation of the object."""
+ # Serializing to a tuple containing the data elements instead of
+ # just pickling the object is being done because the tuple
+ # pickle is much smaller than the pickled object itself.
+ secs = int(calendar.timegm(self.created.utctimetuple()))
+ t = (self.plaintext, secs, self.label)
+ return cPickle.dumps(t, cPickle.HIGHEST_PROTOCOL)
+
+ def deserialize(cls, serialized_obj):
+ "Create a new Captcha object given output from the serialize method."
+ t = cPickle.loads(serialized_obj)
+ scp = cls()
+ scp._plaintext = t[0]
+ scp._created = datetime.utcfromtimestamp(t[1])
+ scp.label = t[2]
+ return scp
+ deserialize = classmethod(deserialize)
No changes.
No changes.
@@ -0,0 +1,67 @@
+import Image, ImageDraw, ImageFont, ImageFilter
+import random
+import os
+
+from pkg_resources import resource_filename
+from tw2.captcha.widgets import Captcha
+
+# get the font path
+font_path = Captcha.text_font_path
+assert os.path.exists(font_path), \
+ 'The font_path "%s" does not exist' % (font_path,)
+
+font_size = Captcha.text_font_size_min
+
+def generate_jpeg(text, file_obj):
+ # Settings ----------------------------------------------------
+ rand = random.randint
+ charNum = len(text)
+ charimg_w = font_size + 8
+ charimg_h = font_size + 8
+ img_w = (font_size * charNum) + 8
+ img_h = int(charimg_h * 1.5)
+ interval = font_size
+ lineNum = rand(5, 15)
+ font = ImageFont.truetype(font_path, font_size)
+
+ # Create a background -----------------------------------------
+ bg_color = rand(0xbb, 0xee)
+ image = Image.new('RGB', (img_w, img_h), (bg_color, bg_color, bg_color))
+
+ # Generate text -----------------------------------------------
+ for i in range(0, charNum):
+ color = rand(0x111111, 0x444444)
+ # Create a small image to hold one character. Background is black
+ charImg = Image.new('RGB', (charimg_w, charimg_h), 0)
+ tmpDraw = ImageDraw.Draw(charImg)
+ # Draw text on this image
+ tmpDraw.text((3, 1), text[i], font=font, fill=color)
+ # Rotate a little bit, do some trick if you want
+ charImg = charImg.rotate(rand(-20,20))
+
+ # Create a mask which is same size of the small image
+ mask = Image.new('L', (charimg_w, charimg_h), 0)
+ mask.paste(charImg, (0, 0))
+
+ # Generate Random X Y
+ hpos = 8 + (i * interval) + rand(-8, 5)
+ vpos = rand(5, 15)
+
+ image.paste(charImg, (hpos, vpos), mask)
+ image.paste(charImg, (hpos+1, vpos+1), mask)
+
+ image = image.filter(ImageFilter.SHARPEN)
+
+ # Draw few lines -----------------------------------------
+ draw = ImageDraw.Draw(image)
+ for i in range(0, lineNum):
+ draw.line((rand(1, img_w), rand(1, img_h),
+ rand(1, img_w), rand(1, img_h)),
+ fill=rand(0x666666, 0x999999)
+ )
+
+ image.save(file_obj, format='JPEG')
+
+if __name__ == "__main__":
+ generate_jpeg('hello', '/tmp/foo.jpg')
+ print "Captcha image generated."
@@ -0,0 +1,44 @@
+import random
+import Image
+import ImageFont
+import ImageDraw
+import ImageFilter
+from pkg_resources import resource_filename
+import os.path
+from tw2.captcha.widgets import Captcha
+
+# get the font path
+font_path = Captcha.text_font_path
+assert os.path.exists(font_path), \
+ 'The font_path "%s" does not exist' % (font_path,)
+
+text_font_size_min = Captcha.text_font_size_min
+bgcolor = Captcha.picture_bg_color
+fgcolor = Captcha.picture_fg_color
+# Code taken from
+# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440588
+# written by Robert McDermott
+
+def generate_jpeg(text, file_obj):
+ """Generate a captcha image"""
+ # randomly select the foreground color
+ fgcolor = random.randint(0,0xffff00)
+ # make the background color the opposite of fgcolor
+ bgcolor = fgcolor ^ 0xffffff
+ # create a font object
+ font = ImageFont.truetype(font_path, text_font_size_min)
+ # determine dimensions of the text
+ dim = font.getsize(text)
+ # create a new image slightly larger that the text
+ im = Image.new('RGB', (dim[0]+5,dim[1]+5), bgcolor)
+ d = ImageDraw.Draw(im)
+ x, y = im.size
+ r = random.randint
+ # draw 100 random colored boxes on the background
+ for num in range(100):
+ d.rectangle((r(0,x),r(0,y),r(0,x),r(0,y)),fill=r(0, bgcolor ^ 0xffffff))
+ # add the text to the image
+ d.text((3,3), text, font=font, fill=fgcolor)
+ im = im.filter(ImageFilter.EDGE_ENHANCE_MORE)
+ # save the image to a file
+ im.save(file_obj, format='JPEG')
@@ -0,0 +1,24 @@
+import captcha
+import random
+import os.path
+from pkg_resources import resource_filename
+from tw2.captcha.widgets import Captcha
+
+width = Captcha.picture_width
+height = Captcha.picture_height
+bg_color = Captcha.picture_bg_color
+fg_color = Captcha.picture_fg_color
+font_size_min = Captcha.text_font_size_min
+font_size_max = Captcha.text_font_size_max
+
+captcha.font__paths = [Captcha.text_font_path]
+captcha.captcha__text__render_mode = Captcha.text_render_mode
+captcha.captcha__font_range = (font_size_min, font_size_max)
+
+
+def generate_jpeg(text, file_):
+ font_size = random.randint(font_size_min, font_size_max)
+ fg = random.choice(fg_color)
+ ci = captcha._Captcha__Img(text, width, height, font_size, fg, bg_color)
+ image = ci.render()
+ image.save(file_, format='JPEG')
Oops, something went wrong.

0 comments on commit 725c7fa

Please sign in to comment.