#!/usr/bin/python2.7 import re import time from subprocess import call import simplejson as json import sys import os import db import sha #{{{ logging #import logging #logger = logging.getLogger('gradient') #logging.FileHandler('/var/www/cache/gradient.log') #formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') #hdlr.setFormatter(formatter) #logger.addHandler(hdlr) #logger.setLevel(logging.WARNING) #}}} BASE_URL = "http://localhost:8080/" PARAM_LIST = [ "width", "height", "color1", "color2", "stripes", "stripenumber", "stripeintensity", "blurriness", "contrast", "brightness", "saturation", "hue", "halftone", "bevel", "percentbeveled", "rotate", "flip", "flop", "tilt", "filetype", "gradienttype", "username", ] BIN_CONVERT = "/usr/bin/convert" BIN_IDENTIFY = "/usr/bin/identify" BEVELBORDER = "./bevelborder" WEB_ADDR = "http://i.asdf.us" DEFAULT_FORMAT = "png" DEFAULT_COLORS = { "color1" : "white", "color2" : "black", }; WORKING_DIR = '/tmp' DEFAULT_WIDTH = "200" DEFAULT_HEIGHT = "200" REMOTE_ADDRESS = "" BEVELVALUES = { "flatout": ["-s","-m","outer"], "flatinner": ["-s","-m","inner"], "evenlyframed": ["-s ", "-m ", "split"], "biginner": ["-s","-m","outer","-c","50","-b","red","-a","25"], "bigouter": ["-s","-m","split","-c","50","-b","red","-a","25"], "dramaticflatout": ["-s","-m","outer","-a","25","-b","blue"], "dramaticflatinner": ["-s","-m","outer","-a","25","-b","blue"], } BEVEL_DEFAULT = "12"; HALFTONEVALUES = { "checkeredfade": "h6x6a", "etchedtransition": "o8x8", "bendaydots": "h16x16o", "smallerdots1": "h8x8o", "smallerdots2": "c7x7w", "flatstripes": "o2x2", } def sanitize (s): return re.sub(re.compile(r'\W+'), '', s) def is_number(s): try: return int(s) except (ValueError, TypeError): return False class Gradient: def __init__(self, form): self.now = int(time.time()) self.tag = "imGradient" self.commands = [] self.filename = "" self.filepath = "" params = {} for key in PARAM_LIST: if key in form: if key in ['color1', 'color2']: params[key] = form[key] #params[key] = form[key].value else: params[key] = sanitize(form[key]) #params[key] = sanitize(form[key].value) if key in ['rotate','tilt','blurriness','stripenumber','stripeintensity']: params[key] = params[key] if is_number(params[key]) else "" elif key in ['brightness', 'contrast', 'hue']: if not is_number(params[key]) or params[key] == "100": params[key] = "" else: params[key] = "" params['width'] = params['width'] if is_number(params['width']) else DEFAULT_WIDTH params['height'] = params['height'] if is_number(params['height']) else DEFAULT_HEIGHT params["color1"] = params["color1"] or DEFAULT_COLORS["color1"]; params["color2"] = params["color2"] or DEFAULT_COLORS["color2"]; self.params = params def newfilename(self): return "{}{}-{}_{}_{}.{}".format( self.tag, self.params['color1'].replace('#',''), self.params['color2'].replace('#',''), self.now, self.params['username'], self.params['filetype'] or DEFAULT_FORMAT, ) def buildCmd(self, filename, directory=WORKING_DIR): cmd = [BIN_CONVERT] cmd.extend([ '-size', "{}x{}".format(self.params["width"],self.params["height"]) ]) if self.params['rotate']: cmd.extend(["-rotate", self.params["rotate"]]) if self.params['tilt']: cmd.extend(["-distort","SRT",self.params['tilt']]) if self.params['flip'] == "true": cmd.append("-flip") if self.params['flop'] == "true": cmd.append("-flop") if self.params['contrast']: cmd.extend(["-contrast-stretch", self.params['contrast']]) gradients = { "canvas" : ["canvas:{}".format(self.params['color1'])], "radial" : [ "radial-gradient:{}-{}".format( self.params['color1'], self.params['color2']) ], "colorspace" : [ "-colorspace", "Gray", "plasma:{}-{}".format(self.params['color1'], self.params['color2']) ], "mirrored" : [ "plasma:{}-{}".format(self.params['color1'], self.params['color2']), "\(","+clone","-flop","\)", "append" ], "plasmawash" : [ "plasma:{}-{}".format(self.params['color1'], self.params['color2']), "-set","colorspace","HSB" ], "gradientwash" : [ "gradient:{}-{}".format(self.params['color1'], self.params['color2']), "-set","colorspace","HSB" ], "noise" : ["xc:","+noise","Random","-virtual-pixel","tile"] } if self.params["gradienttype"] in gradients: cmd.extend(gradients[self.params['gradienttype']]) else: cmd.append("gradient:{}-{}".format(self.params['color1'], self.params['color2'])) if self.params['blurriness']: cmd.extend(["-blur","0x{}".format(self.params["blurriness"]),"-auto-level"]) if self.params['stripes'] == "true" and len(self.params['stripenumber']): cmd.extend(["-function","Sinusoid"]) if self.params['stripeintensity']: cmd.append("{},{}".format(self.params['stripenumber'],self.params["stripeintensity"])) else: cmd.append(self.params['stripenumber']) if self.params["halftone"] in HALFTONEVALUES: cmd.extend([ "-ordered-dither", HALFTONEVALUES[self.params["halftone"]] ]) cmd += [ '-modulate', "{},{},{}".format( self.params['brightness'] or "100", self.params['saturation'] or "100", self.params['hue'] or "100") ] cmd.append(os.path.join(directory,filename)); # logger.warning('in buildCmd: {}' % cmd) try: call(cmd) self.commands.append(" ".join(cmd)); except Exception as e: sys.stderr.write( "ERROR:{}".format(e)) raise; return cmd def makeBevel(self, filename, directory): def get_bevelvalue(key, bevpercentval): bevel_args = BEVELVALUES[key] bevel_args.insert(1, bevpercentval) return bevel_args if self.params['percentbeveled']: try: w, h = map(int, (self.params['width'], self.params['height'])) except Exception as e: sys.stderr.write( "ERROR: {}".format(e)) exit(1); if h >= w: bevpercentval = str(int(self.params['percentbeveled'])*0.005*int(h)) else: bevpercentval = str(int(self.params['percentbeveled'])*0.005*int(w)) else: bevpercentval = BEVEL_DEFAULT bevel = get_bevelvalue(self.params['bevel'], bevpercentval) cmd = [BEVELBORDER] cmd += bevel cmd += [ os.path.join(directory,filename), os.path.join(directory, filename) ] try: call(cmd) self.commands.append(" ".join(cmd)) except Exception as e: sys.stderr.write( "ERROR: {}".format(e)) raise; def create(self, directory=WORKING_DIR): self.filename = self.newfilename() self.filepath = os.path.join(directory, self.filename) self.buildCmd(self.filename, directory) if self.params['bevel'] in BEVELVALUES: self.makeBevel(self.filename, directory) self.output = [ str(os.stat(self.filepath)[6]), "{}px".format(self.params["width"]), "{}px".format(self.params["height"]), ] TEST_FORM = { "width" : "200", "color1" : "#ffdead", "color2" : "blue", "stripes" : "true", "stripenumber" : "20", "gradienttype" : "radial", "stripeintensity" : "20", "halftone" : "checkeredfade", "percentbeveled" : "30", "flip" : "true", "bevel" : "flatout", "rotate" : "20", "height" : "200", "filetype" : "jpg", "username" : "whatever" } if __name__ == "__main__": g = Gradient(TEST_FORM); g.create(); print g.now print " ".join(g.commands) print "\n".join(g.output)