File: Base.py

package info (click to toggle)
pycaptcha 0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,224 kB
  • sloc: python: 699; makefile: 8; sh: 7
file content (69 lines) | stat: -rw-r--r-- 2,235 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
""" Captcha.Visual.BAse

Base classes for visual CAPTCHAs. We use the Python Imaging Library
to manipulate these images.
"""
#
# PyCAPTCHA Package
# Copyright (C) 2004 Micah Dowty <micah@navi.cx>
#

import Captcha
import Image

__all__ = ['ImageCaptcha', 'Layer']


class ImageCaptcha(Captcha.BaseCaptcha):
    """Base class for image-based CAPTCHA tests.
       The render() function generates the CAPTCHA image at the given size by
       combining Layer instances from self.layers, which should be created by
       the subclass-defined getLayers().
       """
    defaultSize = (256,96)

    def __init__(self, *args, **kwargs):
        Captcha.BaseCaptcha.__init__(self)
        self._layers = self.getLayers(*args, **kwargs)

    def getImage(self):
        """Get a PIL image representing this CAPTCHA test, creating it if necessary"""
        if not self._image:
            self._image = self.render()
        return self._image

    def getLayers(self):
        """Subclasses must override this to return a list of Layer instances to render.
           Lists within the list of layers are recursively rendered.
           """
        return []

    def render(self, size=None):
        """Render this CAPTCHA, returning a PIL image"""
        if size is None:
            size = self.defaultSize
        img = Image.new("RGB", size)
        return self._renderList(self._layers, Image.new("RGB", size))

    def _renderList(self, l, img):
        for i in l:
            if type(i) == tuple or type(i) == list:
                img = self._renderList(i, img)
            else:
                img = i.render(img) or img
        return img


class Layer(object):
    """A renderable object representing part of a CAPTCHA.
       The render() function should return approximately the same result, regardless
       of the image size. This means any randomization must occur in the constructor.

       If the render() function returns something non-None, it is taken as an image to
       replace the current image with. This can be used to implement transformations
       that result in a separate image without having to copy the results back to the first.
       """
    def render(self, img):
        pass

### The End ###