first working version
[yourule] / yourule.py
diff --git a/yourule.py b/yourule.py
new file mode 100755 (executable)
index 0000000..9010217
--- /dev/null
@@ -0,0 +1,220 @@
+#!/usr/bin/env python
+
+from __future__ import division
+import web
+import sys, os, re
+from storm.locals import *
+from svgruler import SVGRuler
+
+# the url map for the application
+urls = ( '/', 'index',
+         '/ruler_([0-9\.]+)px_([0-9\.]+)([A-Za-z]+).(svg|png|jpg)', 'ruler_img',
+         '/show/(.*(svg|png|jpg))', 'show_ruler',
+         '/gallery(.*)', 'gallery',
+         '/delete/(\d+)', 'delete',
+         '/undelete/(\d+)', 'undelete')
+
+database = create_database("sqlite:yourule.db")
+store = Store(database)
+
+class Ruler(object):
+    __storm_table__ = "gallery"
+    id = Int(primary=True)
+    pixel_width = Float()
+    unit_width = Float()
+    model = Unicode()
+    units = Unicode()
+    show = Int()
+    cm_in_ratio = 0.3937
+
+    def __init__(self, **kw):
+        self.pixel_width = float(kw['pixel_width'])
+        self.unit_width = float(kw['unit_width'])
+        self.units = unicode(kw['units'])
+        if kw.has_key('model'):
+            self.model = unicode(kw['model'])
+        else:
+            self.model = u''
+
+    def cm_width(self):
+        if self.units == 'centimeters':
+            return self.unit_width
+        elif self.units == 'inches':
+            return(round(self.unit_width / self.cm_in_ratio, 2))
+
+    def in_width(self):
+        if self.units == 'inches':
+            return self.unit_width
+        elif self.units == 'centimeters':
+            return(round(self.unit_width * self.cm_in_ratio, 2))
+
+    def url(self):
+        return('ruler_%spx_%s%s.png' % (self.pixel_width,
+                                        self.unit_width, self.units))
+
+
+class index:
+    def GET(self):
+        web.header("Content-Type","text/html; charset=utf-8")
+        web.render('index.tmpl')
+
+    def POST(self):
+        input = web.input()
+
+        errormsg = validate_input(input)
+
+        if errormsg:
+            pixel_width = input['pixel_width']
+            unit_width = input['unit_width']
+            units = input['units']
+            web.render('index.tmpl')
+        else:
+            ruler = Ruler(pixel_width = input['pixel_width'], 
+                          unit_width = input['unit_width'], 
+                          units = input['units'])
+            
+            web.redirect('/show/%s' % ruler.url())
+
+class show_ruler:
+    def GET(self, ruler_url, ext):
+        web.debug('test test')
+        if web.input().has_key('fromgallery'):
+            fromgallery = True
+        else:
+            fromgallery = False
+
+        other_unit, other_unit_url = get_other_unit(ruler_url)
+
+        web.header("Content-Type","text/html; charset=utf-8")
+        web.render('show_ruler.tmpl')
+
+
+class ruler_img:
+    def GET(self, pixel_width=None, unit_width=None, units=None, ext=None):
+
+        # TODO check to see if it's a format that we support
+
+        # set ruler height to be 200 px always
+        pixel_width = float(pixel_width)
+        unit_width = float(unit_width)
+
+        ruler_height = 200
+
+        scale = pixel_width / unit_width
+        ruler_length = int(unit_width)
+
+        ruler = SVGRuler(scale, units, ruler_height, ruler_length)
+
+        # print the header
+        if ext == 'svg': ext = 'svg+xml'
+        web.header("Content-Type", "image/%s" % ext)
+
+        if ext == 'svg+xml':
+            sys.stdout.write(ruler.getxml())
+        else:
+            pin, pout = os.popen2('convert -size %sx%s - %s:-' % \
+                                  (pixel_width, ruler_height, ext))
+
+            pin.write(ruler.getxml())
+            pin.close()
+            sys.stdout.write(pout.read())
+
+class gallery:
+    def GET(self, ruler_url):
+
+        if ruler_url:
+            pixel_width, unit_width, units = process_ruler_url(ruler_url)[0:3]
+
+        rulers = store.find(Ruler, Ruler.show == 1)
+        rulers.order_by(Ruler.model)
+        web.render('gallery.tmpl')
+
+    def POST(self, ruler_url):
+        input = web.input()
+
+        errormsg = valid_input(input)
+        if not input.model:
+            errormsg = 'Please fill out all fields.'
+
+        if errormsg:
+            pixel_width = input['pixel_width']
+            unit_width = input['unit_width']
+            units = input['units']
+            model = input['model']
+        else:
+            new_ruler = Ruler(pixel_width = input['pixel_width'],
+                              unit_width = input['unit_width'],
+                              units = input['units'],
+                              model = input['model'])
+
+            store.add(new_ruler)
+            store.commit()
+
+        rulers = store.find(Ruler, Ruler.show == 1)
+        rulers.order_by(Ruler.model)
+        web.render('gallery.tmpl')
+
+class delete:
+    def GET(self, id):
+        ruler = store.get(Ruler, int(id))
+        ruler.show = 0
+        store.commit()
+        web.redirect('/gallery')
+
+
+class undelete:
+    def GET(self, id):
+        ruler = store.get(Ruler, int(id))
+        ruler.show = 1
+        store.commit()
+        web.redirect('/gallery')
+
+def get_other_unit(url):
+    pixel_width, unit_width, units = process_ruler_url(url)[0:3]
+
+    ruler = Ruler(pixel_width=pixel_width, unit_width=unit_width, units=units)
+    pixel_width, unit_width, units = process_ruler_url(url)[0:3]
+
+    if units == 'centimeters':
+        units = 'inches'
+        unit_width = ruler.in_width()
+    elif units == 'inches':
+        units = 'centimeters'
+        unit_width = ruler.cm_width()
+
+    new_ruler = Ruler(pixel_width=pixel_width, unit_width=unit_width,
+                      units=units)
+
+    web.debug(units)
+    return(units, new_ruler.url())
+
+
+def process_ruler_url(url):
+    url = re.sub(r'^/?(ruler.*)$', r'\1', url)
+    return(re.match( r'ruler_([\d\.]+)px_([\d\.]+)(\w+).(png|svg|jpg)',
+           url).groups())
+
+def validate_input(input):
+    errormsg = False
+
+    if not input.pixel_width \
+        or not input.unit_width:
+        errormsg = 'Please fill out all fields.'
+    elif not re.match('^[\d\.]+$', input.pixel_width) \
+        or not re.match('^[\d\.]+$', input.unit_width):
+        errormsg = "Widths must be numbers."
+    elif input['pixel_width'] < 0 \
+        or input['unit_width'] < 0:
+        errormsg = 'Widths must be greater than postive.'
+
+    return(errormsg)
+
+# render the site template here so that i can use it later
+web.render('site.tmpl', None, True, 'site')
+
+web.webapi.internalerror = web.debugerror
+if __name__ == "__main__":
+    web.run(urls, globals(), web.reloader)
+
+application = web.wsgifunc(web.webpyfunc(urls, globals()))
+

Benjamin Mako Hill || Want to submit a patch?