logo.py
author Tero Marttila <terom@fixme.fi>
Tue, 05 May 2009 16:21:41 +0300
changeset 0 44c5c8c2ac66
permissions -rwxr-xr-x
initial code
0
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#!/usr/bin/python2.5
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
import cgi, cgitb
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
cgitb.enable()
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
from PIL import Image, ImageDraw, ImageFont
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
from cStringIO import StringIO
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
import random
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
# settings
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
text = [
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    "aalto",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    "unive",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    "rsity"
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
]
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
random_chars = [ '"', '!', '?' ]
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
line_colors = [
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
    "#0469af",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
    "#fbc614",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    "#e1313b",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
]
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
fonts = {
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    'dejavu-sans-bold':     "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
    'helvetica':            "HELR65W.TTF",
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
}
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
font_name = 'helvetica'
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
font_size = 30
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
def randomize (seq) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
        Returns the given sequence in random order as a list
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
    # copy
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
    l = list(seq)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    # rearrange
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
    random.shuffle(l)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    return l
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
def build_data (text, chars, line_colors) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
        Returns a matrix of (text, color) tuples representing the data to render
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        [ [ (str, str) ] ]
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
            text        - list of lines
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
            chars       - list of random chars to interpse
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
            line_colors - list of colors to draw the chars in
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    data = []
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
    for line, char, color in zip(text, chars, line_colors) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
        # pick position to place char
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        pos = random.randint(1, len(line) - 1)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        # split into three parts
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
        data.append([
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
                (line[:pos], "#000000"),
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
                (char, color),
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
                (line[pos:], "#000000"),
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
            ])
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    return data
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
def load_font (font_name, font_size) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
        Load a font by name
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    # load font
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
    font_path = fonts[font_name]
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    font = ImageFont.truetype(font_path, font_size)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
    return font
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
def render_img (data, font, background_color="#ffffff", line_spacing=0) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
        Render the data (as from build_data) as an image, using the given PIL.ImageFont, and return the PIL Image object
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
    img_width = img_height = 0
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
    img_data = []
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    # compute image width/height
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    for segments in data :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
        line_width = line_height = 0
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        # build a new list of segments with additional info
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
        line_segments = []
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
        for seg_text, seg_color in segments :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
            # compute rendered text size
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
            seg_width, seg_height = font.getsize(seg_text)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
            
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
            # update line_*
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
            line_width += seg_width
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
            line_height = max(line_height, seg_height)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
            
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
            # build the new segments list
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
            line_segments.append((seg_text, seg_color, seg_width))
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        # update img_*
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        img_width = max(img_width, line_width)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
        img_height += line_height
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
        img_data.append((line_segments, line_height))
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
    # calculate height needed for line spacing
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    img_height += (len(img_data) - 1) * line_spacing
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    # create image
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    img = Image.new("RGB", (img_width, img_height), background_color)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    draw = ImageDraw.Draw(img)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
    # draw text
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
    img_y = 0
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
    for segments, line_height in img_data :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
        img_x = 0
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
        # draw each segment build above, incremeing along img_x
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
        for seg_text, seg_color, seg_width in segments :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
            draw.text((img_x, img_y), seg_text, font=font, fill=seg_color)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
            img_x += seg_width
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
        
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
        img_y += line_height + line_spacing
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
    
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    return img
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
def build_png (img) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        Write the given PIL.Image as a string, returning the raw binary data
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
    # render PNG output
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    buf = StringIO()
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
    img.save(buf, "png")
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
    data = buf.getvalue()
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
    return data
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
def response (type, data) :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        Write out the HTTP Response
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    """
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    from sys import stdout
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
    stdout.write("Content-Type: %s\r\n" % type)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    stdout.write("Content-Length: %d\r\n" % len(data))
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    stdout.write("\r\n")
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    stdout.write(data)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
def main () :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    data = build_data(text, randomize(random_chars), line_colors)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
    font = load_font(font_name, font_size)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    img = render_img(data, font)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    png_data = build_png(img)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    response("image/png", png_data)
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
if __name__ == '__main__' :
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    main()
44c5c8c2ac66 initial code
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173