diff options
| author | Pepper <pepper@scannerjammer.com> | 2015-09-26 04:14:44 -0400 |
|---|---|---|
| committer | Pepper <pepper@scannerjammer.com> | 2015-09-26 04:14:44 -0400 |
| commit | 4ebeb643da6419835e9ac3adb731e38a8ec9c7b4 (patch) | |
| tree | 4876b43410d67b62a238102ee98bf78f248fee78 | |
| parent | cc7fcec7ea718777f41154a107bdf8c709ed968a (diff) | |
reworked some more
| -rw-r--r-- | config.py | 2 | ||||
| -rw-r--r-- | examples/grid.sh | 3 | ||||
| -rw-r--r-- | examples/test.sh | 2 | ||||
| -rw-r--r-- | lib/param/enum.py | 2 | ||||
| -rw-r--r-- | lib/param/json.py | 3 | ||||
| -rw-r--r-- | lib/param/raw.py | 2 | ||||
| -rw-r--r-- | lib/params.py | 2 | ||||
| -rw-r--r-- | lib/pb/__init__.py | 311 | ||||
| -rwxr-xr-x | lib/pb/breaker.py | 110 | ||||
| -rwxr-xr-x | lib/pb/generate.py | 255 | ||||
| -rwxr-xr-x | lib/pb/gradient.py | 186 | ||||
| -rwxr-xr-x | lib/pb/grid.py | 127 | ||||
| -rwxr-xr-x | lib/pb/pattern.py | 30 | ||||
| -rw-r--r-- | lib/server.py | 38 | ||||
| -rw-r--r-- | run_module_examples.py | 9 | ||||
| -rw-r--r-- | run_server.py | 5 |
16 files changed, 579 insertions, 508 deletions
@@ -21,7 +21,7 @@ WORKING_DIR = "/var/www/cache" #server SERVER_HOST='0.0.0.0' -SERVER_PORT=8889 +SERVER_PORT=8999 #s3 AWS_ACCESS_KEY_ID = 'AKIAIR53VPBXKJMXZIBA' diff --git a/examples/grid.sh b/examples/grid.sh index da5fe41..d6d76e4 100644 --- a/examples/grid.sh +++ b/examples/grid.sh @@ -1 +1,2 @@ -curl localhost:8889/imgrid -H 'Cookie: imname=pepper' -H 'Origin: http://asdf.us' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: */*' -H 'Referer: http://asdf.us/imgrid/' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'width=700&height=500&linethickness=1&opacity=1&linecolor=MISTYROSE4&spacing=10&vlines=false&hlines=false&shadow=false&bgimage=&bgcolor=transparent&imageinstead=&planebgcolor=transparent&skycolor=none&planebgimage=&transition=background&swing=0&tilt=0&roll=0&zoom=0&trim=false&format=&username=pepper' --compressed +#curl localhost:8999/im/api/imgrid -H 'Cookie: imname=pepper' -H 'Origin: http://asdf.us' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: */*' -H 'Referer: http://asdf.us/imgrid/' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'width=700&height=500&linethickness=1&opacity=1&linecolor=MISTYROSE4&spacing=10&vlines=false&hlines=false&shadow=false&bgimage=&bgcolor=transparent&imageinstead=&planebgcolor=transparent&skycolor=none&planebgimage=&transition=background&swing=0&tilt=0&roll=0&zoom=0&trim=false&format=&username=pepper' --compressed +curl http://asdf.us/im/api/imgrid -H 'Cookie: imname=pepper' -H 'Origin: http://asdf.us' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: */*' -H 'Referer: http://asdf.us/imgrid/' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'width=700&height=500&linethickness=1&opacity=1&linecolor=MISTYROSE4&spacing=10&vlines=false&hlines=false&shadow=false&bgimage=&bgcolor=transparent&imageinstead=&planebgcolor=transparent&skycolor=none&planebgimage=&transition=background&swing=0&tilt=0&roll=0&zoom=0&trim=false&format=&username=pepper' --compressed diff --git a/examples/test.sh b/examples/test.sh new file mode 100644 index 0000000..860fc0f --- /dev/null +++ b/examples/test.sh @@ -0,0 +1,2 @@ +#curl localhost:8999/test +curl http://asdf.us/test diff --git a/lib/param/enum.py b/lib/param/enum.py index 067e0cd..49e11f6 100644 --- a/lib/param/enum.py +++ b/lib/param/enum.py @@ -3,6 +3,6 @@ import sys class Enum(Param): def __init__(self, value, enum_values=[], classname=""): super(Enum,self).__init__(classname=classname) - if value not in enum_values: + if value and value not in enum_values: return self.err_warn("Value %s not in enum values" % str(value)) self.value = value diff --git a/lib/param/json.py b/lib/param/json.py index 8d1a66e..af9b775 100644 --- a/lib/param/json.py +++ b/lib/param/json.py @@ -4,5 +4,4 @@ import simplejson as json class Json(Param): def __init__(self, value, classname=""): super(Json, self).__init__(classname=classname) - self.value = json.parse(value) - + self.value = json.loads(value) diff --git a/lib/param/raw.py b/lib/param/raw.py index 839f7e5..3d2f93f 100644 --- a/lib/param/raw.py +++ b/lib/param/raw.py @@ -3,4 +3,4 @@ from param import Param class Raw(Param): def __init__(self, value, classname=""): super(Raw, self).__init__(classname=classname) - self.value = value + self.value = value or None diff --git a/lib/params.py b/lib/params.py index 6db17d2..78a65eb 100644 --- a/lib/params.py +++ b/lib/params.py @@ -38,7 +38,7 @@ class Params(object): try: value = None if key in classkwargs: - value = classkwargs[key] + value = classkwargs[key] or def_dict[key].get('default', None) elif 'default' in def_dict[key]: value = def_dict[key]['default'] if def_dict[key]['type'] == "bool": diff --git a/lib/pb/__init__.py b/lib/pb/__init__.py index 29569c6..41b9155 100644 --- a/lib/pb/__init__.py +++ b/lib/pb/__init__.py @@ -1,10 +1,10 @@ import re from config import * -import time +import time import urllib, urllib2 import sys, os import random -from subprocess import Popen,PIPE,call +from subprocess import Popen, PIPE, call from params import Params import sha import simplejson as json @@ -16,182 +16,181 @@ Request = urllib2.Request urlencode = urllib.urlencode urlopen = urllib2.urlopen -_max_filename_length = 20; +_max_filename_length = 20 class PbProcessError(Exception): - pass + pass class Pb(object): - 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 = None + 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 = None - def _filename_create(self, url=None, namepart="", extension=""): - if url: - _basename = os.path.basename(url) - namepart = re.split(r'\.', _basename)[0] - namepart = self._url_sanitize(namepart)[0:_max_filename_length] - name = "" - if namepart: name += "%s-" % namepart - name += "%s_%s" % (self.__class__.__name__, self._now) - if self.params.username : name += "_%s" % self.params.username - if extension: name += ".%s" % extension - return name - - def _filepath_create(self, filename, directory=WORKING_DIR): - return os.path.join(directory, filename) + def _filename_create(self, url=None, namepart="", extension=""): + if url: + _basename = os.path.basename(url) + namepart = re.split(r'\.', _basename)[0] + namepart = self._url_sanitize(namepart)[0:_max_filename_length] + name = "" + if namepart: name += "%s-" % namepart + name += "%s_%s" % (self.__class__.__name__, self._now) + if self.params.username: name += "_%s" % self.params.username + if extension: name += ".%s" % extension + return name - def _filename_filepath_create(self, url=None, namepart="", directory=WORKING_DIR, extension=""): - _filename = self._filename_create(url=url, namepart=namepart, extension=extension); - _filepath = self._filepath_create(_filename, directory=directory); - return _filename, _filepath + def _filepath_create(self, filename, directory=WORKING_DIR): + return os.path.join(directory, filename) - def _tempfilepath_create(self, namepart="temp", directory=WORKING_DIR, extension=""): - _filename = self._filename_create(namepart=namepart, extension=extension) - return self._filepath_create(_filename, directory=directory) + def _filename_filepath_create(self, url=None, namepart="", directory=WORKING_DIR, extension=""): + _filename = self._filename_create(url=url, namepart=namepart, extension=extension) + _filepath = self._filepath_create(_filename, directory=directory) + return _filename, _filepath - def _hashdir_create(self): - self._hashdir = sha.new(self.filename).hexdigest()[:2] + def _tempfilepath_create(self, namepart="temp", directory=WORKING_DIR, extension=""): + _filename = self._filename_create(namepart=namepart, extension=extension) + return self._filepath_create(_filename, directory=directory) - def _url_sanitize (self, s): - return re.sub(r'\W+', '', s) + def _hashdir_create(self): + self._hashdir = sha.new(self.filename).hexdigest()[:2] - def _call_cmd(self, cmd): - try: - cmd = map(lambda i: str(i), cmd) - call(cmd) - self.commands.append(" ".join(cmd)); - except Exception: - raise Exception("Unable to call cmd {}".format(str(cmd))) + def _url_sanitize(self, s): + return re.sub(r'\W+', '', s) - def _dimensions(self, filepath): - try: - ident = (Popen([BIN_IDENTIFY, filepath], stdout=PIPE).communicate()[0]).split(" ") - return ident[2].split("x") - except Exception as e: - self.err_warn("Unable to get file dimensions:\n") - self.err_ward(str(e)) + def _call_cmd(self, cmd): + try: + cmd = map(lambda i: str(i), cmd) + call(cmd) + self.commands.append(" ".join(cmd)) + except Exception: + raise Exception("Unable to call cmd {}".format(str(cmd))) - def _file_dimensions (self): - self.file_width, self.file_height = self._dimensions(self.filepath) - - def _width_and_height_set(self, filepath=None, width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT): - if filepath: - self.width, self.height = self._dimensions(filepath) - return - self.width = width - self.height = height + def _dimensions(self, filepath): + try: + ident = (Popen([BIN_IDENTIFY, filepath], stdout=PIPE).communicate()[0]).split(" ") + return ident[2].split("x") + except Exception as e: + self.err_warn("Unable to get file dimensions:\n") + self.err_ward(str(e)) - def _file_size_get(self): - try: - self.file_size = 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_dimensions(self): + self.file_width, self.file_height = self._dimensions(self.filepath) - def _file_read(self, filepath): - f = open(filepath, 'r'); - data = f.read() - f.close() - return data + def _width_and_height_set(self, filepath=None, width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT): + if filepath: + self.width, self.height = self._dimensions(filepath) + return + self.width = width + self.height = height - 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 - map(lambda n: os.remove(n), self._files_created) - - def _file_clean_local(self): - os.remove(self.filepath) + def _file_size_get(self): + try: + self.file_size = 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 err_fatal(self, s): - sys.stderr.write("ERROR[FATAL]:%s - %s\n".format(self.__class__.__name__, s)) - sys.exit(1); - - @classmethod - def example_run(cls, params=None, verbose=True): - example_params = params or cls.example_params - if not example_params: - raise AttributeError ("Must supply test params to test %s" % cls.__name__) - b = cls(**example_params) - b.create(); - if verbose: - sys.stderr.write("generated %s\n" % b.filepath) - sys.stderr.write("files created %s\n" % b._files_created) - sys.stderr.write("commands:\n %s\n" % ";\n ".join(b.commands)) - return b + def _file_read(self, filepath): + f = open(filepath, 'r') + data = f.read() + f.close() + return data - @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; + def err_warn(self, s): + sys.stderr.write("ERROR:{} - {}\n".format(self.__class__.__name__, s)) + raise PbProcessError - def _choose_gif_frame(self, filepath): - _gif_frames = Pb.gif_frames(filepath) - frame = random.choice(_gif_frames) - self._call_cmd([BIN_CONVERT, frame, filepath]) + def _cleanup(self): + if not self._files_created: return + map(lambda n: os.remove(n), self._files_created) - def db_send(self, remote_addr=None, db_connection=None): - try: - db = db_connection or Db(); - except Exception as e: - sys.stderr.write("Could not connect to db:\n{}".format(e)) - sys.exit(1); - try: - - _insert_data = { - 'date' : self._now, - 'remote_addr' : remote_addr, - 'username' : str(self.params.username), - 'url' : self._db_url_param, - 'directory' : self._hashdir, - 'oldfile' : None, - 'newfile' : self.filename, - 'dataobj' : json.dumps(dict(self._input_kwargs)), - 'cmd' : "; ".join(self.commands), - 'tag' : self._tag, - } - db.insert_cmd(**_insert_data) - except Exception as e: - self.err_warn("Problem sending to database:\n %s" % str(e)) + def _file_clean_local(self): + os.remove(self.filepath) - def file_s3move(self): - self._hashdir_create() - s3cli = S3Cli() - s3cli.s3move(self.filepath, "im/{}/{}".format(self._hashdir, self.filename)) - self._file_clean_local(); - - def file_dict(self): - return { - 'url' : "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.filename), - 'size' : self.file_size, - 'width' : "%spx" % self.file_width, - 'height' : "%spx" % self.file_height, - } + def err_fatal(self, s): + sys.stderr.write("ERROR[FATAL]:%s - %s\n".format(self.__class__.__name__, s)) + sys.exit(1) - def create(self): - #base methods FIXME move into File class + @classmethod + def example_run(cls, params=None, verbose=True): + example_params = params or cls.example_params + if not example_params: + raise AttributeError("Must supply test params to test %s" % cls.__name__) + b = cls(**example_params) + b.create() + if verbose: + sys.stderr.write("generated %s\n" % b.filepath) + sys.stderr.write("files created %s\n" % b._files_created) + sys.stderr.write("commands:\n %s\n" % ";\n ".join(b.commands)) + return b - self._file_dimensions() - self._file_size_get() - self._cleanup(); + @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 + + def _choose_gif_frame(self, 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=None, db_connection=None): + try: + db = db_connection or Db() + except Exception as e: + sys.stderr.write("Could not connect to db:\n{}".format(e)) + sys.exit(1) + try: + + _insert_data = { + 'date' : self._now, + 'remote_addr' : remote_addr, + 'username' : str(self.params.username), + 'url' : self._db_url_param, + 'directory' : self._hashdir, + 'oldfile' : None, + 'newfile' : self.filename, + 'dataobj' : json.dumps(dict(self._input_kwargs)), + 'cmd' : "; ".join(self.commands), + 'tag' : self._tag, + } + db.insert_cmd(**_insert_data) + except Exception as e: + self.err_warn("Problem sending to database:\n %s" % str(e)) + + def file_s3move(self): + self._hashdir_create() + s3cli = S3Cli() + s3cli.s3move(self.filepath, "im/{}/{}".format(self._hashdir, self.filename)) + self._file_clean_local() + + def file_dict(self): + return { + 'url' : "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.filename), + 'size' : self.file_size, + 'width' : "%spx" % self.file_width, + 'height' : "%spx" % self.file_height, + } + + def create(self): + #base methods FIXME move into File class + self._file_dimensions() + self._file_size_get() + self._cleanup() from pb.grid import PbGrid from pb.breaker import PbBreaker diff --git a/lib/pb/breaker.py b/lib/pb/breaker.py index a38030a..a6f6c92 100755 --- a/lib/pb/breaker.py +++ b/lib/pb/breaker.py @@ -1,15 +1,11 @@ #!/usr/bin/python2.7 import os -import sys import random import re -import urllib -import inspect -from config import * +from config import BIN_CONVERT from pb import Pb -from params import Params -DEFAULT_FINALFORMAT = "png"; +DEFAULT_FINALFORMAT = "png" _subtle_break_mark = 'pron' _extreme_break_mark = 'sugar' @@ -17,7 +13,7 @@ _extreme_break_mark = 'sugar' _header_offset = 2000 _default_breakmode = "subtle" -class PbBreaker(Pb): #FIXME in db gallery +class PbBreaker(Pb): example_params = { "url" : "http://i.asdf.us/im/de/HolyMountain2_1322275112_seamonkey.gif", "breaktype" : "RGB_WASH", @@ -28,36 +24,42 @@ class PbBreaker(Pb): #FIXME in db gallery "expanded" : "false" } def __init__(self, **kwargs): - super(PbBreaker,self).__init__(**kwargs); + super(PbBreaker, self).__init__(**kwargs) _definitions = { - 'username': { 'type': 'string' }, - 'breaktype': { 'type': 'string' }, - 'breakmode': { - 'type': 'enum', - 'enum_values' : ['subtle', 'extreme', 'gradual'] , - 'default' : _default_breakmode - }, - 'breakangle': { 'type': 'float' }, - 'expanded': { 'type': 'bool' }, - 'url': { 'type': 'img_url' }, - 'finalformat': { 'type': 'enum', 'enum_values' : ['png', 'gif', 'jpg' ] } + 'username': {'type': 'string'}, + 'breaktype': {'type': 'string'}, + 'breakmode': { + 'type': 'enum', + 'enum_values' : ['subtle', 'extreme', 'gradual'], + 'default' : _default_breakmode + }, + 'breakangle': {'type': 'float'}, + 'expanded': {'type': 'bool'}, + 'url': {'type': 'img_url'}, + 'finalformat': {'type': 'enum', 'enum_values' : ['png', 'gif', 'jpg']} } - self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__); + self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__) self._files_created.append(self.params.url.path) self.params.breaktype.set_val(self._get_breaktype(str(self.params.breaktype))) - + #psd returns an animation if not self.params.finalformat and self.params.url.mimetype == "gif": - self.params.finalformat.set_val("gif") + self.params.finalformat.set_val("gif") elif self.params.breaktype == 'miff': - self.params.finalformat.set_val("jpg") - self.params.breakmode.set_val("subtle") + self.params.finalformat.set_val("jpg") + self.params.breakmode.set_val("subtle") elif not self.params.finalformat: - self.params.finalformat.set_val(DEFAULT_FINALFORMAT) - self._width_and_height_set(filepath=self.params.url.path) + self.params.finalformat.set_val(DEFAULT_FINALFORMAT) + self._width_and_height_set(filepath=self.params.url.path) - 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.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']) @@ -81,19 +83,23 @@ class PbBreaker(Pb): #FIXME in db gallery #}}} return breaktypeTranslate[key] -#{{{#########rotatefunctions####################################### +#{{{#########rotatefunctions###################################### def _rotate(self): - cmd = [BIN_CONVERT,self.params.url.path,"-rotate",self.params.breakangle,"+repage",self.params.url.path] - self._call_cmd(cmd) + cmd = [ + BIN_CONVERT, self.params.url.path, + "-rotate", self.params.breakangle, + "+repage", self.params.url.path + ] + self._call_cmd(cmd) def _rotate_back(self): angle = str(360-int(self.params.breakangle)) - cmd = [BIN_CONVERT,self.filepath,"-rotate",angle,"+repage",self.filepath] - self._call_cmd(cmd) + cmd = [BIN_CONVERT, self.filepath, "-rotate", angle, "+repage", self.filepath] + self._call_cmd(cmd) if not self.params.expanded: - cmd = [BIN_CONVERT,self.filepath,"-gravity","Center","-crop","{}x{}+0+0".format( - self.width, self.height),"+repage",self.filepath] - self._call_cmd(cmd) + cmd = [BIN_CONVERT, self.filepath, "-gravity", "Center", "-crop", "{}x{}+0+0".format( + self.width, self.height), "+repage", self.filepath] + self._call_cmd(cmd) #}}} def _subtle_break(self): @@ -105,21 +111,21 @@ class PbBreaker(Pb): #FIXME in db gallery self._file_data = newfile[0:len(self._file_data)] def _extreme_break(self): - increment = len(self._file_data)/10; + increment = len(self._file_data)/10 i = 0 - newfile = ""; + newfile = "" for b in self._file_data: - if i > _header_offset and not (i % increment): + if i > _header_offset and not i % increment: b += _extreme_break_mark newfile += b i += 1 self._file_data = newfile[0:len(self._file_data)] - def _enforce_jpg(self): - if self.params.breaktype in [ "exr", "bmp", "miff" ] and not re.match(r'jpe?g$', self.params.url.mimetype, re.IGNORECASE): + if self.params.breaktype in ["exr", "bmp", "miff"] and not \ + re.match(r'jpe?g$', self.params.url.mimetype, re.IGNORECASE): jpg_file = self._tempfilepath_create(extension="jpg") - self._call_cmd([BIN_CONVERT,self.params.url.path, jpg_file]) + self._call_cmd([BIN_CONVERT, self.params.url.path, jpg_file]) self._files_created.append(jpg_file) self._conversion_file = jpg_file @@ -131,16 +137,16 @@ class PbBreaker(Pb): #FIXME in db gallery self._files_created.append(self._conversion_file) def _prepare_filedata(self): - if self.params.url.mimetype == "gif" and self.params.breaktype not in [ 'mat', 'psd' ]: + if self.params.url.mimetype == "gif" and self.params.breaktype not in ['mat', 'psd']: self._choose_gif_frame(self.params.url.path) if self.params.breakangle: self._rotate() - self._enforce_jpg(); - self._first_conversion(); + self._enforce_jpg() + self._first_conversion() self._file_data = self._file_read(self._conversion_file) if not self._file_data: - self.err_warn("Unable to get file data"); - + self.err_warn("Unable to get file data") + def _add_false_data(self): if self.params.breakmode == "subtle": self._subtle_break() @@ -148,10 +154,10 @@ class PbBreaker(Pb): #FIXME in db gallery self._extreme_break() f = open(self._conversion_file, 'w') f.write(self._file_data) - f.close(); + f.close() def _final_conversion(self): - self._call_cmd( [BIN_CONVERT, self._conversion_file, self.filepath]) + self._call_cmd([BIN_CONVERT, self._conversion_file, self.filepath]) def psd_psbfilepath(num): return os.path.join(re.sub(r'\.', "-%s." % num, self.filepath)) if str(self.params.breaktype) == 'psd': @@ -164,8 +170,8 @@ class PbBreaker(Pb): #FIXME in db gallery self._rotate_back() def create(self): - self._prepare_filedata(); - self._add_false_data(); - self._final_conversion() + self._prepare_filedata() + self._add_false_data() + self._final_conversion() super(PbBreaker, self).create() diff --git a/lib/pb/generate.py b/lib/pb/generate.py index 088ca3c..12e3de1 100755 --- a/lib/pb/generate.py +++ b/lib/pb/generate.py @@ -5,136 +5,155 @@ from config import * from pb import Pb _default_tag = "im" -_gravity_params = ["NorthWest","North","NorthEast","West","Center","East","SouthWest","South","SouthEast"] +_gravity_params = [ + "NorthWest", "North", "NorthEast", "West", + "Center", "East", "SouthWest", "South", "SouthEast" +] _gravity_default = "Center" -_compose_params = [ "Over", "ATop", "Dst_Over", "Dst_In", "Dst_Out", "Multiply", - "Screen", "Divide", "Plus", "Difference", "Exclusion", - "Lighten", "Darken", "Overlay", "Hard_Light", "Soft_Light", - "Linear_Dodge", "Linear_Burn", "Color_Dodge", "Color_Burn" ] -_dispose_params = ["None","Previous","Background"] +_compose_params = [ + "Over", "ATop", "Dst_Over", "Dst_In", "Dst_Out", "Multiply", + "Screen", "Divide", "Plus", "Difference", "Exclusion", "Pin_Light", + "Lighten", "Darken", "Overlay", "Hard_Light", "Soft_Light", + "Linear_Dodge", "Linear_Burn", "Color_Dodge", "Color_Burn" +] +_dispose_params = ["None", "Previous", "Background"] _dispose_default = "None" class PbGenerate(Pb): - example_params = { #{{{ example params - 'nearest': 'true', - # 'height': None, - 'compose': 'Soft_Light', - 'coalesce': 'true', - 'dispose': 'None', - 'gravity': 'Center', - 'width': '200', - 'black': 'black', - 'tile': 'true', - 'white': 'white', - 'contrast': '100', - 'hue': '90', - 'saturation': '100', - 'merge_early': 'true', - 'format': 'gif', - 'background': 'http://i.asdf.us/im/bc/new_1430440747.gif', - 'subtract': '#EE7AE9', - 'transparent': 'true', - # 'rotate': None, - 'name': 'yo', - # 'brightness': None, - 'url': 'http://asdf.us/im/new.gif', - 'flop': 'true', - 'flip': 'false', - 'callback': 'jsonp1430442384162', - 'fuzz': '5' -#}}} + example_params = { + """Example params. Used with the classmethod Pb.run_example""" + 'nearest': 'true', + 'compose': 'Soft_Light', + 'coalesce': 'true', + 'dispose': 'None', + 'gravity': 'Center', + 'width': '200', + 'black': 'black', + 'tile': 'true', + 'white': 'white', + 'contrast': '100', + 'hue': '90', + 'saturation': '100', + 'merge_early': 'true', + 'format': 'gif', + 'background': 'http://i.asdf.us/im/bc/new_1430440747.gif', + 'subtract': '#EE7AE9', + 'transparent': 'true', + 'name': 'yo', + 'url': 'http://asdf.us/im/new.gif', + 'flop': 'true', + 'flip': 'false', + 'callback': 'jsonp1430442384162', + 'fuzz': '5' } - def __init__(self, **kwargs): - super(PbGenerate,self).__init__(**kwargs); - _definitions = { - #IMAGES - "url": { 'type': "img_url" }, - "background": { 'type': "img_url" }, +#}}} + def __init__(self, **kwargs): + super(PbGenerate, self).__init__(**kwargs) + _definitions = { + """ + Used to assert the value-types of the incoming parameters. + Types are defined as in their individual params classes. + """ + #IMAGES + "url": {'type': "img_url"}, + "background": {'type': "img_url"}, + + #BOOLS + "coalesce": {'type': "bool"}, + "nearest": {'type': "bool"}, + "merge_early": {'type': "bool"}, + "flip": {'type': "bool"}, + "flop": {'type': "bool"}, + "tile": {'type': "bool"}, + "transparent": {'type': "bool"}, - #BOOLS - "coalesce": { 'type': "bool" }, - "nearest": { 'type': "bool" }, - "merge_early": { 'type': "bool" }, - "flip": { 'type': "bool" }, - "flop": { 'type': "bool" }, - "tile": { 'type': "bool" }, - "transparent": { 'type': "bool" }, + #COLORS + "black": {'type': "color", 'default': 'black'}, + "white": {'type': "color", 'default': 'white'}, + "subtract": {'type': "color"}, - #COLORS - "black": { 'type': "color", 'default': 'black' }, - "white": { 'type': "color", 'default': 'white' }, - "subtract": { 'type': "color" }, + #INTS + "fuzz": {'type': "int"}, + "width": {'type': "int"}, + "height": {'type': "int"}, + "brightness": {'type': "int"}, + "contrast": {'type': "int"}, + "saturation": {'type': "int"}, + "rotate": {'type': "int"}, + "hue": {'type': "int"}, - #INTS - "fuzz": { 'type': "int" }, - "width": { 'type': "int" }, - "height": { 'type': "int" }, - "brightness": { 'type': "int" }, - "contrast": { 'type': "int" }, - "saturation": { 'type': "int" }, - "rotate": { 'type': "int" }, - "hue": { 'type': "int" }, - - #ENUMS - "compose": { 'type': "enum", 'enum_values': _compose_params, 'default': "Atop" }, - "gravity": { 'type': "enum", 'enum_values': _gravity_params, 'default': _gravity_default }, - "dispose": { 'type': "enum", 'enum_values': _dispose_params, 'default': "None" }, - "format": { 'type': "enum", 'enum_values': OUTPUT_IMAGE_TYPES, 'default': DEFAULT_FINALFORMAT }, + #ENUMS + "compose": {'type': "enum", 'enum_values': _compose_params, 'default': "Atop"}, + "gravity": {'type': "enum", 'enum_values': _gravity_params, 'default': _gravity_default}, + "dispose": {'type': "enum", 'enum_values': _dispose_params, 'default': "None"}, + "format": {'type': "enum", 'enum_values': OUTPUT_IMAGE_TYPES, 'default': DEFAULT_FINALFORMAT}, - #STRINGS - "username": { 'type': "string" }, - "callback": { 'type': "string" }, - } - self.tag = _default_tag - self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__); - if self.params.background: self.tag = self.params.compose - if self.params.transparent: self.tag = self.params.transparent + #STRINGS + "username": {'type': "string"}, + "callback": {'type': "string"}, + } - 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']) + + """Definitions and arguments are merged into attributes of the params object""" + self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__) + + """Used for the database tag column. Allows for tracking of the type + of overlay method used.""" + self.tag = _default_tag + if self.params.background: self.tag = self.params.compose + 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 = [ - BIN_CONVERT, self.params.background['path'], - "null:", self.filepath, "-matte", - "-dispose", self.params.dispose, - "-gravity", self.params.gravity, - "-compose", self.params.compose, "-layers", "composite", - self.filepath ] - self._call_cmd(cmd); + """Imagemagick composite command""" + cmd = [ + BIN_CONVERT, self.params.background['path'], + "null:", self.filepath, "-matte", + "-dispose", self.params.dispose, + "-gravity", self.params.gravity, + "-compose", self.params.compose, "-layers", "composite", + self.filepath + ] + self._call_cmd(cmd) def _convert(self): - cmd = [BIN_CONVERT, self.params.url['path'] ] - if self.params.rotate: cmd += ["-rotate", self.params.rotate ] - if self.params.flip: cmd += ["-flip"] - if self.params.flop: cmd += ["-flop"] - if self.params.transparent: - if self.params.fuzz: - cmd += ["-fuzz", "{}%".format(self.params.fuzz) ] - cmd += [ "-transparent", self.params.subtract ] - if self.params.width or self.params.height: - if self.params.nearest and self.params.format == "gif": - cmd += [ "-coalesce","+map","-interpolate","Nearest","-interpolative-resize" ] - else: - cmd.append("-resize") - cmd += [ "{}x{}".format(self.params.width or "", self.params.height or "") ] - if self.params.black != "black" or self.params.white != 'white': - cmd += [ "+level-colors" , "{},{}".format(self.params.black, self.params.white) ] - if self.params.contrast: cmd += [ '-contrast-stretch', self.params.contrast ] - if self.params.brightness or self.params.saturation or self.params.hue: - cmd += [ - "-modulate", "{},{},{}".format( - (self.params.brightness or 100), - (self.params.contrast or 100), - (self.params.hue or 100) - )] - cmd.append("-coalesce"); #why? #FIXME - cmd += [ self.filepath ]; - self._call_cmd(cmd); - + """Imagemagick convert command""" + cmd = [BIN_CONVERT, self.params.url['path']] + if self.params.rotate: cmd += ["-rotate", self.params.rotate] + if self.params.flip: cmd += ["-flip"] + if self.params.flop: cmd += ["-flop"] + if self.params.transparent: + if self.params.fuzz: + cmd += ["-fuzz", "{}%".format(self.params.fuzz)] + cmd += ["-transparent", self.params.subtract] + if self.params.width or self.params.height: + if self.params.nearest and self.params.format == "gif": + cmd += ["-coalesce","+map","-interpolate","Nearest","-interpolative-resize"] + else: + cmd.append("-resize") + cmd += ["{}x{}".format(self.params.width or "", self.params.height or "")] + if self.params.black != "black" or self.params.white != 'white': + cmd += ["+level-colors" , "{},{}".format(self.params.black, self.params.white)] + if self.params.contrast: cmd += ['-contrast-stretch', self.params.contrast] + if self.params.brightness or self.params.saturation or self.params.hue: + cmd += [ + "-modulate", "{},{},{}".format( + self.params.brightness or 100, + self.params.contrast or 100, + self.params.hue or 100 + ) + ] + cmd.append("-coalesce"); #why? #FIXME + cmd += [self.filepath] + self._call_cmd(cmd) + def create(self): - self._convert() - if self.params.background: - self._composite() - super(PbGenerate, self).create() + self._convert() + if self.params.background: + self._composite() + super(PbGenerate, self).create() diff --git a/lib/pb/gradient.py b/lib/pb/gradient.py index 22fe561..02d57d3 100755 --- a/lib/pb/gradient.py +++ b/lib/pb/gradient.py @@ -1,18 +1,11 @@ #!/usr/bin/python2.7
-import re
-import time
-from subprocess import call
-import simplejson as json
-import sys
-import os
-import sha
from config import *
from pb import Pb
_default_color_1 = "white"
_default_color_2 = "black"
-_default_bevel_percent = "12";
+_default_bevel_percent = "12"
_halftone_values = {
"checkeredfade": "h6x6a",
@@ -25,67 +18,71 @@ _halftone_values = { class PbGradient(Pb):
example_params = {
- "width" : "200",
- "color1" : "#ffdead",
- "color2" : "blue",
- "stripes" : "true",
- "stripenumber" : "20",
- "gradienttype" : "radial",
- "stripeintensity" : "20",
- "halftone" : "checkeredfade",
- "percentbeveled" : "30",
- "flip" : "true",
- "bevel" : "flatinner",
- "rotate" : "20",
- "height" : "200",
- "filetype" : "jpg",
- "username" : "whatever"
+ "width" : "200",
+ "color1" : "#ffdead",
+ "color2" : "blue",
+ "stripes" : "true",
+ "stripenumber" : "20",
+ "gradienttype" : "radial",
+ "stripeintensity" : "20",
+ "halftone" : "checkeredfade",
+ "percentbeveled" : "30",
+ "flip" : "true",
+ "bevel" : "flatinner",
+ "rotate" : "20",
+ "height" : "200",
+ "filetype" : "jpg",
+ "username" : "whatever"
}
def __init__(self, **kwargs):
- super(PbGradient,self).__init__(**kwargs);
+ super(PbGradient, self).__init__(**kwargs)
_definitions = {
- 'width': { 'type':'int', 'default': DEFAULT_WIDTH },
- 'height': { 'type':'int', 'default' : DEFAULT_HEIGHT },
- 'color1': { 'type':'color', 'default': _default_color_1 },
- 'color2': { 'type':'color', 'default': _default_color_2 },
- 'stripes': { 'type':'bool' },
- 'stripenumber': { 'type':'int', 'default': 0 },
- 'stripeintensity': { 'type':'int', 'default': 0 },
- 'blurriness': { 'type':'int', 'default': 0 },
- 'contrast': { 'type':'int', 'default': 100 },
- 'brightness': { 'type':'int', 'default': 100 },
- 'saturation': { 'type':'int', 'default': 100 },
- 'hue': { 'type':'int', 'default': 100 },
- 'halftone': { 'type':'enum', 'enum_values' : [
- 'checkeredfade', 'etchedtransition', 'bendaydots',
- 'smallerdots1', 'smallerdots2', 'flatstripes',
- ] },
- 'bevel': { 'type':'enum', 'enum_values' : [
- 'flatout', 'flatinner', 'evenlyframed', 'biginner',
- 'bigouter', 'dramaticflatout', 'dramaticflatinner',
- ] },
- 'percentbeveled': { 'type':'int', 'default': _default_bevel_percent },
- 'tilt': { 'type':'int' },
- 'rotate': { 'type':'int' },
- 'flip': { 'type':'bool' },
- 'flop': { 'type':'bool' },
- 'filetype': { 'type':'enum', 'enum_values' : OUTPUT_IMAGE_TYPES, 'default': DEFAULT_FINALFORMAT },
- 'gradienttype': { 'type':'enum', 'enum_values' : [
- 'default', 'canvas', 'radial', 'colorspace',
- 'mirrored', 'plasmawash', 'gradientwash', 'noise'
- ], 'default': 'default' },
- 'username': { 'type':'string' }
+ 'width': {'type':'int', 'default': DEFAULT_WIDTH},
+ 'height': {'type':'int', 'default' : DEFAULT_HEIGHT},
+ 'color1': {'type':'color', 'default': _default_color_1},
+ 'color2': {'type':'color', 'default': _default_color_2},
+ 'stripes': {'type':'bool'},
+ 'stripenumber': {'type':'int', 'default': 0},
+ 'stripeintensity': {'type':'int', 'default': 0},
+ 'blurriness': {'type':'int', 'default': 0},
+ 'contrast': {'type':'int', 'default': 100},
+ 'brightness': {'type':'int', 'default': 100},
+ 'saturation': {'type':'int', 'default': 100},
+ 'hue': {'type':'int', 'default': 100},
+ 'halftone': {'type':'enum', 'enum_values' : [
+ 'checkeredfade', 'etchedtransition', 'bendaydots',
+ 'smallerdots1', 'smallerdots2', 'flatstripes',
+ ]},
+ 'bevel': {'type':'enum', 'enum_values' : [
+ 'flatout', 'flatinner', 'evenlyframed', 'biginner',
+ 'bigouter', 'dramaticflatout', 'dramaticflatinner',
+ ]},
+ 'percentbeveled': {'type':'int', 'default': _default_bevel_percent},
+ 'tilt': {'type':'int'},
+ 'rotate': {'type':'int'},
+ 'flip': {'type':'bool'},
+ 'flop': {'type':'bool'},
+ 'filetype': {
+ 'type':'enum',
+ 'enum_values':OUTPUT_IMAGE_TYPES,
+ 'default': DEFAULT_FINALFORMAT
+ },
+ 'gradienttype': {'type':'enum', 'enum_values':[
+ 'gradient', 'canvas', 'radial', 'colorspace',
+ 'mirrored', 'plasmawash', 'gradientwash', 'noise'
+ ], 'default': 'gradient'},
+ 'username': {'type':'string'}
}
- self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__);
+ self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__)
self.filename, self.filepath = self._filename_filepath_create()
- def _filename_create(self, **kwargs):
+ def _filename_create(self):
_base = "{}{}-{}_{}".format(
- self.__class__.__name__,
- str(self.params.color1).replace('#','').replace('(','-').replace(')','-'),
- str(self.params.color2).replace('#','').replace('(','-').replace(')','-'),
- self._now,
+ self.__class__.__name__,
+ str(self.params.color1).replace('#', '').replace('(', '-').replace(')', '-'),
+ str(self.params.color2).replace('#', '').replace('(', '-').replace(')', '-'),
+ self._now,
)
if self.params.username: _base += "_%s" % self.params.username
return _base + ".%s" % self.params.filetype
@@ -95,20 +92,20 @@ class PbGradient(Pb): cmd = [BIN_CONVERT]
cmd.extend([
'-size',
- "{}x{}".format(self.params.width,self.params.height)
+ "{}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.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 = {
- "default" : "gradient:{}-{}".format(self.params.color1, self.params.color2),
+ "gradient" : ["gradient:{}-{}".format(self.params.color1, self.params.color2)],
"canvas" : ["canvas:{}".format(self.params.color1)],
"radial" : [
- "radial-gradient:{}-{}".format( self.params.color1, self.params.color2)
- ],
+ "radial-gradient:{}-{}".format(self.params.color1, self.params.color2)
+ ],
"colorspace" : [
"-colorspace",
"Gray",
@@ -116,7 +113,7 @@ class PbGradient(Pb): ],
"mirrored" : [
"plasma:{}-{}".format(self.params.color1, self.params.color2),
- "\(","+clone","-flop","\)",
+ "\(", "+clone", "-flop", "\)",
"append"
],
"plasmawash" : [
@@ -125,34 +122,35 @@ class PbGradient(Pb): ],
"gradientwash" : [
"gradient:{}-{}".format(self.params.color1, self.params.color2),
- "-set","colorspace","HSB"
+ "-set", "colorspace", "HSB"
],
"noise" : ["xc:","+noise","Random","-virtual-pixel","tile"]
}
cmd += _gradients[str(self.params.gradienttype)]
-
- if self.params.blurriness:
- cmd.extend(["-blur","0x{}".format(self.params.blurriness),"-auto-level"])
-
+
+ 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))
+ cmd.extend(["-function", "Sinusoid"])
+ if self.params.stripeintensity:
+ cmd.append("{},{}".format(self.params.stripenumber, self.params.stripeintensity))
else:
cmd.append(self.params.stripenumber)
- if str(self.params.halftone) in _halftone_values:
+ if str(self.params.halftone) in _halftone_values:
cmd.extend([
- "-ordered-dither",
+ "-ordered-dither",
_halftone_values[str(self.params.halftone)]
])
- cmd += [
- '-modulate',
+ cmd += [
+ '-modulate',
"{},{},{}".format(
- self.params.brightness or "100",
- self.params.saturation or "100",
- self.params.hue or "100")
+ self.params.brightness or "100",
+ self.params.saturation or "100",
+ self.params.hue or "100"
+ )
]
- cmd.append(self.filepath);
+ cmd.append(self.filepath)
self._call_cmd(cmd)
if self.params.bevel: self._make_bevel()
@@ -163,19 +161,19 @@ class PbGradient(Pb): else:
bevpercentval = str(int(self.params.percentbeveled)*0.005*int(w))
return {
- "flatout": ["-s",bevpercentval,"-m","outer"],
- "flatinner": ["-s",bevpercentval,"-m","inner"],
- "evenlyframed": ["-s ",bevpercentval,"-m", "split"],
- "biginner": ["-s",bevpercentval,"-m","outer","-c","50","-b","red","-a","25"],
- "bigouter": ["-s",bevpercentval,"-m","split","-c","50","-b","red","-a","25"],
- "dramaticflatout": ["-s",bevpercentval,"-m","outer","-a","25","-b","blue"],
- "dramaticflatinner": ["-s",bevpercentval,"-m","outer","-a","25","-b","blue"],
+ "flatout": ["-s", bevpercentval, "-m", "outer"],
+ "flatinner": ["-s", bevpercentval, "-m", "inner"],
+ "evenlyframed": ["-s ", bevpercentval, "-m", "split"],
+ "biginner": ["-s", bevpercentval, "-m", "outer", "-c", "50", "-b", "red", "-a", "25"],
+ "bigouter": ["-s", bevpercentval, "-m", "split", "-c", "50", "-b", "red", "-a", "25"],
+ "dramaticflatout": ["-s", bevpercentval, "-m", "outer", "-a", "25", "-b", "blue"],
+ "dramaticflatinner": ["-s", bevpercentval, "-m", "outer", "-a", "25", "-b", "blue"],
}[str(self.params.bevel)]
def _make_bevel(self):
cmd = [BEVELBORDER]
- cmd += self._get_bevelvalue()
- cmd += [ self.filepath, self.filepath]
+ cmd += self._get_bevelvalue()
+ cmd += [self.filepath, self.filepath]
self._call_cmd(cmd)
def create(self):
diff --git a/lib/pb/grid.py b/lib/pb/grid.py index 53d31df..0fafd1c 100755 --- a/lib/pb/grid.py +++ b/lib/pb/grid.py @@ -3,7 +3,8 @@ import re import os import simplejson as json import random -from config import DEFAULT_FINALFORMAT, DEFAULT_HEIGHT, DEFAULT_WIDTH, WORKING_DIR, OUTPUT_IMAGE_TYPES +from config import DEFAULT_FINALFORMAT, DEFAULT_HEIGHT,\ + DEFAULT_WIDTH, WORKING_DIR, OUTPUT_IMAGE_TYPES from config import THREEDROTATE, GRID, BIN_CONVERT, BIN_COMPOSITE import tempfile from pb import Pb @@ -22,53 +23,75 @@ class PbGrid(Pb): 'trim' : 'true' } def __init__(self, **kwargs ): - super(PbGrid,self).__init__(**kwargs); - _definitions = { - 'width': { 'type':'int' }, - 'height': { 'type':'int' }, - 'linethickness': { 'type':'int', 'default': 1 }, - 'opacity': { 'type':'float', "default": 1.0 }, - 'linecolor': { 'type':'color', 'default': 'whitesmoke' }, - 'linethickness': { 'type':'int' }, - 'spacing': { 'type':'int', 'default': 10 }, - 'vlines': { 'type':'bool' }, - 'hlines': { 'type':'bool' }, - 'shadow': { 'type':'bool' }, - 'bgimage': { 'type':'img_url' }, - 'bgcolor': { 'type':'color', 'default': 'transparent' }, - 'imageinstead': { 'type':'img_url' }, - 'planebgcolor': { 'type':'color', 'default': 'transparent' }, - 'planebgimage': { 'type':'img_url' }, - 'swing': { 'type':'int' }, - 'tilt': { 'type':'int' }, - 'roll': { 'type':'int' }, - 'zoom': { 'type':'int' }, - 'skycolor': { 'type':'color', 'default': 'transparent' }, - 'transition': { 'type':'enum', 'enum_values' : ['background', 'dither', 'edge', 'mirror', 'random', 'tile'], 'default': 'background' }, - 'trim': { 'type':'bool' }, - 'finalformat': { 'type':'enum', 'enum_values' : OUTPUT_IMAGE_TYPES, 'default': DEFAULT_FINALFORMAT }, - 'username': { 'type':'string' }, + super(PbGrid,self).__init__(**kwargs) + _definitions = { + 'width': {'type':'int'}, + 'height': {'type':'int'}, + 'linethickness': {'type':'int', 'default': 1}, + 'opacity': {'type':'float', "default": 1.0}, + 'linecolor': {'type':'color', 'default': 'whitesmoke'}, + 'linethickness': {'type':'int'}, + 'spacing': {'type':'int', 'default': 10}, + 'vlines': {'type':'bool'}, + 'hlines': {'type':'bool'}, + 'shadow': {'type':'bool'}, + 'bgimage': {'type':'img_url'}, + 'bgcolor': {'type':'color', 'default': 'transparent'}, + 'imageinstead': {'type':'img_url'}, + 'planebgcolor': {'type':'color', 'default': 'transparent'}, + 'planebgimage': {'type':'img_url'}, + 'swing': {'type':'int'}, + 'tilt': {'type':'int'}, + 'roll': {'type':'int'}, + 'zoom': {'type':'int'}, + 'skycolor': {'type':'color', 'default': 'transparent'}, + 'transition': { + 'type':'enum', + 'enum_values' :[ + 'background', 'dither', 'edge', 'mirror', 'random', 'tile' + ], + 'default': 'background' + }, + 'trim': {'type':'bool'}, + 'finalformat': { + 'type':'enum', + 'enum_values' :OUTPUT_IMAGE_TYPES, + 'default': DEFAULT_FINALFORMAT + }, + 'username': {'type':'string'}, } - self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__); + self.params.definitions_import( + _definitions, kwargs, classname=self.__class__.__name__ + ) if self.params.imageinstead: - self.filename, self.filepath = self._filename_filepath_create(url=self.params.imageinstead['url'], extension=self.params.finalformat) + self.filename, self.filepath = self._filename_filepath_create( + url=self.params.imageinstead['url'], extension=self.params.finalformat + ) elif self.params.planebgimage: - self.filename, self.filepath = self._filename_filepath_create(url=self.params.planebgimage['url'], extension=self.params.finalformat) + self.filename, self.filepath = self._filename_filepath_create( + url=self.params.planebgimage['url'], extension=self.params.finalformat + ) else: - self.filename, self.filepath = self._filename_filepath_create(extension=self.params.finalformat) + 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]) + 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( - self.params.width or DEFAULT_WIDTH, + self.params.width or DEFAULT_WIDTH, self.params.height or DEFAULT_HEIGHT ) if self.params.bgimage: - return + return bgcolor = "xc:{}".format(self.params.bgcolor or 'transparent') - cmd = [ BIN_CONVERT, "-size", dimensions, bgcolor, self.filepath ] + cmd = [BIN_CONVERT, "-size", dimensions, bgcolor, self.filepath] self._call_cmd(cmd) #2nd step-- run grid @@ -77,18 +100,18 @@ class PbGrid(Pb): if self.params.spacing: if self.params.vlines: width = 2 * int(self.params.width or DEFAULT_WIDTH) - cmd += ["-s","{},{}".format(self.params.spacing,width)] + cmd += ["-s", "{},{}".format(self.params.spacing, width)] elif self.params.hlines: height = 2 * int(self.params.height or DEFAULT_HEIGHT) - cmd += ["-s", "{},{}".format(height,self.params.spacing)] + cmd += ["-s", "{},{}".format(height, self.params.spacing)] else: - cmd += ["-s",self.params.spacing] + cmd += ["-s", self.params.spacing] cmd += [ "-c", self.params.linecolor or _default_line_color] - if self.params.linethickness: cmd += ['-t',self.params.linethickness] - if self.params.opacity: cmd += ['-o',self.params.opacity] + if self.params.linethickness: cmd += ['-t', self.params.linethickness] + if self.params.opacity: cmd += ['-o', self.params.opacity] cmd += [ self.filepath, self.filepath ] self._call_cmd(cmd) - + def _shadow_cmd(self): #convert 1.png \( +clone -background black -shadow 110x1+9+9 \) +swap -background none -layers merge +repage 2.png cmd = [ @@ -99,15 +122,15 @@ class PbGrid(Pb): self.filepath ] self._call_cmd(cmd) - - + + def _threed_rotate_cmd (self): #3rd step--run 3Drotate cmd = [THREEDROTATE] if self.params.swing: cmd += ["pan={}".format(self.params.swing)] if self.params.tilt: cmd += ["tilt={}".format(self.params.tilt)] if self.params.roll: cmd += ["roll={}".format(self.params.roll)] - if self.params.zoom: + if self.params.zoom: cmd += ["zoom={}".format(self.params.zoom)] if cmd == [THREEDROTATE]: #if nothing has been added return @@ -124,27 +147,27 @@ class PbGrid(Pb): def _trim_cmd (self): cmd = [BIN_CONVERT, self.filepath, "-trim", "+repage", self.filepath] self._call_cmd(cmd) - + def _prepare_gridimage(self, image): if image['mimetype'] == 'gif': - _frame = self._choose_gif_frame(image['path']) + _frame = self._choose_gif_frame(image['path']) if image['mimetype'] != 'png': cmd = [BIN_CONVERT, image['path'], self.filepath] else: cmd = ['cp', image['path'], self.filepath] self._call_cmd(cmd) - + def _overlay_planebgimage(self): - cmd = [ + cmd = [ BIN_COMPOSITE, - "-compose", "Dst_Over", "-gravity", "center", - self.params.planebgimage["path"], + "-compose", "Dst_Over", "-gravity", "center", + self.params.planebgimage["path"], self.filepath, self.filepath ] self._call_cmd(cmd) - + def create(self): if self.params.bgimage: self._prepare_gridimage(self.params.bgimage) @@ -157,5 +180,5 @@ class PbGrid(Pb): if self.params.shadow: self._shadow_cmd() self._threed_rotate_cmd() if self.params.planebgimage: self._overlay_planebgimage() - if self.params.trim: self._trim_cmd() + if self.params.trim: self._trim_cmd() super(PbGrid, self).create() diff --git a/lib/pb/pattern.py b/lib/pb/pattern.py index 040eb18..a9ab879 100755 --- a/lib/pb/pattern.py +++ b/lib/pb/pattern.py @@ -19,23 +19,33 @@ class PbPattern(Pb): # "username" : "garfield", "image_url" : "http://i.asdf.us/im/be/PinkHijab_1425078647_reye.gif", } + example_params = { + "username":"pepper", + "pattern_data":"", + "pattern_url":"http://asdf.us/impattern/patterns/63.png", + "image_url":"http://i.asdf.us/im/b4/PbGradientwhiteblack-PbGrid_1443161086_pepper.png", + + } def __init__(self, **kwargs): super(PbPattern,self).__init__(**kwargs); _definitions = { - 'image_url': { 'type':'img_url' }, - 'pattern_url': { 'type':'img_url' }, - 'pattern_data': { 'type':'raw' }, - 'username': { 'type':'string' }, + 'image_url': { 'type':'img_url' }, + 'pattern_url': { 'type':'img_url' }, + 'pattern_data': { 'type':'json' }, + 'username': { 'type':'string' }, } self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__); self.filename, self.filepath = self._filename_filepath_create(url=self.params.image_url['url'], extension=self.params.image_url['mimetype']) - _pattern_filename, self._pattern_filepath = self._filename_filepath_create(namepart="pattern") - - if self.params.pattern_data: self._from_pattern_data() + if self.params.pattern_data: + _pattern_filename, self._pattern_filepath = self._filename_filepath_create(namepart="pattern") + self._from_pattern_data() elif not self.params.pattern_url: self.err_warn("pattern must be supplied as json array or as a png url") + else: + self._pattern_filepath = self.params.pattern_url['path'] + + self._db_url_param = str(self.params.image_url.url) - self._db_url_param = str(self.params.image_url) def _from_pattern_data(self): def boolToColor(boolean): @@ -43,7 +53,7 @@ class PbPattern(Pb): return (0,0,0,255); else: return (255,255,255,255) - specs = json.loads(str(self.params.pattern_data)); + specs = self.params.pattern_data.value; if int(specs['width']) > 100 or int(specs['height']) > 100: raise ValueError sys.stderr.write("height and width need to be less than 100 px") @@ -51,7 +61,7 @@ class PbPattern(Pb): pixels = img.load(); for i in range(0, len(specs['matrix'])): for j in range(0, len(specs['matrix'][i])): - pixels[j,i] = boolToColor(int(specs['matrix'][i][j])); + pixels[j,i] = boolToColor(int(specs['matrix'][i][j])); img.save(self._pattern_filepath, "PNG") diff --git a/lib/server.py b/lib/server.py index e0f3140..8506c7a 100644 --- a/lib/server.py +++ b/lib/server.py @@ -1,10 +1,14 @@ from flask import Flask from flask import abort, redirect, url_for, request, jsonify -from cherrypy import wsgiserver + import sys, os +import cherrypy +from paste.translogger import TransLogger + sys.path.append("./lib") from pb import * from config import SERVER_HOST, SERVER_PORT +#http://flask.pocoo.org/docs/0.10/deploying/fastcgi/ this should be the one class InvalidUsage(Exception): status_code = 400 @@ -28,7 +32,7 @@ class Server(object): @self.app.route('/test', methods=['GET']) def test(): return "HELLO WORLD!" - @self.app.route('/<pb_classname>', methods=['POST']) + @self.app.route('/im/api/<pb_classname>', methods=['POST']) def pb(pb_classname): return self._response_post(pb_classname, request.form.to_dict()) @@ -41,7 +45,7 @@ class Server(object): self._classname_aliases = { 'generate' : 'PbGenerate', 'imgrid' : 'PbGrid', - 'imbreak' : 'PbBreak', + 'imbreak' : 'PbBreaker', 'impattern' : 'PbPattern', 'imgradient' : 'PbGradient', 'landscape' : 'PbLandscape', @@ -74,19 +78,31 @@ class Server(object): raise; return jsonify({ 'error' : 'Request could not be processed' }) - def run(self): - self.app.run() + def run(self, host=SERVER_HOST, port=SERVER_PORT): + self.app.run(host=host, port=port) + +#http://fgimian.github.io/blog/2012/12/08/setting-up-a-rock-solid-python-development-web-server/ def run_wsgi(self, server_port=SERVER_PORT, host=SERVER_HOST): - d = wsgiserver.WSGIPathInfoDispatcher({'/': self.app}) - sys.stderr.write("Starting a wsgi server on %s port %s\n" % (host, server_port)) - self._wsgi_server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', server_port), d) - self._wsgi_server.start() + # Enable WSGI access logging via Paste + app_logged = TransLogger(self.app) + + # Mount the WSGI callable object (app) on the root directory + cherrypy.tree.graft(app_logged, '/') + + # Set the configuration of the web server + cherrypy.config.update({ + 'engine.autoreload_on': True, + 'log.screen': True, + 'server.socket_port': server_port, + 'server.socket_host': host + }) + cherrypy.engine.start() + cherrypy.engine.block() + def stop(self): if self._wsgi_server: - self._wsgi_server.stop() - self._wsgi_server = None return else: return diff --git a/run_module_examples.py b/run_module_examples.py index 9a6ab10..050288a 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -3,7 +3,8 @@ sys.path.append('./lib') from pb import * for cls in Pb.__subclasses__(): print cls.__name__ - instance = cls.example_run() - instance.file_s3move() - print instance.file_dict() - instance.db_send(); + if cls.__name__ == 'PbPattern': + instance = cls.example_run() + instance.file_s3move() + print instance.file_dict() + instance.db_send(); diff --git a/run_server.py b/run_server.py index eaf3e0b..9d80e6c 100644 --- a/run_server.py +++ b/run_server.py @@ -5,8 +5,5 @@ from server import Server server = Server() if __name__ == "__main__": - try: - server.run_wsgi() - except KeyboardInterrupt: - server.stop() + server.run_wsgi() |
