From: Date: Fri, 14 Sep 2007 19:22:57 +0000 (-0400) Subject: first working version X-Git-Url: https://projects.mako.cc/source/yourule/commitdiff_plain/1711747333c7666b644f6124de39c49cd0b26526?ds=sidebyside first working version --- diff --git a/ruler_web.py b/ruler_web.py deleted file mode 100755 index 2738f8f..0000000 --- a/ruler_web.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python - -from __future__ import division -import web -import sys, os, re -from storm.locals import * -from ruler import RulerImage - -# 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))', 'ruler', - '/gallery(.*)', 'gallery', - '/delete/(\d+)', 'delete', - '/undelete/(\d+)', 'undelete') - -database = create_database("sqlite:ruler_web.db") -store = Store(database) - -class SavedRuler(object): - __storm_table__ = "gallery" - id = Int(primary=True) - pixel_width = Float() - unit_width = Float() - model = Unicode() - units = Unicode() - show = Int() - - def __init__(self, **kw): - self.pixel_width = kw['pixel_width'] - self.unit_width = kw['unit_width'] - self.units = kw['units'] - self.model = kw['model'] - - def cm_width(self): - if self.units == 'centimeters': - return self.unit_width - elif self.units == 'inches': - return(self.unit_width * 2.54) - - def in_width(self): - if self.units == 'inches': - return self.unit_width - elif self.units == 'centimeters': - return(self.unit_width * 0.3937) - - -class index: - def GET(self): - web.header("Content-Type","text/html; charset=utf-8") - web.render('index.tmpl') - - def POST(self): - input = web.input() - - pixel_width = input['pixel_width'] - unit_width = input['unit_width'] - units = input['units'] - ruler_url = 'ruler_%spx_%s%s.png' % (pixel_width, unit_width, units) - web.redirect('/show/%s' % ruler_url) - -class 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_units(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 = Ruler(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.output()) - else: - pin, pout = os.popen2('convert -size %sx%s - %s:-' % \ - (pixel_width, ruler_height, ext)) - - pin.write(ruler.output()) - 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(SavedRuler, SavedRuler.show == 1) - rulers.order_by(SavedRuler.model) - - web.render('gallery.tmpl') - - def POST(self): - input = web.input() - - new_ruler = SavedRuler(pixel_width=float(input['pixel_width']), - unit_width=float(input['unit_width']), - units=unicode(input['units']), - model=unicode(input['model'])) - - store.add(new_ruler) - store.commit() - - web.redirect('gallery') - -class delete: - def GET(self, id): - ruler = store.get(SavedRuler, int(id)) - ruler.show = 0 - store.commit() - web.redirect('/gallery') - - -class undelete: - def GET(self, id): - ruler = store.get(SavedRuler, int(id)) - ruler.show = 1 - store.commit() - web.redirect('/gallery') - -def get_other_units(url): - pixel_width, unit_width, units = process_ruler_url(url)[0:3] - ruler = SavedRuler(pixel_width=float(pixel_width), - unit_width=float(unit_width), - units=unicode(units), - model=unicode(model)) - -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()) - -# 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) - diff --git a/static/images/bl.png b/static/images/bl.png new file mode 100644 index 0000000..f0970ae Binary files /dev/null and b/static/images/bl.png differ diff --git a/static/images/br.png b/static/images/br.png new file mode 100644 index 0000000..7c1a5c8 Binary files /dev/null and b/static/images/br.png differ diff --git a/static/images/r.png b/static/images/r.png new file mode 100644 index 0000000..fab4ac0 Binary files /dev/null and b/static/images/r.png differ diff --git a/static/images/tl.png b/static/images/tl.png new file mode 100644 index 0000000..04576f8 Binary files /dev/null and b/static/images/tl.png differ diff --git a/static/images/tr.png b/static/images/tr.png new file mode 100644 index 0000000..e4ac949 Binary files /dev/null and b/static/images/tr.png differ diff --git a/static/images/trash.png b/static/images/trash.png deleted file mode 100644 index 0e0953c..0000000 Binary files a/static/images/trash.png and /dev/null differ diff --git a/static/images/yourule_banner.png b/static/images/yourule_banner.png new file mode 100644 index 0000000..877889c Binary files /dev/null and b/static/images/yourule_banner.png differ diff --git a/static/images/yourule_banner.svg b/static/images/yourule_banner.svg new file mode 100644 index 0000000..3b46682 --- /dev/null +++ b/static/images/yourule_banner.svg @@ -0,0 +1,556 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + YouRule + Onscreen Ruler Generator + diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..b589157 --- /dev/null +++ b/static/style.css @@ -0,0 +1,137 @@ +@charset "UTF-8"; + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +dl, dt, dd, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-family: inherit; + vertical-align: baseline; +} + +body { + font: Arial, Helvetica, sans-serif; +} + +label { + font-weight: bold; +} + +em { + font-style: italic; +} + +#wrapper { + padding: 1em 0 0 0; + margin: 0 auto 0 auto; + width: 885px; +} + +#header { + width: 885px; + height: 138px; + background: url(/static/images/yourule_banner.png); +} + +#header h1, #header h2 { + display: none; +} + +.mainbox { + margin-top: 1em; + background: url(/static/images/tl.png) no-repeat top left; +} + +.mainbox_top { + background: url(/static/images/tr.png) no-repeat top right; +} + +.mainbox_bottom { + background: url(/static/images/bl.png) no-repeat bottom left; +} + +.mainbox_bottom div { + background: url(/static/images/br.png) no-repeat bottom right; +} + +.mainbox_content { + background: url(/static/images/r.png) top right repeat-y; +} + + +.mainbox_top div, .mainbox_top, .mainbox_bottom div, .mainbox_bottom { + width: 100%; + height: 30px; + font-size: 1px; +} + +.mainbox_content, .mainbox_bottom { + margin-top: -19px; +} + +.mainbox_content { + padding: 0em 3em 2em 3em; + line-height: 1.5em; +} + +.mainbox_content h2 { + border-bottom: 3px #1e3d7b solid; + margin: 19px 0 0.8em 0; + font-weight: bold; +} + +.mainbox_content p { + margin-bottom: 0.5em; +} + +#gallery { + border: 1px solid #1e3d7b; + width: 100%; + border-collapse: collapse; +} + +#gallery th { + background: #1e3d7b; + color: white; +} + +#gallery td { + text-align: center; +} + +#menu { + text-align: right; + margin: 0.5em; +} + +#rulerimg { + margin: 0.5em; +} + +.errormsg { + background-color: #f7fb70; + color: #4c4c4c; + text-align: center; + border: 1px #fdff00 solid; + width: 20em; + margin: 1em; +} + +strong { + font-weight: bold; +} + +#footer { + margin-top: 3em; + font-size: 0.8em; + text-align: center; +} diff --git a/ruler.py b/svgruler.py similarity index 97% rename from ruler.py rename to svgruler.py index 39bcd3d..7c66050 100644 --- a/ruler.py +++ b/svgruler.py @@ -2,7 +2,7 @@ from __future__ import division import SVGdraw -class Ruler: +class SVGRuler: def __init__(self, scale=None, units=None, ruler_height=None, ruler_length=None): @@ -49,14 +49,14 @@ class Ruler: self.__drawline(0.3) self.__drawline(0.6) - self.svg.addElement(SVGdraw.text((self.point - font_height * 1.4), + self.svg.addElement(SVGdraw.text((self.point - font_height * 1.15), (self.ruler_height * 0.6 - 5), str(i + 1), font_height)) self.drawing.setSVG(self.svg) - def output(self): + def getxml(self): import cStringIO xml = cStringIO.StringIO() xml.write("\n") diff --git a/templates/_form_elements.tmpl b/templates/_form_elements.tmpl index 18c57c8..b365ce0 100644 --- a/templates/_form_elements.tmpl +++ b/templates/_form_elements.tmpl @@ -1,14 +1,14 @@ -

Units: +

-

+

-

+

+
+ + +
+
+
+ #filter Filter $body #end filter +
+
+
+ + + +
+ diff --git a/yourule.py b/yourule.py new file mode 100755 index 0000000..9010217 --- /dev/null +++ b/yourule.py @@ -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())) +