implement Options/?help
authorTero Marttila <terom@fixme.fi>
Tue, 05 May 2009 18:01:44 +0300
changeset 8 44d5ead35f4b
parent 7 9a6ac93e7446
child 9 efb80785ca9b
implement Options/?help
index.cgi
--- a/index.cgi	Tue May 05 17:32:27 2009 +0300
+++ b/index.cgi	Tue May 05 18:01:44 2009 +0300
@@ -26,15 +26,12 @@
     
 class Defaults :
     # settings
-    text = [
-        u"aalto",
-        u"unive",
-        u"rsity"
-    ]
+
+    text_lang = 'en'
 
     chars = [ u'"', u'!', u'?' ]
 
-    line_colors = [
+    colors = [
         "#0469af",
         "#fbc614",
         "#e1313b",
@@ -43,17 +40,42 @@
     font_name = 'helvetica'
     font_size = 30
     
-    background_color = "#ffffff"
+    bg_color = "#ffffff"
     line_spacing = -10
     sharpness = 0.6
 
     img_format = 'png'
 
-fonts = {
+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
@@ -113,7 +135,7 @@
     """
     
     # load font
-    font_path = fonts[font_name]
+    font_path = FONTS[font_name]
     font = ImageFont.truetype(font_path, font_size)
     
     return font
@@ -209,51 +231,89 @@
     else :
         raise ValueError(val)
 
-def handle_request (req) :
-    # parse args
-    if 'text' in req.args :
-        text = req.args.getlist('text', unicode)
-    else :
-        text = Defaults.text
-    
-    if 'chars' in req.args :
-        chars = req.args.getlist('chars', unicode)
-    else :
-        chars = Defaults.chars
+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
 
-    if 'colors' in req.args :
-        colors = req.args.getlist('colors', arg_color)
-
-    else :
-        colors = Defaults.line_colors
+    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 :
+            return args.get(self.name, self.default, self.type)
 
-    font_name = req.args.get('font', Defaults.font_name)
-    font_size = req.args.get('font-size', Defaults.font_size, int)
-    background_color = req.args.get('background-color', Defaults.background_color, arg_color)
-    line_spacing = req.args.get('line-spacing', Defaults.line_spacing, int)
-    sharpness = req.args.get('sharpness', Defaults.sharpness, float)
-    img_format = req.args.get('image-format', Defaults.img_format)
+class Options (object) :
+    def __init__ (self, *options) :
+        self.options = options
 
-    if font_size > FONT_SIZE_MAX :
-        raise ValueError(font_size)
+    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('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()),
+)
+
+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'])
     
     # put the chars in random order by default
-    if req.args.get('random-chars', True, arg_bool) :
-        chars = randomize(chars)
+    if opts['random-chars'] :
+        opts['chars'] = randomize(opts['chars'])
 
     # load/prep resources
-    data = build_data(text, chars, colors)
-    font = load_font(font_name, font_size)
+    data = build_data(opts['text'], opts['chars'], opts['colors'])
+    font = load_font(opts['font'], opts['font-size'])
     
     # render the image
-    img = render_img(data, font, background_color, line_spacing)
+    img = render_img(data, font, opts['bg-color'], opts['line-spacing'])
 
-    img = effect_sharpness(img, sharpness)
+    img = effect_sharpness(img, opts['sharpness'])
 
-    png_data = build_img(img, img_format)
+    png_data = build_img(img, opts['image-format'])
     
     # build the response
-    response = werkzeug.Response(png_data, mimetype='image/%s' % img_format)
+    response = werkzeug.Response(png_data, mimetype='image/%s' % opts['image-format'])
 
     return response