diff options
| -rwxr-xr-x | generate.py (renamed from generate) | 238 | ||||
| -rwxr-xr-x | pbserver.py | 16 |
2 files changed, 80 insertions, 174 deletions
@@ -2,198 +2,108 @@ import sys import os import re -import time -import string -import urllib, urllib2 -from subprocess import Popen, PIPE import sha -import simplejson as json -import mimetypes +from pb.config import * +import pb.lib.utils as utils -urlencode = urllib.urlencode -urlopen = urllib2.urlopen -Request = urllib2.Request - -MAX_SIZE = 1024 * 1024 * 1.2 * 1.5 -WORKING_DIR = "/var/www/cache" LIKE_A_BOSS = "ryz pepper seamonkey JAMES".split(" ") - -BIN_CONVERT = "/usr/bin/convert" -BIN_COMPOSITE = "/usr/bin/composite" -BIN_IDENTIFY = "/usr/bin/identify" DEFAULT_FINALFORMAT = "gif" DB_TAG = "pb"; GRAVITY = "NorthWest North NorthEast West Center East SouthWest South SouthEast".split(" ") +FORMAT = "jpg gif png".split(" ") +COMPOSE = "Over ATop Dst_Over Dst_In Dst_Out Multiply Screen Divide Plus Difference Exclusion "+ + "Lighten Darken Overlay Hard_Light Soft_Light Pegtop_Light Linear_Light Vivid_Light Pin_Light "+ + "Linear_Dodge Linear_Burn Color_Dodge Color_Burn".split(" "); -#{{{Utility functions -def is_color(s): - if s == "": - return "transparent" - if re.match('(rgba?\([0-9]+,[0-9]+,[0-9]+\))|([a-zA-Z]+)|(\#[A-Ha-h0-9]+)', s): - return s.replace(' ', ''); - else: - sys.stderr.write("Not a color: {}\n".format(s)) - raise ValueError -def bool_correct(s): - if re.match(r'^false$', s, re.IGNORECASE): - return False - elif re.match(r'^true$', s, re.IGNORECASE): - return True - else: - return s - -class dotdict(dict): - """dot.notation access to dictionary attributes""" - def __getattr__(self, attr): - return self.get(attr) - __setattr__= dict.__setitem__ - __delattr__= dict.__delitem__ - -def get_mimetype(f): - try: - mimetype = Popen( - [BIN_IDENTIFY, f], stdout=PIPE - ).communicate()[0].split(" ")[1].lower() - return mimetype - except Exception as e: - sys.stderr.write("IMGRID couldn't determine mimetype") - sys.stderr.write(str(e)) - raise; - -def sanitize (str): - return re.sub(r'\W+', '', str) - -def now(): - return int(time.time()) - -def browser_request (url, data=None): - headers = { - 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', - 'Accept': '*/*', - } - try: - req = Request(url, data, headers) - response = urlopen(req) - except IOError, e: - if hasattr(e, 'code'): - sys.stderr.write( '%s - ERROR %s' % (url, e.code) ) - raise; - return None - else: - return response - -def download(url, destination, max_size=MAX_SIZE): - response = browser_request(url, None) - rawimg = response.read() - if len(rawimg) == 0: - sys.stderr.write("got zero-length file") - raise; - if len(rawimg) > max_size: - sys.stderr.write("file too big: max size {} KB / {} is {} KB".format( - str(MAX_SIZE/1024), - destination, - str(len(rawimg)/1024) - )) - raise; - f = open(destination, "w") - f.write(rawimg) - f.close() - -def file_size (filepath): - try: - return os.stat(file)[6] - except Exception as e: - sys.stderr.write("IMGRID couldn't determine file size") - sys.stderr.write(str(e)) - raise; - -def gif_frames(filepath): - try: - info = Popen([BIN_IDENTIFY,filepath], stdout=PIPE).communicate()[0] - frames = filter((lambda x: x), map( - (lambda x: x.split(" ")[0]), - (info).split('\n') - )) - return frames - except Exception as e: - sys.stderr.write("IMGRID couldn't get gif frames") - sys.stderr.write(str(e)) - raise; -#}}} - -class Photoblaster(): - def __init__(self, params): +class Generate(): + def __init__(self, **kwargs): self.params = {} self.tag = "im" - self.now = now() + self.now = utils.now() self.files_created = [] self.commands = []; self._required_keys = [ #{{{ required_keys + #IMAGES "url", + "background", + + #BOOLS + "coalesce", + "dispose", + "nearest", + "merge_early", + "flip", + "flop", + "tile", "transparent", + + #COLORS + "black", + "white", "subtract", + + #INTS "fuzz", "width", "height", - "black", - "white", "brightness", "contrast", "saturation", - "hue", "rotate", - "flip", - "flop", - "background", - "merge_early", + "hue", + + #ENUMS "compose", "gravity", - "tile", "format", + + #STRINGS "name", "callback", - "coalesce", - "nearest", - "dispose", #}}} ] for k in self._required_keys: - if k in params: - if k in [ 'url', 'background' ] and bool_correct(params[k]): - self.params[k] = {} - self.params[k]['url'] = params[k] - self.params[k]['filename'] = "PBTMP{}_{}".format(now(), k) - - self.params[k]['path'] = os.path.join(WORKING_DIR, self.params[k]['filename']) + if k in kwargs: + if k in [ 'url', 'background' ] and utils.bool_correct(kwargs[k]): + self.params[k] = { + 'url' : kwargs[k], + 'filename' : self._make_tempname(k), + 'path' : os.path.join(WORKING_DIR, self._make_tempname(k)) , + } try: - download(self.params[k]['url'], self.params[k]['path']) + utils.download(self.params[k]['url'], self.params[k]['path']) self.files_created.append(self.params[k]['path']) - self.params[k]['mimetype'] = get_mimetype(self.params[k]['path']) - frames = gif_frames(self.params[k]['path']) - if len(frames) > 1: - self.params[k]['path'] = random.choice(frames) - - - except Exception as e: - sys.stderr.write("BAD PARAMS\n") + self.params[k]['mimetype'] = utils.get_mimetype(self.params[k]['path']) + except Exception: sys.stderr.write(str(e)) - raise; + raise Exception ("BAD PARAMS"); elif k in [ 'black', 'white', 'subtract' ]: try: - self.params[k] = is_color(params[k]) - except Exception as e: - sys.stderr.write("Unable to process color for:\n") - sys.stderr.write(k) - raise e + self.params[k] = utils.is_color(kwargs[k]) + except Exception: + raise Exception("Unable to process color for:\n{}".format(k)) + elif k in [ + "coalesce", "dispose", "nearest", "merge_early", + "flip", "flop", "tile", "transparent", + ]: + self.params[k] = utils.bootl_correct(utils.sanitize(kwargs[k])) + elif k == 'gravity' and self._test_enum(k, GRAVITY): + self.params[k] = kwargs[k] + elif k == 'format' and self._test_enum(k, FORMAT): + self.params[k] = kwargs[k] + elif k == 'compose' and self._test_enum(k, COMPOSE): + self.params[k] = kwargs[k] + elif k in [ "fuzz", "width", "height", "brightness", "contrast", "saturation", "rotate", "hue" ]: + self.params[k] = int(params[k]) else: - self.params[k] = bool_correct(sanitize(params[k])) + self.params[k] = utils.sanitize(kwargs[k]) else: - self.params[k] = False; + self.params[k] = None; - self.params = dotdict(self.params) + self.params = utils.dotdict(self.params) self.basename = self._get_filename(); @@ -203,6 +113,15 @@ class Photoblaster(): #final filepath is stored in self.filepath self.filepath = os.path.join(WORKING_DIR, self.filename) + def _make_tempname(self, s): + return "PBTMP{}{}".format(self.now, s); + + def _test_enum(self, k, arr): + if k in arr: + return True + else: + raise Exception("Bad Param: {}".format(k)) + def _get_filename(self): return "{}_{}_{}".format( self.tag, @@ -210,17 +129,12 @@ class Photoblaster(): self.params.username or "" ); - def _call_cmd(self, cmd, error=""): - try: - call(cmd) - self.commands.append(" ".join(cmd)); - except Exception as e: - sys.stderr.write("IT HIT AN ERROR") - sys.stderr.write(str(cmd)) - if error: - sys.stderr.write(error) - else: - sys.stderr.write(str(e)) + def _call_cmd(self, cmd): + try: + utils.call_cmd(cmd) + self.commands.append(" ".join(cmd)); + except Exception: + raise Exception("Unable to call cmd {}".format(str(cmd))) def _cleanup(self): if not len(self.files_created): diff --git a/pbserver.py b/pbserver.py index fb7fb65..a2fb1a7 100755 --- a/pbserver.py +++ b/pbserver.py @@ -6,16 +6,16 @@ from pb.imgrid import Imgrid from pb.breaker import Breaker from pb.pattern import Pattern -from pb.config import AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, BUCKET_NAME +from pb.config import AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, BUCKET_NAME, BIN_IDENTIFY +import pb.lib.utils as utils import os import sys import pb.lib.db as db -import mimetypes + import sha from subprocess import call, Popen, PIPE import simplejson as json -BIN_IDENTIFY = "/usr/bin/identify" from boto.s3.connection import S3Connection from boto.s3.key import Key @@ -30,20 +30,12 @@ BASE_URL = "http://i.asdf.us" def hashdir(filename): return sha.new(filename).hexdigest()[:2] -def file_size (filepath): - try: - return os.stat(filepath)[6] - except Exception as e: - sys.stderr.write(str(e)) - raise; - def bin_identify (filepath): ident = Popen([BIN_IDENTIFY, filepath], stdout=PIPE).communicate()[0] partz = ident.split(" ") width,height = partz[2].split("x") return [ width, height ] - def cleanup(filepath): try: call(['rm', filepath]) @@ -80,7 +72,7 @@ def insert_cmd (date, remote_addr, username, url, directory, oldfile, newfile, c def return_image(im, insert_url="NULL"): directory = hashdir(im.filename) dimensions = bin_identify(im.filepath) - size = file_size(im.filepath) + size = utils.file_size(im.filepath) objectname = "im/{}/{}".format(directory, im.filename) try: s3move(im.filepath, objectname) |
