diff options
| -rwxr-xr-x | Flask_test/pbserver.py | 133 | ||||
| -rwxr-xr-x | lib/Pb/Break/__init__.py | 4 | ||||
| -rwxr-xr-x | lib/Pb/Generate/__init__.py | 4 | ||||
| -rwxr-xr-x | lib/Pb/Gradient/__init__.py | 2 | ||||
| -rwxr-xr-x | lib/Pb/Grid/__init__.py | 4 | ||||
| -rwxr-xr-x | lib/Pb/Landscape/__init__.py | 6 | ||||
| -rwxr-xr-x | lib/Pb/Pattern/__init__.py | 6 | ||||
| -rw-r--r-- | lib/Pb/__init__.py | 127 | ||||
| -rwxr-xr-x | pbserver.py | 217 | ||||
| -rw-r--r-- | run_examples.py | 6 |
10 files changed, 245 insertions, 264 deletions
diff --git a/Flask_test/pbserver.py b/Flask_test/pbserver.py new file mode 100755 index 0000000..321619f --- /dev/null +++ b/Flask_test/pbserver.py @@ -0,0 +1,133 @@ +#!/usr/bin/python2.7 +from bottle import route, run, post, request, static_file +import sys +sys.path.append("./lib") +#FIXME probably can get away with import * here +from Pb.Break import PbBreak +from Pb.Generate import PbGenerate +from Pb.Gradient import PbGradient +from Pb.Grid import PbGrid +from Pb.Landscape import PbLandscape +from Pb.Pattern import PbPattern + +from Config import AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, BUCKET_NAME, BIN_IDENTIFY +from Pb import Pb +from Db import Db + +import os +import sys + +import sha +from subprocess import call, Popen, PIPE +import simplejson as json + +from boto.s3.connection import S3Connection +from boto.s3.key import Key +# +try: + db = Db(); +except Exception as e: + sys.stderr.write("Could not connect to db:\n{}".format(e)) + sys.exit(1); + +BASE_URL = "http://i.asdf.us" + +def s3move(filename,objectname): + try: + conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, is_secure=False) + b = conn.get_bucket(BUCKET_NAME) + k = Key(b) + k.key = objectname + k.set_contents_from_filename(filename) + k.set_acl('public-read') + k.storage_class = 'REDUCED_REDUNDANCY' + except Exception as e: + sys.stderr.write(str(e)); + raise(e) + + + +def return_image(im, insert_url="NULL"): + return format_im_data(im, insert_url) + + +def return_jsonp(im, insert_url="NULL"): + return "{}({})".format(im.get("callback"), format_im_data(im, insert_url)) + + +def _pb_post(pb_class, request): + try: + im = pb_class(**(dict(request.forms))) + im.create(); + return return_image(im) + except Exception as e: + sys.stderr.write("%s failure" % pb_class.__name__) + sys.stderr.write("params:\n") + for i in request.forms: + sys.stderr.write("{}:{}\n".format(i, request.forms[i])) + raise; + return json.dumps({ 'error' : 'Request could not be processed' }) + +@post('/im/api/imgradient') +def gradient(): + _pb_post(PbGradient, request) + +@post('/im/api/imgrid') +def imgrid(): + _pb_post(PbLandscape, request) + +@post('/im/api/generate') +def generate(): + _pb_post(PbGenerate, request) + +@post('/im/api/imbreak') + _pb_post(PbBreak, request) + +@post('/im/api/impattern') +def pattern(): + _pb_post(PbPattern, request) + +@post('/im/api/imlandscape') +def imlandscape(): + _pb_post(Imlandscape, request) + + + +#static routes +@route('/im/<filename>') +def server_static(filename): + return static_file(filename, root='frontend/im/') +@route('/im') +def server_static(): + return static_file("index.html", root='frontend/im/') +@route('/imgrid') +def server_static(): + return static_file("index.html", root='frontend/imgrid/') +@route('/imgradient') +def server_static(): + return static_file("index.html", root='frontend/imgradient/') +@route('/imlandscape') +def server_static(): + return static_file("index.html", root='frontend/imlandscape/') +@route('/impattern') +def server_static(): + return static_file("index.html", root='frontend/impattern/') +@route('/imbreak') +def server_static(): + return static_file("index.html", root='frontend/imbreak/') +@route('/') +def server_static(): + return static_file("index.html", root='frontend/im/') +@route('/css/<filename>') +def server_static(filename): + return static_file(filename, root='frontend/css/') +@route('/js/<filename>') +def server_static(filename): + return static_file(filename, root='frontend/js/') +@route('/img/<filename>') +def server_static(filename): + return static_file(filename, root='frontend/img/') + + +run(host='0.0.0.0', server='flup', port=8999, debug=True) +#run(host='0.0.0.0', port=8999, debug=True) diff --git a/lib/Pb/Break/__init__.py b/lib/Pb/Break/__init__.py index cf12cc2..d8faa14 100755 --- a/lib/Pb/Break/__init__.py +++ b/lib/Pb/Break/__init__.py @@ -28,7 +28,7 @@ class PbBreak(Pb): #FIXME in db gallery "expanded" : "false" } def __init__(self, **kwargs): - super(PbBreak,self).__init__(); + super(PbBreak,self).__init__(**kwargs); _definitions = { 'username': { 'type': 'string' }, 'breaktype': { 'type': 'string' }, @@ -59,6 +59,8 @@ class PbBreak(Pb): #FIXME in db gallery self.filename, self.filepath = self._filename_filepath_create(url=self.params.url.url, extension=self.params.finalformat) self._conversion_file = self._tempfilepath_create(namepart="conversion", extension=self.params.breaktype) + self._db_url_param = str(self.params.url['url']) + def _get_breaktype(self, key): #{{{ conversion table breaktypeTranslate = { diff --git a/lib/Pb/Generate/__init__.py b/lib/Pb/Generate/__init__.py index e50e514..8e206db 100755 --- a/lib/Pb/Generate/__init__.py +++ b/lib/Pb/Generate/__init__.py @@ -45,7 +45,7 @@ class PbGenerate(Pb): #}}} } def __init__(self, **kwargs): - super(PbGenerate,self).__init__(); + super(PbGenerate,self).__init__(**kwargs); _definitions = { #IMAGES "url": { 'type': "img_url" }, @@ -91,6 +91,8 @@ class PbGenerate(Pb): if self.params.transparent: self.tag = self.params.transparent self.filename, self.filepath = self._filename_filepath_create(url=self.params.url['url'], extension=self.params.format) + + self._db_url_param = str(self.params.url['url']) def _composite (self): cmd = [ diff --git a/lib/Pb/Gradient/__init__.py b/lib/Pb/Gradient/__init__.py index 00adbf1..25e84bb 100755 --- a/lib/Pb/Gradient/__init__.py +++ b/lib/Pb/Gradient/__init__.py @@ -42,7 +42,7 @@ class PbGradient(Pb): "username" : "whatever"
}
def __init__(self, **kwargs):
- super(PbGradient,self).__init__();
+ super(PbGradient,self).__init__(**kwargs);
_definitions = {
'width': { 'type':'int', 'default': DEFAULT_WIDTH },
'height': { 'type':'int', 'default' : DEFAULT_HEIGHT },
diff --git a/lib/Pb/Grid/__init__.py b/lib/Pb/Grid/__init__.py index 2f7ae4b..b940d5c 100755 --- a/lib/Pb/Grid/__init__.py +++ b/lib/Pb/Grid/__init__.py @@ -22,7 +22,7 @@ class PbGrid(Pb): 'trim' : 'true' } def __init__(self, **kwargs ): - super(PbGrid,self).__init__(); + super(PbGrid,self).__init__(**kwargs); _definitions = { 'width': { 'type':'int' }, 'height': { 'type':'int' }, @@ -57,6 +57,8 @@ class PbGrid(Pb): else: self.filename, self.filepath = self._filename_filepath_create(extension=self.params.finalformat) + self._db_url_param = str(filter(lambda n: n, [ self.params.imageinstead, self.params.planebgimage, self.params.bgimage, "NULL"])[0]) + #makes a canvas file...step 1 (if not bgimage) def _make_canvas(self): dimensions = "{}x{}".format( diff --git a/lib/Pb/Landscape/__init__.py b/lib/Pb/Landscape/__init__.py index 33eedd6..cc1bcb0 100755 --- a/lib/Pb/Landscape/__init__.py +++ b/lib/Pb/Landscape/__init__.py @@ -6,13 +6,13 @@ import urlparse, re class PbLandscape(Pb): example_params = { - 'imgdata' : open('Pb/Landscape/_base64img', 'rb').read(), + 'imgdata' : open('lib/Pb/Landscape/_base64img', 'rb').read(), 'texture' : 'http://someurl.biz/someimg.jpg', 'heightmap' : 'http://someurl.biz/someimg.jpg', 'name' : 'donkey' } def __init__(self, **kwargs): - super(PbLandscape,self).__init__(); + super(PbLandscape,self).__init__(**kwargs); _definitions = { 'heightmap': {'type': 'string'} , 'imgdata': {'type': 'raw' } , @@ -22,6 +22,8 @@ class PbLandscape(Pb): self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__); _namepart = re.sub(r'https?:?/?/?', '', str(self.params.texture)) self.filename, self.filepath = self._filename_filepath_create(url=_namepart, extension="png") + + self._db_url_param = str(self.params.texture) def _saveImgData(self): try: diff --git a/lib/Pb/Pattern/__init__.py b/lib/Pb/Pattern/__init__.py index 4e4c5a8..930af64 100755 --- a/lib/Pb/Pattern/__init__.py +++ b/lib/Pb/Pattern/__init__.py @@ -20,7 +20,7 @@ class PbPattern(Pb): "image_url" : "http://i.asdf.us/im/be/PinkHijab_1425078647_reye.gif", } def __init__(self, **kwargs): - super(PbPattern,self).__init__(); + super(PbPattern,self).__init__(**kwargs); _definitions = { 'image_url': { 'type':'img_url' }, 'pattern_url': { 'type':'img_url' }, @@ -35,6 +35,8 @@ class PbPattern(Pb): elif not self.params.pattern_url: self.err_warn("pattern must be supplied as json array or as a png url") + self._db_url_param = str(self.params.image_url) + def _from_pattern_data(self): def boolToColor(boolean): if boolean: @@ -55,7 +57,7 @@ class PbPattern(Pb): #first step def _make_canvas(self): - _width, _height = self.dimensions(self.params.image_url['path']) # same here + _width, _height = self._dimensions(self.params.image_url['path']) # same here cmd = [BIN_CONVERT, "-size", _width + "x" + _height, "canvas:transparent", self.filepath] self._call_cmd(cmd) diff --git a/lib/Pb/__init__.py b/lib/Pb/__init__.py index 4d8a8d4..eab9878 100644 --- a/lib/Pb/__init__.py +++ b/lib/Pb/__init__.py @@ -1,27 +1,33 @@ import re from Config import * import time -import urllib -import urllib2 -import sys -import os +import urllib, urllib2 +import sys, os import random from subprocess import Popen,PIPE,call from Params import Params -import time +import sha + Request = urllib2.Request urlencode = urllib.urlencode urlopen = urllib2.urlopen _max_filename_length = 20; +class PbProcessError(Exception): + pass + class Pb(object): - def __init__(self): + def __init__(self, **kwargs): + self._input_kwargs = kwargs self._now = str(int(time.time())); self.params = Params(classname=self.__class__.__name__, now=self._now); self._files_created = [] self.commands = []; self._working_dir = WORKING_DIR + self._tag = self.__class__.__name__ + self._hashdir = None + self._db_url_param = "NULL" def _filename_create(self, url=None, namepart="", extension=""): if url: @@ -47,6 +53,9 @@ class Pb(object): _filename = self._filename_create(namepart=namepart, extension=extension) return self._filepath_create(_filename, directory=directory) + def _hashdir_create(self): + self._hashdir = sha.new(self.filename).hexdigest()[:2] + def _url_sanitize (self, s): return re.sub(r'\W+', '', s) @@ -58,28 +67,26 @@ class Pb(object): except Exception: raise Exception("Unable to call cmd {}".format(str(cmd))) + def _dimensions(self, filepath): + ident = (Popen([BIN_IDENTIFY, filepath], stdout=PIPE).communicate()[0]).split(" ") + return ident[2].split("x") - @staticmethod - def dimensions (filepath): - #works in lieu of a mimetype check (it reads the header as well) - ident = (Popen([BIN_IDENTIFY, filepath], stdout=PIPE).communicate()[0]).split(" ") - return ident[2].split("x") - + def file_dimensions (self): + return self._dimensions(self.filename) + def _width_and_height_set(self, filepath=None, width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT): if filepath: - self.width, self.height = Pb.dimensions(filepath) + self.width, self.height = self._dimensions(filepath) return self.width = width self.height = height - @staticmethod - def file_size (filepath): - try: - return os.stat(filepath)[6] - except Exception as e: - sys.stderr.write("Couldn't determine filesize\n") - sys.stderr.write(str(e)+"\n") - raise; + def file_size(self): + try: + return os.stat(self.filepath)[6] + except Exception as e: + self.err_warn("Couldn't determine filesize of %s\n" % self.filepath) + self.err_warn(str(e)) def _file_read(self, filepath): f = open(filepath, 'r'); @@ -89,14 +96,17 @@ class Pb(object): def err_warn(self, s): sys.stderr.write("ERROR:{} - {}\n".format(self.__class__.__name__, s)) - + raise PbProcessError + def _cleanup(self): - if not self._files_created: return - cmd = ["rm"]+self._files_created - self._call_cmd(cmd) + if not self._files_created: return + map(lambda n: os.remove(n), self._files_created) + + def _file_clean_local(self): + os.remove(self.filepath) def err_fatal(self, s): - sys.stderr.write("ERROR[FATAL]:{} - {}\n".format(self.__class__.__name__, s)) + sys.stderr.write("ERROR[FATAL]:%s - %s\n".format(self.__class__.__name__, s)) sys.exit(1); @classmethod @@ -113,18 +123,57 @@ class Pb(object): @staticmethod 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: - self.err_warn("couldn't get gif frames") - raise e; + 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: + self.err_warn("couldn't get gif frames") + raise e; def _choose_gif_frame(self, filepath): - _gif_frames = Pb.gif_frames(filepath) - frame = random.choice(_gif_frames) - self._call_cmd([BIN_CONVERT, frame, filepath]) + _gif_frames = Pb.gif_frames(filepath) + frame = random.choice(_gif_frames) + self._call_cmd([BIN_CONVERT, frame, filepath]) + + def db_send(self, remote_addr="NULL"): + try: + db.insert_cmd(**{ + 'date' : self._now, + 'remote_addr' : remote_addr, + 'username' : self.params.username or "NULL", + 'url' : self._db_url_param, + 'directory' : self._hashdir, + 'oldfile' : "NULL", #weird + 'newfile' : im.filename, + 'dataobj' : json.dumps(dict(self._input_kwargs)), + 'cmd' : ";".join(self.commands), + 'tag' : self._tag, + }) + except Exception as e: + self.err_warn("Problem sending to database") + + def file_s3move(self): + self._hashdir_create() + s3move(im.filepath, "im/{}/{}".format(self._hashdir, im.filename)) + self._files_created.append(self.filepath) + self._file_clean_local(); + + def file_json(self): + dimensions = self.file_dimensions(); + return json.dumps({ + 'url' : "im/%s/%s".format(BASE_URL, self._hashdir, self.filename), + 'size' : self.file_size(), + 'width' : "{}px".format(dimensions[0]), + 'height' : "{}px".format(dimensions[1]), + }) + +from Pb.Grid import PbGrid +from Pb.Break import PbBreak +from Pb.Pattern import PbPattern +from Pb.Generate import PbGenerate +from Pb.Landscape import PbLandscape +from Pb.Gradient import PbGradient diff --git a/pbserver.py b/pbserver.py deleted file mode 100755 index 530e54f..0000000 --- a/pbserver.py +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/python2.7 -from bottle import route, run, post, request, static_file - -from Pb.Gradient import Gradient -from Pb.Imgrid import Imgrid -from Pb.Breaker import Breaker -from Pb.Pattern import Pattern -from Pb.Generate import Generate -from Pb.Imlandscape import Imlandscape - -from Config import AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, BUCKET_NAME, BIN_IDENTIFY -from Pb import Pb -from Db import Db - -import os -import sys - -import sha -from subprocess import call, Popen, PIPE -import simplejson as json - -from boto.s3.connection import S3Connection -from boto.s3.key import Key -# -try: - db = Db(); -except Exception as e: - sys.stderr.write("Could not connect to db:\n{}".format(e)) - sys.exit(1); -BASE_URL = "http://i.asdf.us" - -def hashdir(filename): - return sha.new(filename).hexdigest()[:2] - -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]) - except Exception as e: - sys.stderr.write(str(e)) - raise - -def s3move(filename,objectname): - try: - conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, is_secure=False) - b = conn.get_bucket(BUCKET_NAME) - k = Key(b) - k.key = objectname - k.set_contents_from_filename(filename) - k.set_acl('public-read') - k.storage_class = 'REDUCED_REDUNDANCY' - except Exception as e: - sys.stderr.write(str(e)); - raise(e) - -def format_im_data(im, insert_url="NULL"): - directory = hashdir(im.filename) - dimensions = bin_identify(im.filepath) - size = Pb.file_size(im.filepath) - objectname = "im/{}/{}".format(directory, im.filename) - try: - s3move(im.filepath, objectname) - cleanup(im.filepath) - db.insert_cmd( - date=im._now, - remote_addr=request.environ.get('REMOTE_ADDR', "NULL"), - username=im.params.username or "NULL", - url=insert_url, - directory=directory, - oldfile="NULL", - newfile=im.filename, - dataobj=";".join(im.commands), - cmd=json.dumps(dict(im.params)), - tag=im.__class__.__name__, - ) - return json.dumps({ - 'url' : "{}/{}".format(BASE_URL, objectname), - 'size' : size, - 'width' : "{}px".format(dimensions[0]), - 'height' : "{}px".format(dimensions[1]), - }) - except Exception as e: - sys.stderr.write("Problem sending to database or s3\n") - sys.stderr.write(str(e)) - raise; - - -def return_image(im, insert_url="NULL"): - return format_im_data(im, insert_url) - - -def return_jsonp(im, insert_url="NULL"): - return "{}({})".format(im.get("callback"), format_im_data(im, insert_url)) - - -@post('/im/api/imgradient') -def gradient(): - try: - im = Gradient(**(dict(request.forms))) - im.create(); - return return_image(im) - except Exception as e: - sys.stderr.write("imgradient failure\n") - sys.stderr.write("params:\n") - for i in request.forms: - sys.stderr.write("{}:{}\n".format(i, request.forms[i])) - raise; - return json.dumps({ 'error' : 'Request could not be processed' }) - -@post('/im/api/imgrid') -def imgrid(): - try: - im = Imgrid(**(dict(request.forms))) - im.create(); - url= "NULL" - for elem in [ im.params.imageinstead , im.params.bgimage, im.params.planebgimage ]: - if elem: - url = elem['url'] - break - return return_image(im, url) - except Exception as e: - sys.stderr.write(str(e)) - return json.dumps({ 'error' : 'Request could not be processed' }) - -@post('/im/api/generate') -def generate(): - try: - im = Generate(**(dict(request.forms))) - im.create(); - return return_image(im) - except Exception as e: - sys.stderr.write(str(e)) - return json.dumps({ 'error' : 'Request could not be processed' }) - -@post('/im/api/imbreak') -def breaker(): - try: - im = Breaker(**(dict(request.forms))) - im.create(); - return return_image(im, im.params.url) - except Exception as e: - sys.stderr.write(str(e)) - return json.dumps({ 'error' : 'Request could not be processed' }) - -@post('/im/api/impattern') -def pattern(): - try: - im = Pattern(**(dict(request.forms))) - im.create(); - return return_image(im, im.params['image_url']) - except Exception as e: - sys.stderr.write(str(e)+"\n") - for i in request.forms: - sys.stderr.write("{}:{}\n".format(i, request.forms[i])) - raise; - return json.dumps({ 'error' : 'Request could not be processed' }) - -@post('/im/api/imlandscape') -def imlandscape(): - sys.stderr.write(str(dict(request.forms))) - try: - im = Imlandscape(**(dict(request.forms))) - im.create(); - sys.stderr.write(str(im.params)) - return return_image(im, im.params['texture']) - except Exception as e: - sys.stderr.write(str(e)) - return json.dumps({ 'error' : 'Request could not be processed' }) - - - -#static routes -@route('/im/<filename>') -def server_static(filename): - return static_file(filename, root='frontend/im/') -@route('/im') -def server_static(): - return static_file("index.html", root='frontend/im/') -@route('/imgrid') -def server_static(): - return static_file("index.html", root='frontend/imgrid/') -@route('/imgradient') -def server_static(): - return static_file("index.html", root='frontend/imgradient/') -@route('/imlandscape') -def server_static(): - return static_file("index.html", root='frontend/imlandscape/') -@route('/impattern') -def server_static(): - return static_file("index.html", root='frontend/impattern/') -@route('/imbreak') -def server_static(): - return static_file("index.html", root='frontend/imbreak/') -@route('/') -def server_static(): - return static_file("index.html", root='frontend/im/') -@route('/css/<filename>') -def server_static(filename): - return static_file(filename, root='frontend/css/') -@route('/js/<filename>') -def server_static(filename): - return static_file(filename, root='frontend/js/') -@route('/img/<filename>') -def server_static(filename): - return static_file(filename, root='frontend/img/') - - -run(host='0.0.0.0', server='flup', port=8999, debug=True) -#run(host='0.0.0.0', port=8999, debug=True) - - - diff --git a/run_examples.py b/run_examples.py new file mode 100644 index 0000000..ce07dcc --- /dev/null +++ b/run_examples.py @@ -0,0 +1,6 @@ +import sys +sys.path.append('./lib') +from Pb import * +for cls in Pb.__subclasses__(): + print cls.__name__ + cls.example_run() |
