index.cgi
changeset 13 a0cb32f3de3d
parent 12 aa6b83c94528
child 14 e30e33081480
--- a/index.cgi	Tue May 05 18:25:16 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-#!/usr/bin/python2.5
-import werkzeug
-from werkzeug.exceptions import HTTPException
-import wsgiref.handlers
-
-from PIL import Image, ImageDraw, ImageFont, ImageEnhance
-from cStringIO import StringIO
-import random, itertools, time
-
-if not hasattr(itertools, 'izip_longest') :
-  
-    def izip_longest(*args, **kwds):
-        # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
-        fillvalue = kwds.get('fillvalue')
-        def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
-            yield counter()         # yields the fillvalue, or raises IndexError
-        fillers = itertools.repeat(fillvalue)
-        iters = [itertools.chain(it, sentinel(), fillers) for it in args]
-        try:
-            for tup in itertools.izip(*iters):
-                yield tup
-        except IndexError:
-            pass
-    
-    itertools.izip_longest = izip_longest 
-    
-class Defaults :
-    # settings
-
-    text_lang = 'en'
-
-    chars = [ u'"', u'!', u'?' ]
-
-    colors = [
-        "#0469af",
-        "#fbc614",
-        "#e1313b",
-    ]
-
-    font_name = 'helvetica'
-    font_size = 30
-    
-    bg_color = "#ffffff"
-    line_spacing = -10
-    sharpness = 0.6
-
-    img_format = 'png'
-
-TEXT_BY_LANG = dict(
-    en = [
-        u"aalto",
-        u"unive",
-        u"rsity"
-    ],
-    fi = [
-        u"aalto",
-        u"yliop",
-        u"isto"
-    ],
-    se = [
-        u"aalto",
-        u"univer",
-        u"sitetet",
-    ],
-)
-
-FONTS = {
-        'dejavu-sans-bold':     "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf",
-        'helvetica':            "HELR65W.TTF",
-    }
-
-IMAGE_FORMATS = {
-    'jpeg': 'jpeg',
-    'jpg':  'jpeg',
-    'png':  'png',
-    'bmp':  'bmp'
-}
-
-FONT_SIZE_MAX = 1024
-
-# enable debugging
-DEBUG = True
-
-
-def randomize (seq) :
-    """
-        Returns the given sequence in random order as a list
-    """
-    
-    # copy
-    l = list(seq)
-    
-    # rearrange
-    random.shuffle(l)
-
-    return l
-
-def randomize_str_char (str) :
-    """
-        Randomize the given string by moving one char around
-    """
-
-    l = list(str)
-
-    c = l.pop(random.randint(0, len(l) - 1))
-    l.insert(random.randint(0, len(l)), c)
-
-    return ''.join(l)
-
-def build_data (text, chars, line_colors, random_chars=True, random_text=False, random_text_char=False) :
-    """
-        Returns a matrix of (text, color) tuples representing the data to render
-
-        [ [ (str, str) ] ]
-
-            text        - list of lines
-            chars       - list of random chars to interpse
-            line_colors - list of colors to draw the chars in
-            random_chars        - randomize the lines the chars go in
-            random_text         - randomize the chars in each line
-            random_text_char    - randomize each line by moving one char around
-    """
-
-    data = []
-
-    if random_chars :
-        chars = randomize(chars)
-    
-    for line, char, color in itertools.izip_longest(text, chars, line_colors, fillvalue=None) :
-        # pick position to place char
-        pos = random.randint(1, len(line) - 1)
-
-        if not color :
-            color = "#000000"
-
-        if random_text :
-            line = ''.join(randomize(line))
-
-        if random_text_char :
-            line = randomize_str_char(line)
-        
-        # split into three parts
-        if char :
-            data.append([
-                    (line[:pos], "#000000"),
-                    (char, color),
-                    (line[pos:], "#000000"),
-                ])
-        else :
-            data.append([
-                    (line, "#000000"),
-                ])
-    
-    return data
-
-def load_font (font_name, font_size) :
-    """
-        Load a font by name
-    """
-    
-    # load font
-    font_path = FONTS[font_name]
-    font = ImageFont.truetype(font_path, font_size)
-    
-    return font
-
-def render_img (data, font, background_color="#ffffff", line_spacing=0) :
-    """
-        Render the data (as from build_data) as an image, using the given PIL.ImageFont, and return the PIL Image object
-    """
-
-    img_width = img_height = 0
-
-    img_data = []
-    
-    # compute image width/height
-    for segments in data :
-        line_width = line_height = 0
-        
-        # build a new list of segments with additional info
-        line_segments = []
-        
-        for seg_text, seg_color in segments :
-            # compute rendered text size
-            seg_width, seg_height = font.getsize(seg_text)
-            
-            # update line_*
-            line_width += seg_width
-            line_height = max(line_height, seg_height)
-            
-            # build the new segments list
-            line_segments.append((seg_text, seg_color, seg_width))
-        
-        # update img_*
-        img_width = max(img_width, line_width)
-        img_height += line_height
-        img_data.append((line_segments, line_height))
-
-    # calculate height needed for line spacing
-    img_height += (len(img_data) - 1) * line_spacing
-
-    # create image
-    img = Image.new("RGB", (img_width, img_height), background_color)
-    draw = ImageDraw.Draw(img)
-
-    # draw text
-    img_y = 0
-    for segments, line_height in img_data :
-        img_x = 0
-        
-        # draw each segment build above, incremeing along img_x
-        for seg_text, seg_color, seg_width in segments :
-            draw.text((img_x, img_y), seg_text, font=font, fill=seg_color)
-
-            img_x += seg_width
-        
-        img_y += line_height + line_spacing
-    
-    return img
-
-def effect_sharpness (img, factor) :
-    """
-        Sharpen the image by the given factor
-    """
-
-    return ImageEnhance.Sharpness(img).enhance(factor)
-
-def build_img (img, format='png') :
-    """
-        Write the given PIL.Image as a string, returning the raw binary data
-
-        Format should be one of the PIL-supported image foarts
-    """
-
-    # render PNG output
-    buf = StringIO()
-    img.save(buf, format)
-    data = buf.getvalue()
-
-    return data
-
-def arg_bool (val) :
-    if val.lower() in ('true', 't', '1', 'yes', 'y') :
-        return True
-    elif val.lower() in ('false', 'f', '0', 'no', 'n') :
-        return False
-    else :
-        raise ValueError(val)
-
-def arg_color (val) :
-    if val.beginswith('#') :
-        int(val[1:], 16)
-
-        return val
-    else :
-        raise ValueError(val)
-
-class Option (object) :
-    def __init__ (self, name, is_list, type, default, range) :
-        self.name = name
-        self.is_list = is_list
-        self.type = type
-        self.default = default
-        self.range = range
-
-    def parse (self, args) :
-        if self.is_list :
-            if self.name in args :
-                return args.getlist(self.name, self.type)
-            else :
-                return self.default
-        else :
-            if self.type == arg_bool and not self.default and self.name in args :
-                return True
-
-            else :
-                return args.get(self.name, self.default, self.type)
-
-class Options (object) :
-    def __init__ (self, *options) :
-        self.options = options
-
-    def parse (self, args) :
-        return dict((opt.name, opt.parse(args)) for opt in self.options)
-
-OPTIONS = Options(
-    Option('lang',          False,  str,        Defaults.text_lang,     TEXT_BY_LANG.keys()),
-    Option('text',          True,   unicode,    None,                   None),
-    Option('random-text',   False,  arg_bool,   False,                  None),
-    Option('random-text-char', False, arg_bool, False,                  None),
-    Option('chars',         True,   unicode,    Defaults.chars,         None),
-    Option('random-chars',  False,  arg_bool,   True,                   None),
-    Option('colors',        True,   arg_color,  Defaults.colors,        None),
-    Option('font',          False,  str,        Defaults.font_name,     FONTS.keys()),
-    Option('font-size',     False,  int,        Defaults.font_size,     None),
-    Option('bg-color',      False,  arg_color,  Defaults.bg_color,      None),
-    Option('line-spacing',  False,  int,        Defaults.line_spacing,  None),
-    Option('sharpness',     False,  float,      Defaults.sharpness,     None),
-    Option('image-format',  False,  str,        Defaults.img_format,    IMAGE_FORMATS.keys()),
-    Option('seed',          False,  int,        None,                   None),
-)
-
-def handle_help (req) :
-    return werkzeug.Response('\n'.join(
-        "%-15s %4s  %-10s %-20s %s" % data for data in [
-            ("name", "", "type", "default", "range"),
-            ("", "", "", "", ""),
-        ] + [(
-            opt.name, 
-            'list' if opt.is_list else 'item', 
-            opt.type.__name__, 
-            repr(opt.default), 
-            opt.range if opt.range else ""
-        ) for opt in OPTIONS.options]
-    ), mimetype='text/plain')
-
-def handle_request (req) :
-    if 'help' in req.args :
-        return handle_help(req)
-
-    # parse options
-    opts = OPTIONS.parse(req.args)
-
-    # postprocess
-    if opts['text'] is None :
-        opts['text'] = TEXT_BY_LANG[opts['lang']]
-
-    if opts['font-size'] > FONT_SIZE_MAX :
-        raise ValueError(opts['font-size'])
-    
-    if opts['seed'] is None :
-        opts['seed'] = time.time()
-    
-    # load/prep resources
-    random.seed(opts['seed'])
-    data = build_data(opts['text'], opts['chars'], opts['colors'], opts['random-chars'], opts['random-text'], opts['random-text-char'])
-    font = load_font(opts['font'], opts['font-size'])
-    
-    # render the image
-    img = render_img(data, font, opts['bg-color'], opts['line-spacing'])
-
-    img = effect_sharpness(img, opts['sharpness'])
-
-    png_data = build_img(img, opts['image-format'])
-    
-    # build the response
-    response = werkzeug.Response(png_data, mimetype='image/%s' % opts['image-format'])
-
-    return response
-
-@werkzeug.Request.application
-def wsgi_application (request) :
-    """
-        Our werkzeug WSGI handler
-    """
-
-    try :
-        # request -> response
-        response = handle_request(request)
-
-        return response
-
-    except HTTPException, e :
-        # return as HTTP response
-        return e
-
-def main () :
-    handler = wsgiref.handlers.CGIHandler()
-    app = wsgi_application
-    
-    if DEBUG :
-        # enable debugging
-        app = werkzeug.DebuggedApplication(app, evalex=False)
-
-    handler.run(app)
-
-if __name__ == '__main__' :
-    main()
-