From 46681c0088ac43d4d626e793d09583173f3c0ba7 Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 13:30:58 -0800 Subject: good first version works --- photoblaster/_file.py | 157 ++++++++++++++++++++++++ photoblaster/config.py | 2 +- photoblaster/modules/.ropeproject/globalnames | Bin 476 -> 494 bytes photoblaster/modules/base.py | 165 +++----------------------- photoblaster/modules/pbgenerate.py | 1 + photoblaster/modules/pbgradient.py | 158 +++++++++++++----------- run_module_examples.py | 4 +- 7 files changed, 264 insertions(+), 223 deletions(-) create mode 100644 photoblaster/_file.py diff --git a/photoblaster/_file.py b/photoblaster/_file.py new file mode 100644 index 0000000..3ab1afc --- /dev/null +++ b/photoblaster/_file.py @@ -0,0 +1,157 @@ +import os +import re +import random +import sha +import sys +import time +from photoblaster.s3.cli import S3Cli +from subprocess import Popen, PIPE +from photoblaster.config import WORKING_DIR, BIN_IDENTIFY, DEFAULT_WIDTH, \ + DEFAULT_HEIGHT, BIN_CONVERT, LOCAL, BASE_URL, DEFAULT_FINALFORMAT + +_MAX_FILENAME_LENGTH = 20 + + +class File(object): + def __init__( + self, + namepart="", + username="", + is_temp=False, + extension=DEFAULT_FINALFORMAT, + directory=WORKING_DIR + ): + self._is_temp = is_temp + self.extension = extension + self._directory = directory + self._filename = None + self._creation_time = str(int(time.time())) + self.set_filename( + namepart=namepart, + username=username + ) + self._hashdir = sha.new( + self.get_filepath() + ).hexdigest()[:2] + self._storage = "local" + + @classmethod + def from_url(cls, url, **kwargs): + """creates the filename from a url""" + _basename = os.path.basename(url) + namepart = re.split(r'\.', _basename)[0] + namepart = cls.url_sanitize(namepart)[0:_MAX_FILENAME_LENGTH] + kwargs[namepart] = namepart + return cls(**kwargs) + + def set_filename( + self, + namepart="", + username="" + ): + name = "" + if self._is_temp: + namepart = "temp" + if namepart: + name += "%s-" % namepart + name += "%s_%s" % (self.__class__.__name__, self.get_creation_time()) + if username: + name += "_%s" % username + if self.extension: + name += ".%s" % self.extension + self._filename = name + + def set_filepath( + self, + directory=WORKING_DIR + ): + """creates a local working path""" + if self._is_temp: + self.directory = WORKING_DIR + self.filepath = os.path.join(directory, self.get_filename()) + + def get_filepath(self): + return os.path.join(self._directory, self.get_filename()) + + def get_filename(self): + return self._filename + + @staticmethod + def url_sanitize(self, s): + return re.sub(r'\W+', '', s) + + def get_dimensions(self): + try: + ident = (Popen( + [BIN_IDENTIFY, self.get_filepath()], + stdout=PIPE).communicate()[0]).split(" ") + return ident[2].split("x") + except Exception as e: + sys.stderr.write("Unable to get file dimensions:\n") + sys.stderr.write("%s \n" % e) + + def get_raw_data(self): + f = open(self.get_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: + sys.stderr.write("couldn't get gif frames\n") + raise e + + def _choose_gif_frame(self): + _gif_frames = self.gif_frames(self.filepath) + frame = random.choice(_gif_frames) + self._call_cmd([BIN_CONVERT, frame, self.filepath]) + + def as_dict(self): + url = "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.get_filename()) + if self.get_storage() == "local": + url = "/im/cache/%s" % self.get_filename() + dimensions = self.get_dimensions() + return { + 'url': url, + 'size': self.get_size_in_bytes(), + 'width': "%spx" % dimensions[0], + 'height': "%spx" % dimensions[1], + } + + def s3move(self): + s3cli = S3Cli() + s3cli.s3move( + self.get_filepath(), "im/{}/{}".format( + self._hashdir, self.get_filename()) + ) + self._storage = "s3" + + def delete(self): + os.remove(self.get_filepath()) + self._storage = None + + def get_storage(self): + return self._storage + + def get_hashdir(self): + return self._hashdir + + def get_creation_time(self): + return self._creation_time + + def get_size_in_bytes(self): + try: + return os.stat(self.get_filepath())[6] + except Exception as e: + sys.stderr.write( + "Couldn't determine filesize of %s\n" % self.get_filepath()) + sys.stderr.write("%s\n" % e) diff --git a/photoblaster/config.py b/photoblaster/config.py index adaae8e..9e0bc4f 100644 --- a/photoblaster/config.py +++ b/photoblaster/config.py @@ -60,5 +60,5 @@ DB_PASSWORD = "gTYgT&M6q" DB_NAME = "asdfus" if LOCAL: DB_HOST = "localhost" - +BASE_URL = "http://i.asdf.us" diff --git a/photoblaster/modules/.ropeproject/globalnames b/photoblaster/modules/.ropeproject/globalnames index 6a68327..bf1ed49 100644 Binary files a/photoblaster/modules/.ropeproject/globalnames and b/photoblaster/modules/.ropeproject/globalnames differ diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index ada2504..14163f5 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -2,22 +2,11 @@ contains only the Pb class which is used by the Pb.* modules for inheritance """ -import re -from photoblaster.config import WORKING_DIR, BIN_CONVERT, BIN_IDENTIFY,\ - DEFAULT_HEIGHT, DEFAULT_WIDTH, LOCAL -import time import sys -import os -import random -from subprocess import Popen, PIPE, call +from subprocess import call from photoblaster.params import Params -import sha import simplejson as json -from photoblaster.s3.cli import S3Cli from photoblaster.db.models.imcmd import ImCmd -BASE_URL = "http://i.asdf.us" - -_MAX_FILENAME_LENGTH = 20 class PbProcessError(Exception): @@ -28,65 +17,16 @@ class Pb(object): """Base Pb class. USED ONLY FOR INHERITANCE""" 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.params = Params( + classname=self.__class__.__name__ + ) self._files_created = [] self.commands = [] - self._working_dir = WORKING_DIR self.tag = self.__class__.__name__ - self._hashdir = None self._db_url_param = None - # FIXME move to separate class - self.file_size = None self.width = None self.height = None - self.filename = None - self.filepath = None - self.file_height = None - self.file_width = 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_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 _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 _hashdir_create(self): - self._hashdir = sha.new(self.filename).hexdigest()[:2] - - def _url_sanitize(self, s): - return re.sub(r'\W+', '', s) def _call_cmd(self, cmd): try: @@ -96,44 +36,6 @@ class Pb(object): except Exception: raise Exception("Unable to call cmd {}".format(str(cmd))) - 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_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 _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_read(self, filepath): - f = open(filepath, 'r') - data = f.read() - f.close() - return data - def err_warn(self, s): sys.stderr.write("ERROR:{} - {}\n".format(self.__class__.__name__, s)) raise PbProcessError @@ -141,10 +43,7 @@ class Pb(object): 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) + map(lambda n: n.delete(), self._files_created) def err_fatal(self, s): sys.stderr.write("ERROR[FATAL]:%s - %s\n" % ( @@ -161,39 +60,25 @@ class Pb(object): b = cls(**example_params) b.create() if verbose: - sys.stderr.write("generated %s\n" % b.filepath) + sys.stderr.write("generated %s\n" % b.newfile.get_filepath()) sys.stderr.write("files created %s\n" % b._files_created) sys.stderr.write("commands:\n %s\n" % ";\n ".join(b.commands)) return b - @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: - Pb.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): + def db_send( + self, + remote_addr=None, + db_connection=None + ): try: _insert_data = { - 'date': self._now, + 'date': self.newfile.get_creation_time(), 'remote_addr': remote_addr, 'name': str(self.params.username), 'url': self._db_url_param, - 'dir': self._hashdir, + 'dir': self.newfile.get_hashdir(), 'oldfile': None, - 'newfile': self.filename, + 'newfile': self.newfile.get_filename(), 'dataobj': json.dumps(dict(self._input_kwargs)), 'cmd': "; ".join(self.commands), 'tag': self.tag, @@ -202,27 +87,5 @@ class Pb(object): 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): - url = "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.filename) - if LOCAL: - url = "/im/cache/%s" % self.filename - return { - 'url': url, - '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() diff --git a/photoblaster/modules/pbgenerate.py b/photoblaster/modules/pbgenerate.py index d857562..c034a6f 100755 --- a/photoblaster/modules/pbgenerate.py +++ b/photoblaster/modules/pbgenerate.py @@ -123,6 +123,7 @@ class PbGenerate(Pb): elif self.params.transparent: self.tag = "%s:%s" % (self.tag, "transparent") + self.newfile = File() self.filename, self.filepath = self._filename_filepath_create( url=self.params.url['url'], extension=self.params.format ) diff --git a/photoblaster/modules/pbgradient.py b/photoblaster/modules/pbgradient.py index 9b8ecaf..bf6bdd2 100755 --- a/photoblaster/modules/pbgradient.py +++ b/photoblaster/modules/pbgradient.py @@ -4,6 +4,7 @@ from photoblaster.config import DEFAULT_WIDTH, DEFAULT_HEIGHT,\ DEFAULT_FINALFORMAT, \ BIN_CONVERT, BEVELBORDER, OUTPUT_IMAGE_TYPES from photoblaster.modules import Pb +from photoblaster._file import File _DEFAULT_COLOR_1 = "white" _DEFAULT_COLOR_2 = "black" @@ -19,77 +20,79 @@ _halftone_values = { "flatstripes": "o2x2", } + class PbGradient(Pb): example_params = { - "width" : "200", - "color1" : "#ffdead", - "color2" : "blue", - "stripes" : "true", - "stripenumber" : "20", - "gradienttype" : "plasma", - "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": "plasma", + "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) _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' : [ + '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' : [ + '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'}, + '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':[ + 'gradienttype': {'type': 'enum', 'enum_values': [ 'gradient', 'canvas', 'plasma', 'radial', 'colorspace', 'mirrored', 'plasmawash', 'gradientwash', 'noise' ], 'default': 'gradient'}, - 'username': {'type':'string'} + 'username': {'type': 'string'} } - self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__) - - self.filename, self.filepath = self._filename_filepath_create() + self.params.definitions_import( + _definitions, kwargs, classname=self.__class__.__name__) - def _filename_create(self, **kwargs): - _base = "{}{}-{}_{}".format( + namepart = "%s%s-%s" % ( self.__class__.__name__, - str(self.params.color1).replace('#', '').replace('(', '-').replace(')', '-'), - str(self.params.color2).replace('#', '').replace('(', '-').replace(')', '-'), - self._now, + str(self.params.color1).replace( + '#', '').replace('(', '-').replace(')', '-'), + str(self.params.color2).replace( + '#', '').replace('(', '-').replace(')', '-') ) - if self.params.username: _base += "_%s" % self.params.username - return _base + ".%s" % self.params.filetype - + if self.params.username: + namepart += "_%s" % self.params.username + self.newfile = File(namepart=namepart, extension=self.params.filetype) def _build_cmd(self): cmd = [BIN_CONVERT] @@ -109,15 +112,18 @@ class PbGradient(Pb): if self.params.contrast: cmd.extend(["-contrast-stretch", str(self.params.contrast)]) _gradients = { - "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) + "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) ], - "plasma" : [ + "plasma": [ "plasma:{}-{}".format(self.params.color1, self.params.color2) ], - "colorspace" : [ + "colorspace": [ "-colorspace", "Gray", "plasma:{}-{}".format( @@ -125,7 +131,7 @@ class PbGradient(Pb): self.params.color2 ) ], - "mirrored" : [ + "mirrored": [ "plasma:{}-{}".format( self.params.color1, self.params.color2 @@ -133,26 +139,27 @@ class PbGradient(Pb): "(", "+clone", "-flop", ")", "+append" ], - "plasmawash" : [ + "plasmawash": [ "plasma:{}-{}".format( self.params.color1, self.params.color2 ), "-set", "colorspace", "HSB" ], - "gradientwash" : [ + "gradientwash": [ "gradient:{}-{}".format( self.params.color1, self.params.color2 ), "-set", "colorspace", "HSB" ], - "noise" : ["xc:", "+noise", "Random", "-virtual-pixel", "tile"] + "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"]) + cmd.extend( + ["-blur", "0x{}".format(self.params.blurriness), "-auto-level"]) if self.params.stripes and self.params.stripenumber: cmd.extend(["-function", "Sinusoid"]) @@ -177,32 +184,45 @@ class PbGradient(Pb): self.params.hue or "100" ) ] - cmd.append(self.filepath) - import sys - sys.stderr.write("\n%s\n" % cmd) + cmd.append(self.newfile.get_filepath()) self._call_cmd(cmd) - if self.params.bevel: self._make_bevel() + if self.params.bevel: + self._make_bevel() def _get_bevelvalue(self): w, h = map(int, (self.params.width, self.params.height)) if h >= w: - bevpercentval = str(int(int(self.params.percentbeveled)*int(h))/500) + bevpercentval = str( + int(int(self.params.percentbeveled)*int(h))/500) else: - bevpercentval = str(int(int(self.params.percentbeveled)*int(w))/500) + bevpercentval = str( + int(int(self.params.percentbeveled)*int(w))/500) 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"], + "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.newfile.get_filepath(), self.newfile.get_filepath()] self._call_cmd(cmd) def create(self): diff --git a/run_module_examples.py b/run_module_examples.py index 82d35ea..779a6e8 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -5,6 +5,6 @@ for cls in Pb.__subclasses__(): print cls.__name__ if cls.__name__ == "PbGradient": instance = cls.example_run() - instance.file_s3move() - print instance.file_dict() + print instance.newfile.as_dict() + instance.newfile.s3move() instance.db_send() -- cgit v1.2.3-70-g09d2 From 6f1d39fc12ce4a87dff5e1ac39fdab447e0ea68f Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 16:24:00 -0800 Subject: better --- photoblaster/_file.py | 8 +++++--- photoblaster/modules/base.py | 10 ++++++---- photoblaster/modules/pbgradient.py | 16 +++++++++------- run_module_examples.py | 4 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/photoblaster/_file.py b/photoblaster/_file.py index 3ab1afc..0a21d51 100644 --- a/photoblaster/_file.py +++ b/photoblaster/_file.py @@ -19,8 +19,10 @@ class File(object): username="", is_temp=False, extension=DEFAULT_FINALFORMAT, - directory=WORKING_DIR + directory=WORKING_DIR, + classname="pb" ): + self._classname = classname self._is_temp = is_temp self.extension = extension self._directory = directory @@ -52,9 +54,9 @@ class File(object): name = "" if self._is_temp: namepart = "temp" + name += "%s_%s" % (self._classname, self.get_creation_time()) if namepart: - name += "%s-" % namepart - name += "%s_%s" % (self.__class__.__name__, self.get_creation_time()) + name += "_%s" % namepart if username: name += "_%s" % username if self.extension: diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 14163f5..253ad16 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -25,6 +25,8 @@ class Pb(object): self.tag = self.__class__.__name__ self._db_url_param = None + self.output_file = None + self.width = None self.height = None @@ -60,7 +62,7 @@ class Pb(object): b = cls(**example_params) b.create() if verbose: - sys.stderr.write("generated %s\n" % b.newfile.get_filepath()) + sys.stderr.write("generated %s\n" % b.output_file.get_filepath()) sys.stderr.write("files created %s\n" % b._files_created) sys.stderr.write("commands:\n %s\n" % ";\n ".join(b.commands)) return b @@ -72,13 +74,13 @@ class Pb(object): ): try: _insert_data = { - 'date': self.newfile.get_creation_time(), + 'date': self.output_file.get_creation_time(), 'remote_addr': remote_addr, 'name': str(self.params.username), 'url': self._db_url_param, - 'dir': self.newfile.get_hashdir(), + 'dir': self.output_file.get_hashdir(), 'oldfile': None, - 'newfile': self.newfile.get_filename(), + 'newfile': self.output_file.get_filename(), 'dataobj': json.dumps(dict(self._input_kwargs)), 'cmd': "; ".join(self.commands), 'tag': self.tag, diff --git a/photoblaster/modules/pbgradient.py b/photoblaster/modules/pbgradient.py index bf6bdd2..b65412c 100755 --- a/photoblaster/modules/pbgradient.py +++ b/photoblaster/modules/pbgradient.py @@ -83,16 +83,18 @@ class PbGradient(Pb): self.params.definitions_import( _definitions, kwargs, classname=self.__class__.__name__) - namepart = "%s%s-%s" % ( - self.__class__.__name__, + namepart = "%s-%s" % ( str(self.params.color1).replace( '#', '').replace('(', '-').replace(')', '-'), str(self.params.color2).replace( '#', '').replace('(', '-').replace(')', '-') ) - if self.params.username: - namepart += "_%s" % self.params.username - self.newfile = File(namepart=namepart, extension=self.params.filetype) + self.output_file = File( + namepart=namepart, + extension=self.params.filetype, + classname=self.__class__.__name__, + username=self.params.username + ) def _build_cmd(self): cmd = [BIN_CONVERT] @@ -184,7 +186,7 @@ class PbGradient(Pb): self.params.hue or "100" ) ] - cmd.append(self.newfile.get_filepath()) + cmd.append(self.output_file.get_filepath()) self._call_cmd(cmd) if self.params.bevel: self._make_bevel() @@ -222,7 +224,7 @@ class PbGradient(Pb): def _make_bevel(self): cmd = [BEVELBORDER] cmd += self._get_bevelvalue() - cmd += [self.newfile.get_filepath(), self.newfile.get_filepath()] + cmd += [self.output_file.get_filepath(), self.output_file.get_filepath()] self._call_cmd(cmd) def create(self): diff --git a/run_module_examples.py b/run_module_examples.py index 779a6e8..54b8a30 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -5,6 +5,6 @@ for cls in Pb.__subclasses__(): print cls.__name__ if cls.__name__ == "PbGradient": instance = cls.example_run() - print instance.newfile.as_dict() - instance.newfile.s3move() + print instance.output_file.as_dict() + instance.output_file.s3move() instance.db_send() -- cgit v1.2.3-70-g09d2 From a77b7aa6bca2ed6104d7582aaea3ab349cccc24e Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 20:52:30 -0800 Subject: awesome --- photoblaster/_file.py | 23 +++++-- photoblaster/modules/base.py | 4 +- photoblaster/modules/pbbreaker.py | 76 +++++++++++++-------- photoblaster/modules/pbgrid.py | 138 +++++++++++++++++++++++--------------- photoblaster/param/img_url.py | 53 ++++++++++----- photoblaster/params.py | 18 +++-- run_module_examples.py | 2 +- 7 files changed, 199 insertions(+), 115 deletions(-) diff --git a/photoblaster/_file.py b/photoblaster/_file.py index 0a21d51..bd043b8 100644 --- a/photoblaster/_file.py +++ b/photoblaster/_file.py @@ -43,14 +43,18 @@ class File(object): _basename = os.path.basename(url) namepart = re.split(r'\.', _basename)[0] namepart = cls.url_sanitize(namepart)[0:_MAX_FILENAME_LENGTH] - kwargs[namepart] = namepart + kwargs["namepart"] = namepart return cls(**kwargs) def set_filename( self, namepart="", - username="" + username="", + filename=None ): + if filename: + self._filename = filename + return name = "" if self._is_temp: namepart = "temp" @@ -65,12 +69,17 @@ class File(object): def set_filepath( self, - directory=WORKING_DIR + directory=WORKING_DIR, + filepath=None ): """creates a local working path""" + if filepath: + self._filepath = filepath + self.set_filename(filename=os.path.basename(filepath)) + return if self._is_temp: self.directory = WORKING_DIR - self.filepath = os.path.join(directory, self.get_filename()) + self._filepath = os.path.join(directory, self.get_filename()) def get_filepath(self): return os.path.join(self._directory, self.get_filename()) @@ -79,7 +88,7 @@ class File(object): return self._filename @staticmethod - def url_sanitize(self, s): + def url_sanitize(s): return re.sub(r'\W+', '', s) def get_dimensions(self): @@ -113,9 +122,9 @@ class File(object): raise e def _choose_gif_frame(self): - _gif_frames = self.gif_frames(self.filepath) + _gif_frames = self.gif_frames(self._filepath) frame = random.choice(_gif_frames) - self._call_cmd([BIN_CONVERT, frame, self.filepath]) + self._call_cmd([BIN_CONVERT, frame, self._filepath]) def as_dict(self): url = "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.get_filename()) diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 253ad16..4d39266 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -43,6 +43,7 @@ class Pb(object): raise PbProcessError def _cleanup(self): + print self._files_created if not self._files_created: return map(lambda n: n.delete(), self._files_created) @@ -90,4 +91,5 @@ class Pb(object): self.err_warn("Problem sending to database:\n %s" % str(e)) def create(self): - self._cleanup() + pass + #self._cleanup() diff --git a/photoblaster/modules/pbbreaker.py b/photoblaster/modules/pbbreaker.py index e4c4665..4fa654f 100755 --- a/photoblaster/modules/pbbreaker.py +++ b/photoblaster/modules/pbbreaker.py @@ -4,6 +4,7 @@ import random import re from photoblaster.config import BIN_CONVERT from photoblaster.modules import Pb +from photoblaster._file import File DEFAULT_FINALFORMAT = "png" @@ -60,7 +61,7 @@ class PbBreaker(Pb): self.params.definitions_import(_definitions, kwargs, classname=self.__class__.__name__) - self._files_created.append(self.params.url.path) + self._files_created.append(self.params.url.get_file()) self.params.breaktype.set_val(self._get_breaktype( str(self.params.breaktype))) @@ -72,14 +73,19 @@ class PbBreaker(Pb): 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.width, self.height = self.params.url.get_file().get_dimensions() - self.filename, self.filepath = self._filename_filepath_create( - url=self.params.url.url, - extension=self.params.finalformat + self.output_file = File.from_url( + self.params.url.url, + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username ) - self._conversion_file = self._tempfilepath_create( + self._conversion_file = File( + is_temp=True, namepart="conversion", + classname=self.__class__.__name__, + username=self.params.username, extension=self.params.breaktype ) @@ -90,26 +96,27 @@ class PbBreaker(Pb): def _rotate(self): cmd = [ - BIN_CONVERT, self.params.url.path, + BIN_CONVERT, self.params.url.get_file().get_filepath(), "-rotate", self.params.breakangle, - "+repage", self.params.url.path + "+repage", self.params.url.get_file().get_filepath() ] 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.output_file.get_filepath(), + "-rotate", angle, "+repage", self.output_file.get_filepath()] self._call_cmd(cmd) if not self.params.expanded: cmd = [BIN_CONVERT, - self.filepath, + self.output_file.get_filepath(), "-gravity", "Center", "-crop", "{}x{}+0+0".format(self.width, self.height), "+repage", - self.filepath] + self.output_file.get_filepath()] self._call_cmd(cmd) def _subtle_break(self): @@ -133,11 +140,17 @@ class PbBreaker(Pb): 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): - jpg_file = self._tempfilepath_create(extension="jpg") - self._call_cmd([BIN_CONVERT, self.params.url.path, jpg_file]) + re.match( + r'jpe?g$', + self.params.url.mimetype, + re.IGNORECASE + ): + jpg_file = File( + is_temp=True, + extension="jpg", + ) + self._call_cmd( + [BIN_CONVERT, self.params.url.path, jpg_file.get_filepath()]) self._files_created.append(jpg_file) self._conversion_file = jpg_file @@ -146,19 +159,19 @@ class PbBreaker(Pb): self._conversion_file = self.params.url.path return self._call_cmd([BIN_CONVERT, - self.params.url.path, - self._conversion_file]) + self.params.url.get_file().get_filepath(), + self._conversion_file.get_filepath()]) 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']: + 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._file_data = self._file_read(self._conversion_file) + self._file_data = self._conversion_file.get_raw_data() if not self._file_data: self.err_warn("Unable to get file data") @@ -167,21 +180,30 @@ class PbBreaker(Pb): self._subtle_break() elif self.params.breakmode == "extreme": self._extreme_break() - f = open(self._conversion_file, 'w') + f = open(self._conversion_file.get_filepath(), 'w') f.write(self._file_data) f.close() def _final_conversion(self): - self._call_cmd([BIN_CONVERT, self._conversion_file, self.filepath]) + self._call_cmd([ + BIN_CONVERT, + self._conversion_file.get_filepath(), + self.output_file.get_filepath()]) def psd_psbfilepath(num): - return os.path.join(re.sub(r'\.', "-%s." % num, self.filepath)) + return os.path.join( + re.sub(r'\.', "-%s." % num, self.output_file.get_filepath()) + ) if str(self.params.breaktype) == 'psd': - self._call_cmd(['mv', psd_psbfilepath(1), self.filepath]) - self._files_created.append(psd_psbfilepath(0)) + self._call_cmd( + ['mv', psd_psbfilepath(1), self.output_file.get_filepath()]) + self.output_file.set_filepath(filepath=psd_psbfilepath(0)) + self._files_created.append(self.output_file) if str(self.params.breaktype) == 'psb': - self._call_cmd(['mv', psd_psbfilepath(0), self.filepath]) - self._files_created.append(psd_psbfilepath(1)) + self._call_cmd( + ['mv', psd_psbfilepath(0), self.output_file.get_filepath()]) + self.output_file.set_filepath(filepath=psd_psbfilepath(1)) + self._files_created.append(self.output_file) if self.params.breakangle: self._rotate_back() diff --git a/photoblaster/modules/pbgrid.py b/photoblaster/modules/pbgrid.py index 83950e6..cb4eefb 100755 --- a/photoblaster/modules/pbgrid.py +++ b/photoblaster/modules/pbgrid.py @@ -2,15 +2,18 @@ from photoblaster.config import DEFAULT_FINALFORMAT, DEFAULT_HEIGHT,\ DEFAULT_WIDTH, OUTPUT_IMAGE_TYPES,\ THREEDROTATE, GRID, BIN_CONVERT, BIN_COMPOSITE from photoblaster.modules import Pb +from photoblaster._file import File _DEFAULT_LINE_COLOR = "silver" + class PbGrid(Pb): """ Creates or overlays a grid on an image, and adds 3D perspective """ example_params = { - 'bgimage': 'http://i.asdf.us/im/1a/imBreak_1424909483_xx_abridged___.gif', + 'bgimage': + 'http://i.asdf.us/im/1a/imBreak_1424909483_xx_abridged___.gif', 'planebgimage': 'http://i.imgur.com/FICZtph.png', 'tilt': '30', 'spacing': '30', @@ -19,63 +22,75 @@ class PbGrid(Pb): 'shadow': 'true', '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'}, - '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':'float'}, - 'skycolor': {'type':'color', 'default': 'transparent'}, + 'width': {'type': 'int'}, + 'height': {'type': 'int'}, + 'linethickness': {'type': 'int', 'default': 1}, + 'opacity': {'type': 'float', "default": 1.0}, + 'linecolor': {'type': 'color', 'default': 'whitesmoke'}, + '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': 'float'}, + 'skycolor': {'type': 'color', 'default': 'transparent'}, 'transition': { - 'type':'enum', - 'enum_values' :[ + 'type': 'enum', + 'enum_values': [ 'background', 'dither', 'edge', 'mirror', 'random', 'tile' ], 'default': 'background' }, - 'trim': {'type':'bool'}, + 'trim': {'type': 'bool'}, 'finalformat': { - 'type':'enum', + 'type': 'enum', 'enum_values': OUTPUT_IMAGE_TYPES, 'default': DEFAULT_FINALFORMAT }, - 'username': {'type':'string'}, + 'username': {'type': 'string'}, } 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.output_file = File.from_url( + self.params.imageinstead['url'], + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username ) elif self.params.planebgimage: - self.filename, self.filepath = self._filename_filepath_create( - url=self.params.planebgimage['url'], extension=self.params.finalformat + self.output_file = File.from_url( + self.params.planebgimage['url'], + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username ) else: - self.filename, self.filepath = self._filename_filepath_create( - extension=self.params.finalformat + self.output_file = File( + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username ) self._db_url_param = str( filter( lambda n: n, [ - self.params.imageinstead, self.params.planebgimage, self.params.bgimage, "NULL" + self.params.imageinstead, + self.params.planebgimage, + self.params.bgimage, + "NULL" ] )[0] ) @@ -89,7 +104,9 @@ class PbGrid(Pb): if self.params.bgimage: return bgcolor = "xc:{}".format(self.params.bgcolor or 'transparent') - cmd = [BIN_CONVERT, "-size", dimensions, bgcolor, self.filepath] + cmd = [ + BIN_CONVERT, + "-size", dimensions, bgcolor, self.output_file.get_filepath()] self._call_cmd(cmd) #2nd step-- run grid @@ -109,7 +126,9 @@ class PbGrid(Pb): cmd += ['-t', self.params.linethickness] if self.params.opacity: cmd += ['-o', self.params.opacity] - cmd += [self.filepath, self.filepath] + cmd += [ + self.output_file.get_filepath(), + self.output_file.get_filepath()] self._call_cmd(cmd) def _shadow_cmd(self): @@ -120,55 +139,61 @@ class PbGrid(Pb): """ cmd = [ BIN_CONVERT, - self.filepath, - "(", "+clone", "-background", "black", "-shadow", "100x2+20+10", ")", + self.output_file.get_filepath(), + "(", + "+clone", "-background", "black", "-shadow", "100x2+20+10", ")", "+swap", "-background", "none", "-layers", "merge", "+repage", - self.filepath + self.output_file.get_filepath() ] self._call_cmd(cmd) - def _threed_rotate_cmd(self): - #3rd step--run 3Drotate + #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.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: cmd += ["zoom={}".format(self.params.zoom)] - if cmd == [THREEDROTATE]: #if nothing has been added + if cmd == [THREEDROTATE]: # if nothing has been added return if self.params.planebgcolor and not self.params.planebgimage: cmd += ["bgcolor={}".format(self.params.planebgcolor)] else: cmd += ["bgcolor=none"] cmd += ["skycolor={}".format(self.params.skycolor or 'none')] - if self.params.transition: cmd += ["vp={}".format(self.params.transition)] - cmd += [self.filepath, self.filepath] + if self.params.transition: + cmd += ["vp={}".format(self.params.transition)] + cmd += [ + self.output_file.get_filepath(), self.output_file.get_filepath()] self._call_cmd(cmd) - def _trim_cmd(self): - cmd = [BIN_CONVERT, self.filepath, "-trim", "+repage", self.filepath] + cmd = [ + BIN_CONVERT, + self.output_file.get_filepath(), + "-trim", "+repage", self.output_file.get_filepath()] self._call_cmd(cmd) def _prepare_gridimage(self, image): if image['mimetype'] == 'gif': _frame = self._choose_gif_frame(image['path']) if image['mimetype'] != 'png': - cmd = [BIN_CONVERT, image['path'], self.filepath] + cmd = [BIN_CONVERT, image['path'], self.output_file.get_filepath()] else: - cmd = ['cp', image['path'], self.filepath] + cmd = ['cp', image['path'], self.output_file.get_filepath()] self._call_cmd(cmd) - def _overlay_planebgimage(self): cmd = [ BIN_COMPOSITE, "-compose", "Dst_Over", "-gravity", "center", self.params.planebgimage["path"], - self.filepath, - self.filepath + self.output_file.get_filepath(), + self.output_file.get_filepath() ] self._call_cmd(cmd) @@ -181,8 +206,11 @@ class PbGrid(Pb): else: self._make_canvas() self._grid_command() - if self.params.shadow: self._shadow_cmd() + 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.planebgimage: + self._overlay_planebgimage() + if self.params.trim: + self._trim_cmd() super(PbGrid, self).create() diff --git a/photoblaster/param/img_url.py b/photoblaster/param/img_url.py index 27099eb..9285ecb 100644 --- a/photoblaster/param/img_url.py +++ b/photoblaster/param/img_url.py @@ -1,12 +1,12 @@ """Img_url param class definition lives here""" -import os from photoblaster.param import Param from photoblaster.config import MAX_SIZE, SPECIAL_DOWNLOADERS,\ SPECIAL_DOWNLOADERS_MAX_SIZE,\ BIN_IDENTIFY +from photoblaster._file import File import urllib2 from subprocess import Popen, PIPE -import sys + class Img_url(Param): def __init__(self, value, key="", classname=""): @@ -26,20 +26,19 @@ class Img_url(Param): """ super(Img_url, self).__init__(classname=classname) if value: - self.filename = self._filename_temporary(key) - - self.path = os.path.join(self._working_dir, self.filename) - self._image_download(value, self.path) - self.mimetype = self._image_mimetype(self.path) + self._file = File( + namepart=key, + classname=classname, + is_temp=True + ) + self._image_download(value) + self.mimetype = self._image_mimetype(self.get_filepath()) self.url = value - def _filename_temporary(self, s): - return "_tmp-{}-{}_{}".format(self._classname, self._now, s) - def __dict__(self): return { - 'filename' : self.filename, - 'path': self.path, + 'filename': self.get_filename(), + 'path': self.get_filepath(), 'url': self.url, 'mimetype': self.mimetype } @@ -53,15 +52,15 @@ class Img_url(Param): def __nonzero__(self): return True if self.path and self.mimetype else False - def _image_download(self, url, path): + def _image_download(self, url): """downloads the image to the path specified in the local filesystem""" max_size = MAX_SIZE if self.username in SPECIAL_DOWNLOADERS: max_size = SPECIAL_DOWNLOADERS_MAX_SIZE try: - self._download(url, path, max_size=max_size) - except Exception as e: + self._download(url, self.get_filepath(), max_size=max_size) + except Exception: self.err_warn("Download failed") def _browser_request(self, url, data=None): @@ -75,7 +74,8 @@ class Img_url(Param): response = urllib2.urlopen(req) except IOError as e: if hasattr(e, 'code'): - self.err_warn('browser request error: %s - ERROR %s' % (url, e.code)) + self.err_warn( + 'browser request error: %s - ERROR %s' % (url, e.code)) raise IOError return response @@ -97,11 +97,28 @@ class Img_url(Param): f.close() def _image_mimetype(self, f): - """retrieves the image mimetype from the file header using imagemagick""" + """ + retrieves the image mimetype from the file header using imagemagick + """ try: mimetype = Popen( [BIN_IDENTIFY, f], stdout=PIPE ).communicate()[0].split(" ")[1].lower() return mimetype - except Exception as e: + except Exception: self.err_warn("Couldn't determine mimetype") + + def delete(self): + self._file.delete() + + def get_filename(self): + return self._file.get_filename() + + def get_filepath(self): + return self._file.get_filepath() + + def get_file_dimensions(self): + return self._file.get_dimensions() + + def get_file(self): + return self._file diff --git a/photoblaster/params.py b/photoblaster/params.py index 74570aa..275f030 100644 --- a/photoblaster/params.py +++ b/photoblaster/params.py @@ -3,9 +3,11 @@ import sys from photoblaster.param import Bool, Color, Enum, Float, Int,\ Img_url, Json, Raw, String + class BadParamError(Exception): pass + class Params(object): """ Params is a collection of Param instances, @@ -23,18 +25,19 @@ class Params(object): def _error_log(self, s, error=None, fatal=False): message = "ERROR - BAD PARAM" - if fatal: message += "- [FATAL] -" + if fatal: + message += "- [FATAL] -" sys.stderr.write("{}:{} - {}\n".format(message, self._classname, s)) if error: sys.stderr.write("PARAM ERROR: {}\n".format(str(error))) def err_warn(self, s, error=None): - self._error_log(s, error=error); + self._error_log(s, error=error) raise BadParamError("%s - %s" % (self._classname, s)) def __getattr__(self, key): try: - return self.__getattribute__(key); + return self.__getattribute__(key) except AttributeError: return None @@ -46,7 +49,8 @@ class Params(object): for key in def_dict.keys(): value = None if key in classkwargs: - value = classkwargs.get(key, None) or def_dict[key].get('default', None) + value = classkwargs.get(key, None) or \ + def_dict[key].get('default', None) elif 'default' in def_dict[key]: value = def_dict[key]['default'] if def_dict[key]['type'] == "bool": @@ -54,7 +58,10 @@ class Params(object): elif def_dict[key]['type'] == "color": instance = Color(value, classname=classname) elif def_dict[key]['type'] == "enum": - instance = Enum(value, enum_values=def_dict[key]['enum_values'], classname=classname) + instance = Enum( + value, + enum_values=def_dict[key]['enum_values'], + classname=classname) elif def_dict[key]['type'] == "float": instance = Float(value, classname=classname) elif def_dict[key]['type'] == "img_url": @@ -68,4 +75,3 @@ class Params(object): elif def_dict[key]['type'] == "string": instance = String(value, classname=classname) self.__setattr__(key, instance) - diff --git a/run_module_examples.py b/run_module_examples.py index 54b8a30..4f99e9a 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -3,7 +3,7 @@ from photoblaster.modules import Pb for cls in Pb.__subclasses__(): print cls.__name__ - if cls.__name__ == "PbGradient": + if cls.__name__ == "PbBreaker": instance = cls.example_run() print instance.output_file.as_dict() instance.output_file.s3move() -- cgit v1.2.3-70-g09d2 From 04ab9aadccb96a60948eb272d8aa1ba46cc86a4a Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 20:54:57 -0800 Subject: awesome --- photoblaster/db/models/__init__.py | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/photoblaster/db/models/__init__.py b/photoblaster/db/models/__init__.py index bb3e496..a30383a 100644 --- a/photoblaster/db/models/__init__.py +++ b/photoblaster/db/models/__init__.py @@ -6,6 +6,7 @@ from sqlalchemy.sql.expression import func Base = declarative_base() + class Actions(object): @classmethod def create(cls, **kwargs): @@ -14,8 +15,6 @@ class Actions(object): session.add(cls(**kwargs)) session.commit() except: - #also took this pattern from the sqlalchemy docs to handle "rollback exceptions" - #should I show you the code that's causing the error now? yep session.rollback() raise finally: @@ -31,54 +30,34 @@ class Actions(object): except: session.rollback() raise -#what about update, how it's used? we should maybe look at the flush thing + def free(self): - #I tried creating this free method to help with these timeouts session = inspect(self).session session.close() SessionHeap.remove() - + @classmethod def _search(cls, **kwargs): session = Session() - print "session()" query = session.query(cls).filter_by(**kwargs) session.close() return query try: session.commit() except: - print "session.rollback()" session.rollback() raise finally: - print "session.close()" session.close() SessionHeap.remove() return query -# def _search(cls, **kwargs): -# session = SessionHeap() -# print "session()" -# query = session.query(cls).filter_by(**kwargs) -# try: -# session.commit() -# except: -# print "session.rollback()" -# session.rollback() -# raise -# finally: -# print "session.close()" -# session.close() -# SessionHeap.remove() -# return query -# + @classmethod def search_random(cls, **kwargs): return cls._search(**kwargs).order_by(func.rand()) @classmethod def search(cls, **kwargs): - #something with this maybe? is it creating an extra session instance? because it seems like return cls._search(**kwargs).order_by(desc(cls.id)) @classmethod -- cgit v1.2.3-70-g09d2 From bbc58ea395a62bb5e27a377f73ce586db7296d64 Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 21:26:05 -0800 Subject: ok even better --- photoblaster/modules/base.py | 8 ++++++- photoblaster/modules/pbbreaker.py | 45 ++++++++++++++++++++++++-------------- photoblaster/modules/pbgradient.py | 17 ++++++++------ 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 4d39266..86cc8dc 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -25,7 +25,7 @@ class Pb(object): self.tag = self.__class__.__name__ self._db_url_param = None - self.output_file = None + self._output_file = None self.width = None self.height = None @@ -93,3 +93,9 @@ class Pb(object): def create(self): pass #self._cleanup() + + def get_output_file(self): + return self._output_file + + def set_output_file(self, output_file): + self._output_file = output_file diff --git a/photoblaster/modules/pbbreaker.py b/photoblaster/modules/pbbreaker.py index 4fa654f..94bfb3c 100755 --- a/photoblaster/modules/pbbreaker.py +++ b/photoblaster/modules/pbbreaker.py @@ -75,11 +75,12 @@ class PbBreaker(Pb): self.params.finalformat.set_val(DEFAULT_FINALFORMAT) self.width, self.height = self.params.url.get_file().get_dimensions() - self.output_file = File.from_url( - self.params.url.url, - extension=self.params.finalformat, - classname=self.__class__.__name__, - username=self.params.username + self.set_output_file( + File.from_url( + self.params.url.url, + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username) ) self._conversion_file = File( is_temp=True, @@ -105,18 +106,19 @@ class PbBreaker(Pb): def _rotate_back(self): angle = str(360-int(self.params.breakangle)) cmd = [BIN_CONVERT, - self.output_file.get_filepath(), - "-rotate", angle, "+repage", self.output_file.get_filepath()] + self.get_output_file().get_filepath(), + "-rotate", angle, "+repage", + self.get_output_file().get_filepath()] self._call_cmd(cmd) if not self.params.expanded: cmd = [BIN_CONVERT, - self.output_file.get_filepath(), + self.get_output_file().get_filepath(), "-gravity", "Center", "-crop", "{}x{}+0+0".format(self.width, self.height), "+repage", - self.output_file.get_filepath()] + self.get_output_file().get_filepath()] self._call_cmd(cmd) def _subtle_break(self): @@ -188,22 +190,31 @@ class PbBreaker(Pb): self._call_cmd([ BIN_CONVERT, self._conversion_file.get_filepath(), - self.output_file.get_filepath()]) + self.get_output_file().get_filepath()]) def psd_psbfilepath(num): return os.path.join( - re.sub(r'\.', "-%s." % num, self.output_file.get_filepath()) + re.sub( + r'\.', "-%s." % num, self.get_output_file().get_filepath()) ) if str(self.params.breaktype) == 'psd': self._call_cmd( - ['mv', psd_psbfilepath(1), self.output_file.get_filepath()]) - self.output_file.set_filepath(filepath=psd_psbfilepath(0)) - self._files_created.append(self.output_file) + [ + 'mv', psd_psbfilepath(1), + self.get_output_file().get_filepath() + ] + ) + self._output_file.set_filepath(filepath=psd_psbfilepath(0)) + self._files_created.append(self.get_output_file()) if str(self.params.breaktype) == 'psb': self._call_cmd( - ['mv', psd_psbfilepath(0), self.output_file.get_filepath()]) - self.output_file.set_filepath(filepath=psd_psbfilepath(1)) - self._files_created.append(self.output_file) + [ + 'mv', + psd_psbfilepath(0), + self.get_output_file().get_filepath() + ]) + self._output_file.set_filepath(filepath=psd_psbfilepath(1)) + self._files_created.append(self.get_output_file()) if self.params.breakangle: self._rotate_back() diff --git a/photoblaster/modules/pbgradient.py b/photoblaster/modules/pbgradient.py index b65412c..fe885b5 100755 --- a/photoblaster/modules/pbgradient.py +++ b/photoblaster/modules/pbgradient.py @@ -89,11 +89,12 @@ class PbGradient(Pb): str(self.params.color2).replace( '#', '').replace('(', '-').replace(')', '-') ) - self.output_file = File( - namepart=namepart, - extension=self.params.filetype, - classname=self.__class__.__name__, - username=self.params.username + self.set_output_file( + File( + namepart=namepart, + extension=self.params.filetype, + classname=self.__class__.__name__, + username=self.params.username) ) def _build_cmd(self): @@ -186,7 +187,7 @@ class PbGradient(Pb): self.params.hue or "100" ) ] - cmd.append(self.output_file.get_filepath()) + cmd.append(self.get_output_file().get_filepath()) self._call_cmd(cmd) if self.params.bevel: self._make_bevel() @@ -224,7 +225,9 @@ class PbGradient(Pb): def _make_bevel(self): cmd = [BEVELBORDER] cmd += self._get_bevelvalue() - cmd += [self.output_file.get_filepath(), self.output_file.get_filepath()] + cmd += [ + self.get_output_file().get_filepath(), + self.get_output_file().get_filepath()] self._call_cmd(cmd) def create(self): -- cgit v1.2.3-70-g09d2 From dae34ec90053189eccaa03707f216f7ad3264e84 Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Tue, 1 Mar 2016 21:29:05 -0800 Subject: ok wrapping it up --- photoblaster/modules/base.py | 10 +++++----- run_module_examples.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 86cc8dc..71c1bec 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -43,7 +43,6 @@ class Pb(object): raise PbProcessError def _cleanup(self): - print self._files_created if not self._files_created: return map(lambda n: n.delete(), self._files_created) @@ -63,7 +62,8 @@ class Pb(object): b = cls(**example_params) b.create() if verbose: - sys.stderr.write("generated %s\n" % b.output_file.get_filepath()) + sys.stderr.write( + "generated %s\n" % b.get_output_file().get_filepath()) sys.stderr.write("files created %s\n" % b._files_created) sys.stderr.write("commands:\n %s\n" % ";\n ".join(b.commands)) return b @@ -75,13 +75,13 @@ class Pb(object): ): try: _insert_data = { - 'date': self.output_file.get_creation_time(), + 'date': self.get_output_file().get_creation_time(), 'remote_addr': remote_addr, 'name': str(self.params.username), 'url': self._db_url_param, - 'dir': self.output_file.get_hashdir(), + 'dir': self.get_output_file().get_hashdir(), 'oldfile': None, - 'newfile': self.output_file.get_filename(), + 'newfile': self.get_output_file().get_filename(), 'dataobj': json.dumps(dict(self._input_kwargs)), 'cmd': "; ".join(self.commands), 'tag': self.tag, diff --git a/run_module_examples.py b/run_module_examples.py index 4f99e9a..882de78 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -5,6 +5,6 @@ for cls in Pb.__subclasses__(): print cls.__name__ if cls.__name__ == "PbBreaker": instance = cls.example_run() - print instance.output_file.as_dict() - instance.output_file.s3move() + print instance.get_output_file().as_dict() + instance.get_output_file().s3move() instance.db_send() -- cgit v1.2.3-70-g09d2 From 9e13bba17a2539266f2690f115388ac9598043c9 Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Wed, 2 Mar 2016 07:17:50 -0800 Subject: ready for review --- photoblaster/_file.py | 11 ++-- photoblaster/modules/.ropeproject/globalnames | Bin 494 -> 482 bytes photoblaster/modules/pbbreaker.py | 2 +- photoblaster/modules/pbgenerate.py | 21 ++++--- photoblaster/modules/pbgrid.py | 72 +++++++++++++--------- photoblaster/modules/pblandscape/__init__.py | 17 ++++-- photoblaster/modules/pbpattern.py | 83 +++++++++++++++++--------- photoblaster/param/img_url.py | 2 +- run_module_examples.py | 2 +- 9 files changed, 135 insertions(+), 75 deletions(-) diff --git a/photoblaster/_file.py b/photoblaster/_file.py index bd043b8..b370bb4 100644 --- a/photoblaster/_file.py +++ b/photoblaster/_file.py @@ -5,7 +5,7 @@ import sha import sys import time from photoblaster.s3.cli import S3Cli -from subprocess import Popen, PIPE +from subprocess import Popen, PIPE, call from photoblaster.config import WORKING_DIR, BIN_IDENTIFY, DEFAULT_WIDTH, \ DEFAULT_HEIGHT, BIN_CONVERT, LOCAL, BASE_URL, DEFAULT_FINALFORMAT @@ -121,10 +121,13 @@ class File(object): sys.stderr.write("couldn't get gif frames\n") raise e - def _choose_gif_frame(self): - _gif_frames = self.gif_frames(self._filepath) + def choose_gif_frame(self, module=None): + _gif_frames = self.gif_frames(self.get_filepath()) frame = random.choice(_gif_frames) - self._call_cmd([BIN_CONVERT, frame, self._filepath]) + cmd = [BIN_CONVERT, frame, self.get_filepath()] + call(cmd) + if module: + module.commands.append(" ".join(cmd)) def as_dict(self): url = "%s/im/%s/%s" % (BASE_URL, self._hashdir, self.get_filename()) diff --git a/photoblaster/modules/.ropeproject/globalnames b/photoblaster/modules/.ropeproject/globalnames index bf1ed49..795a9f6 100644 Binary files a/photoblaster/modules/.ropeproject/globalnames and b/photoblaster/modules/.ropeproject/globalnames differ diff --git a/photoblaster/modules/pbbreaker.py b/photoblaster/modules/pbbreaker.py index 94bfb3c..d282513 100755 --- a/photoblaster/modules/pbbreaker.py +++ b/photoblaster/modules/pbbreaker.py @@ -168,7 +168,7 @@ class PbBreaker(Pb): def _prepare_filedata(self): if self.params.url.mimetype == "gif" and\ self.params.breaktype not in ['mat', 'psd']: - self._choose_gif_frame(self.params.url.path) + self.params.url.get_file().choose_gif_frame(module=self) if self.params.breakangle: self._rotate() self._enforce_jpg() diff --git a/photoblaster/modules/pbgenerate.py b/photoblaster/modules/pbgenerate.py index c034a6f..1dd264b 100755 --- a/photoblaster/modules/pbgenerate.py +++ b/photoblaster/modules/pbgenerate.py @@ -2,6 +2,7 @@ from photoblaster.config import BIN_CONVERT, OUTPUT_IMAGE_TYPES,\ DEFAULT_FINALFORMAT from photoblaster.modules import Pb +from photoblaster._file import File _GRAVITY_PARAMS = [ "NorthWest", "North", "NorthEast", "West", @@ -123,9 +124,13 @@ class PbGenerate(Pb): elif self.params.transparent: self.tag = "%s:%s" % (self.tag, "transparent") - self.newfile = File() - self.filename, self.filepath = self._filename_filepath_create( - url=self.params.url['url'], extension=self.params.format + self.set_output_file( + File.from_url( + self.params.url['url'], + username=self.params.username, + classname=self.__class__.__name__, + extension=self.params.format + ) ) self._db_url_param = str(self.params.url['url']) @@ -133,18 +138,18 @@ class PbGenerate(Pb): def _composite(self): """Imagemagick composite command""" cmd = [ - BIN_CONVERT, self.params.background['path'], - "null:", self.filepath, "-matte", + BIN_CONVERT, self.params.background.get_file().get_filepath(), + "null:", self.get_output_file().get_filepath(), "-matte", "-dispose", self.params.dispose, "-gravity", self.params.gravity, "-compose", self.params.compose, "-layers", "composite", - self.filepath + self.get_output_file().get_filepath() ] self._call_cmd(cmd) def _convert(self): """Imagemagick convert command""" - cmd = [BIN_CONVERT, self.params.url['path']] + cmd = [BIN_CONVERT, self.params.url.get_file().get_filepath()] if self.params.rotate: cmd += ["-rotate", self.params.rotate] if self.params.flip: @@ -185,7 +190,7 @@ class PbGenerate(Pb): ) ] cmd.append("-coalesce") # why? FIXME - cmd += [self.filepath] + cmd += [self.get_output_file().get_filepath()] self._call_cmd(cmd) def create(self): diff --git a/photoblaster/modules/pbgrid.py b/photoblaster/modules/pbgrid.py index cb4eefb..c43c4b1 100755 --- a/photoblaster/modules/pbgrid.py +++ b/photoblaster/modules/pbgrid.py @@ -20,6 +20,7 @@ class PbGrid(Pb): 'hlines': 'true', 'roll': '30', 'shadow': 'true', + 'username': 'someuser', 'trim': 'true' } @@ -64,24 +65,27 @@ class PbGrid(Pb): _definitions, kwargs, classname=self.__class__.__name__ ) if self.params.imageinstead: - self.output_file = File.from_url( - self.params.imageinstead['url'], - extension=self.params.finalformat, - classname=self.__class__.__name__, - username=self.params.username + self.set_output_file( + File.from_url( + self.params.imageinstead['url'], + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username) ) elif self.params.planebgimage: - self.output_file = File.from_url( - self.params.planebgimage['url'], - extension=self.params.finalformat, - classname=self.__class__.__name__, - username=self.params.username + self.set_output_file( + File.from_url( + self.params.planebgimage['url'], + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username) ) else: - self.output_file = File( - extension=self.params.finalformat, - classname=self.__class__.__name__, - username=self.params.username + self.set_output_file( + File( + extension=self.params.finalformat, + classname=self.__class__.__name__, + username=self.params.username) ) self._db_url_param = str( @@ -106,7 +110,8 @@ class PbGrid(Pb): bgcolor = "xc:{}".format(self.params.bgcolor or 'transparent') cmd = [ BIN_CONVERT, - "-size", dimensions, bgcolor, self.output_file.get_filepath()] + "-size", dimensions, bgcolor, + self.get_output_file().get_filepath()] self._call_cmd(cmd) #2nd step-- run grid @@ -127,8 +132,8 @@ class PbGrid(Pb): if self.params.opacity: cmd += ['-o', self.params.opacity] cmd += [ - self.output_file.get_filepath(), - self.output_file.get_filepath()] + self.get_output_file().get_filepath(), + self.get_output_file().get_filepath()] self._call_cmd(cmd) def _shadow_cmd(self): @@ -139,11 +144,11 @@ class PbGrid(Pb): """ cmd = [ BIN_CONVERT, - self.output_file.get_filepath(), + self.get_output_file().get_filepath(), "(", "+clone", "-background", "black", "-shadow", "100x2+20+10", ")", "+swap", "-background", "none", "-layers", "merge", "+repage", - self.output_file.get_filepath() + self.get_output_file().get_filepath() ] self._call_cmd(cmd) @@ -168,32 +173,40 @@ class PbGrid(Pb): if self.params.transition: cmd += ["vp={}".format(self.params.transition)] cmd += [ - self.output_file.get_filepath(), self.output_file.get_filepath()] + self.get_output_file().get_filepath(), + self.get_output_file().get_filepath()] self._call_cmd(cmd) def _trim_cmd(self): cmd = [ BIN_CONVERT, - self.output_file.get_filepath(), - "-trim", "+repage", self.output_file.get_filepath()] + self.get_output_file().get_filepath(), + "-trim", "+repage", self.get_output_file().get_filepath()] self._call_cmd(cmd) def _prepare_gridimage(self, image): if image['mimetype'] == 'gif': - _frame = self._choose_gif_frame(image['path']) + image.get_file().choose_gif_frame(module=self) if image['mimetype'] != 'png': - cmd = [BIN_CONVERT, image['path'], self.output_file.get_filepath()] + cmd = [ + BIN_CONVERT, + image.get_file().get_filepath(), + self.get_output_file().get_filepath()] else: - cmd = ['cp', image['path'], self.output_file.get_filepath()] + cmd = [ + 'cp', image.get_file().get_filepath(), + self.output_file.get_filepath()] self._call_cmd(cmd) def _overlay_planebgimage(self): + import sys + sys.stderr.write("should be overlaying here!\n\n\n") cmd = [ BIN_COMPOSITE, "-compose", "Dst_Over", "-gravity", "center", self.params.planebgimage["path"], - self.output_file.get_filepath(), - self.output_file.get_filepath() + self.get_output_file().get_filepath(), + self.get_output_file().get_filepath() ] self._call_cmd(cmd) @@ -210,7 +223,12 @@ class PbGrid(Pb): self._shadow_cmd() self._threed_rotate_cmd() if self.params.planebgimage: + import sys + sys.stderr.write("what the fuck!!!") self._overlay_planebgimage() + else: + import sys + sys.stderr.write("UMMMMMMMMMMMMMMMMMM\n") if self.params.trim: self._trim_cmd() super(PbGrid, self).create() diff --git a/photoblaster/modules/pblandscape/__init__.py b/photoblaster/modules/pblandscape/__init__.py index b03dce0..3044b3b 100755 --- a/photoblaster/modules/pblandscape/__init__.py +++ b/photoblaster/modules/pblandscape/__init__.py @@ -2,7 +2,7 @@ import base64 from photoblaster.modules import Pb import urlparse import re - +from photoblaster._file import File class PbLandscape(Pb): try: @@ -28,11 +28,15 @@ class PbLandscape(Pb): _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" + namepart = re.sub(r'https?:?/?/?', '', str(self.params.texture)) + self.set_output_file( + File( + namepart=namepart, + classname=self.__class__.__name__, + extension="png", + username=self.params.username + ) ) - self._db_url_param = str(self.params.texture) def _saveImgData(self): @@ -43,7 +47,8 @@ class PbLandscape(Pb): # Do something smart with charset and b64 instead of assuming plaindata = base64.b64decode(data) - with open(self.filepath, 'wb') as f: + with open( + self.get_output_file().get_filepath(), 'wb') as f: f.write(plaindata) except Exception as e: self.err_warn(str(e)) diff --git a/photoblaster/modules/pbpattern.py b/photoblaster/modules/pbpattern.py index ccf6963..1e80647 100755 --- a/photoblaster/modules/pbpattern.py +++ b/photoblaster/modules/pbpattern.py @@ -1,39 +1,54 @@ from photoblaster.config import BIN_CONVERT, BIN_COMPOSITE from photoblaster.modules import Pb from PIL import Image +from photoblaster._file import File + +_FUSE_MODE = "Pin_Light" -_FUSE_MODE="Pin_Light" class PbPattern(Pb): example_params = { - "pattern_data" : '{"matrix":[["0","0","0","0","0","1","0","0","0","0"],["0","0","0","0","1","1","1","0","0","0"],["0","0","1","1","1","0","1","0","0","0"],["0","1","1","0","0","0","0","0","0","0"],["0","1","0","0","1","0","0","0","0","0"],["0","1","0","0","1","0","0","0","1","0"],["0","1","0","0","1","1","0","0","1","0"],["0","1","0","0","0","1","1","1","1","0"],["0","1","1","1","1","0","0","0","0","0"],["0","0","0","0","1","0","0","0","0","0"]],"width":"10","height":"10"}', - "image_url" : "http://i.asdf.us/im/be/PinkHijab_1425078647_reye.gif", -# "username" : "garfield", -# "pattern_url" : "http://asdf.us/impattern/patterns/1.png", + "pattern_data": '{"matrix":[["0","0","0","0","0","1","0","0","0","0"],["0","0","0","0","1","1","1","0","0","0"],["0","0","1","1","1","0","1","0","0","0"],["0","1","1","0","0","0","0","0","0","0"],["0","1","0","0","1","0","0","0","0","0"],["0","1","0","0","1","0","0","0","1","0"],["0","1","0","0","1","1","0","0","1","0"],["0","1","0","0","0","1","1","1","1","0"],["0","1","1","1","1","0","0","0","0","0"],["0","0","0","0","1","0","0","0","0","0"]],"width":"10","height":"10"}', + #"username": "garfield", + #"pattern_url": "http://asdf.us/impattern/patterns/1.png", + "image_url": "http://i.asdf.us/im/be/PinkHijab_1425078647_reye.gif", } + def __init__(self, **kwargs): super(PbPattern, self).__init__(**kwargs) _definitions = { - 'image_url': {'type':'img_url'}, - 'pattern_url': {'type':'img_url'}, - 'pattern_data': {'type':'json'}, - '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'] + self.params.definitions_import( + _definitions, kwargs, classname=self.__class__.__name__) + self.set_output_file( + File.from_url( + self.params.image_url['url'], + extension=self.params.image_url['mimetype'], + classname=self.__class__.__name__, + username=self.params.username + ) ) + self.pattern_file = None if self.params.pattern_data: - _pattern_filename, self._pattern_filepath = self._filename_filepath_create(namepart="pattern") + self.pattern_file = File( + namepart="pattern", + username=self.params.username, + classname=self.__class__.__name__, + extension="png" + ) 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") + 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.pattern_file = self.params.pattern_url.get_file() self._db_url_param = str(self.params.image_url.url) - def _from_pattern_data(self): def boolToColor(boolean): if boolean: @@ -48,34 +63,48 @@ class PbPattern(Pb): 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])) - - img.save(self._pattern_filepath, "PNG") + img.save(self.pattern_file.get_filepath(), "PNG") #first step def _make_canvas(self): - _width, _height = self._dimensions(self.params.image_url['path']) # same here - cmd = [BIN_CONVERT, "-size", _width + "x" + _height, "canvas:transparent", self.filepath] + _width, _height = self.params.image_url.get_file().get_dimensions() + cmd = [ + BIN_CONVERT, "-size", _width + "x" + _height, + "canvas:transparent", + self.get_output_file().get_filepath()] self._call_cmd(cmd) #second step use the Canvas as a background def _make_mask(self): #tile the pattern pattern on the canvas - cmd = [BIN_COMPOSITE, "-tile", self._pattern_filepath, self.filepath, self.filepath] + cmd = [ + BIN_COMPOSITE, "-tile", self.pattern_file.get_filepath(), + self.get_output_file().get_filepath(), + self.get_output_file().get_filepath()] self._call_cmd(cmd) #fuse the tiled file to create a mask - #convert thebg.gif -compose Dst_In null: thefile.gif -matte -layers composite new.gif + #convert thebg.gif -compose Dst_In null: \ + #thefile.gif -matte -layers composite new.gif cmd = [ - BIN_CONVERT, self.filepath, "-compose", "Dst_In", "null:", - self.params.image_url['path'], "-matte", "-layers", "composite", self.filepath + BIN_CONVERT, + self.get_output_file().get_filepath(), + "-compose", "Dst_In", "null:", + self.params.image_url.get_file().get_filepath(), + "-matte", "-layers", "composite", + self.get_output_file().get_filepath() + ] self._call_cmd(cmd) #third step def _fuse_mask(self, fuse_mode=_FUSE_MODE): cmd = [ - BIN_CONVERT, "-dispose", "2", self.filepath, "null:", - self.params.image_url['path'], "-matte", "-compose", fuse_mode, "-layers", "composite", - self.filepath + BIN_CONVERT, "-dispose", "2", + self.get_output_file().get_filepath(), + "null:", + self.params.image_url.get_file().get_filepath(), + "-matte", "-compose", fuse_mode, "-layers", "composite", + self.get_output_file().get_filepath() ] self._call_cmd(cmd) diff --git a/photoblaster/param/img_url.py b/photoblaster/param/img_url.py index 9285ecb..a6227e1 100644 --- a/photoblaster/param/img_url.py +++ b/photoblaster/param/img_url.py @@ -50,7 +50,7 @@ class Img_url(Param): return str(self.__dict__()) def __nonzero__(self): - return True if self.path and self.mimetype else False + return True if self.get_file() and self.mimetype else False def _image_download(self, url): """downloads the image to the path specified in the local diff --git a/run_module_examples.py b/run_module_examples.py index 882de78..3c0e29a 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -3,7 +3,7 @@ from photoblaster.modules import Pb for cls in Pb.__subclasses__(): print cls.__name__ - if cls.__name__ == "PbBreaker": + if cls.__name__ == "PbLandscape": instance = cls.example_run() print instance.get_output_file().as_dict() instance.get_output_file().s3move() -- cgit v1.2.3-70-g09d2 From 0621b7f7ab757d2b4df7fd2496f2bbf39b7cf313 Mon Sep 17 00:00:00 2001 From: Pepper Date: Wed, 2 Mar 2016 15:53:05 -0500 Subject: ok finishing --- photoblaster/_file.py | 22 +++++++++------------- photoblaster/modules/pbbreaker.py | 18 ++---------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/photoblaster/_file.py b/photoblaster/_file.py index b370bb4..654f305 100644 --- a/photoblaster/_file.py +++ b/photoblaster/_file.py @@ -67,19 +67,15 @@ class File(object): name += ".%s" % self.extension self._filename = name - def set_filepath( - self, - directory=WORKING_DIR, - filepath=None - ): - """creates a local working path""" - if filepath: - self._filepath = filepath - self.set_filename(filename=os.path.basename(filepath)) - return - if self._is_temp: - self.directory = WORKING_DIR - self._filepath = os.path.join(directory, self.get_filename()) + def set_filepath(self, filepath, module=None): + """sets the filepath""" + if os.path.exits(self._filepath): + cmd = ['mv', self._filepath, filepath] + if module: + module.commands.append(" ".join(cmd)) + self._filepath = filepath + self.set_filename(filename=os.path.basename(filepath)) + self._directory = os.path.dirname(filepath) def get_filepath(self): return os.path.join(self._directory, self.get_filename()) diff --git a/photoblaster/modules/pbbreaker.py b/photoblaster/modules/pbbreaker.py index d282513..8ef77a8 100755 --- a/photoblaster/modules/pbbreaker.py +++ b/photoblaster/modules/pbbreaker.py @@ -198,23 +198,9 @@ class PbBreaker(Pb): r'\.', "-%s." % num, self.get_output_file().get_filepath()) ) if str(self.params.breaktype) == 'psd': - self._call_cmd( - [ - 'mv', psd_psbfilepath(1), - self.get_output_file().get_filepath() - ] - ) - self._output_file.set_filepath(filepath=psd_psbfilepath(0)) - self._files_created.append(self.get_output_file()) + self.get_output_file().set_filepath(psd_psbfilepath(1), module=self) if str(self.params.breaktype) == 'psb': - self._call_cmd( - [ - 'mv', - psd_psbfilepath(0), - self.get_output_file().get_filepath() - ]) - self._output_file.set_filepath(filepath=psd_psbfilepath(1)) - self._files_created.append(self.get_output_file()) + self.get_output_file().set_filepath(psd_psbfilepath(0), module=self) if self.params.breakangle: self._rotate_back() -- cgit v1.2.3-70-g09d2 From f322dc9ebbee582c8283083b887374b1c67c89d5 Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Wed, 2 Mar 2016 12:58:10 -0800 Subject: ok that works --- photoblaster/_file.py | 5 ++--- run_module_examples.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/photoblaster/_file.py b/photoblaster/_file.py index 654f305..4e4a382 100644 --- a/photoblaster/_file.py +++ b/photoblaster/_file.py @@ -69,11 +69,10 @@ class File(object): def set_filepath(self, filepath, module=None): """sets the filepath""" - if os.path.exits(self._filepath): - cmd = ['mv', self._filepath, filepath] + if os.path.exists(self.get_filepath()): + cmd = ['mv', self.get_filepath(), filepath] if module: module.commands.append(" ".join(cmd)) - self._filepath = filepath self.set_filename(filename=os.path.basename(filepath)) self._directory = os.path.dirname(filepath) diff --git a/run_module_examples.py b/run_module_examples.py index 3c0e29a..882de78 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -3,7 +3,7 @@ from photoblaster.modules import Pb for cls in Pb.__subclasses__(): print cls.__name__ - if cls.__name__ == "PbLandscape": + if cls.__name__ == "PbBreaker": instance = cls.example_run() print instance.get_output_file().as_dict() instance.get_output_file().s3move() -- cgit v1.2.3-70-g09d2 From ba79cc5574a6335a7d9bb255bcdfa5ec4a4bd53a Mon Sep 17 00:00:00 2001 From: pepperpepperpepper Date: Wed, 2 Mar 2016 13:02:58 -0800 Subject: ok --- photoblaster/modules/base.py | 1 - photoblaster/modules/pbbreaker.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 71c1bec..382b96c 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -92,7 +92,6 @@ class Pb(object): def create(self): pass - #self._cleanup() def get_output_file(self): return self._output_file diff --git a/photoblaster/modules/pbbreaker.py b/photoblaster/modules/pbbreaker.py index 8ef77a8..bddd07a 100755 --- a/photoblaster/modules/pbbreaker.py +++ b/photoblaster/modules/pbbreaker.py @@ -199,8 +199,10 @@ class PbBreaker(Pb): ) if str(self.params.breaktype) == 'psd': self.get_output_file().set_filepath(psd_psbfilepath(1), module=self) + self._files_created.append(psd_psbfilepath(0)) if str(self.params.breaktype) == 'psb': self.get_output_file().set_filepath(psd_psbfilepath(0), module=self) + self._files_created.append(psd_psbfilepath(1)) if self.params.breakangle: self._rotate_back() -- cgit v1.2.3-70-g09d2 From ca0b113f11be55d023c739003ba7a0cf104529d2 Mon Sep 17 00:00:00 2001 From: Pepper Date: Wed, 2 Mar 2016 17:45:03 -0500 Subject: added db code --- photoblaster/db/__init__.py | 17 ++++++++++------- photoblaster/db/models/__init__.py | 26 ++++--------------------- photoblaster/server.py | 21 ++++++++++++++++---- share/frontend/imlandscape/js/pb.js | 4 ++-- sync_iasdfus_deleted.py | 38 ++++++++++++++----------------------- 5 files changed, 47 insertions(+), 59 deletions(-) diff --git a/photoblaster/db/__init__.py b/photoblaster/db/__init__.py index a3bb960..5847545 100644 --- a/photoblaster/db/__init__.py +++ b/photoblaster/db/__init__.py @@ -3,13 +3,16 @@ from sqlalchemy.orm import sessionmaker, scoped_session from photoblaster.config import DB_HOST, DB_USER, DB_PASSWORD, DB_NAME -engine = create_engine('mysql://{}:{}@{}/{}'.format( - DB_USER, - DB_PASSWORD, - DB_HOST, - DB_NAME -)) +engine = create_engine( + 'mysql://{}:{}@{}/{}'.format( + DB_USER, + DB_PASSWORD, + DB_HOST, + DB_NAME + ), + pool_recycle=3600 +) session_factory = sessionmaker(bind=engine) SessionHeap = scoped_session(session_factory) -Session = session_factory +session = session_factory() diff --git a/photoblaster/db/models/__init__.py b/photoblaster/db/models/__init__.py index a30383a..85784e0 100644 --- a/photoblaster/db/models/__init__.py +++ b/photoblaster/db/models/__init__.py @@ -1,25 +1,20 @@ -from photoblaster.db import SessionHeap, Session +from photoblaster.db import SessionHeap, session from sqlalchemy import inspect, desc from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.sql.expression import func - Base = declarative_base() - class Actions(object): @classmethod def create(cls, **kwargs): - session = Session() + global session try: session.add(cls(**kwargs)) session.commit() except: session.rollback() raise - finally: - session.close() - SessionHeap.remove() def update(self, **kwargs): for key, val in kwargs.iteritems(): @@ -31,14 +26,9 @@ class Actions(object): session.rollback() raise - def free(self): - session = inspect(self).session - session.close() - SessionHeap.remove() - @classmethod def _search(cls, **kwargs): - session = Session() + global session query = session.query(cls).filter_by(**kwargs) session.close() return query @@ -47,9 +37,6 @@ class Actions(object): except: session.rollback() raise - finally: - session.close() - SessionHeap.remove() return query @classmethod @@ -62,19 +49,14 @@ class Actions(object): @classmethod def query(cls, **kwargs): - session = SessionHeap() - print "session() query" + global session query = session.query(cls) try: session.add(cls(**kwargs)) session.commit() except: - print "session.rollback()" session.rollback() raise - finally: - session.close() - SessionHeap.remove() return query from photoblaster.db.models.imcmd import ImCmd diff --git a/photoblaster/server.py b/photoblaster/server.py index 0e89886..4a80fd0 100644 --- a/photoblaster/server.py +++ b/photoblaster/server.py @@ -81,7 +81,6 @@ class InvalidUsage(Exception): class Server(object): """Main server class""" def __init__(self): - # self.app = Flask(__name__) self.app = Flask(__name__, static_folder=STATIC_FOLDER) self._wsgi_server = None self._classname_aliases = _CLASSNAME_ALIASES @@ -90,6 +89,18 @@ class Server(object): def test(): return "HELLO WORLD!" + @self.app.route('/im/proxy', methods=['GET']) + def p_image(): + sys.stderr.write("got request") + url = request.args.get("url") + req = urllib2.Request(url=url) + req = urllib2.urlopen(req) + header = req.headers.getheader('content-type') + if re.match(r'image', header, re.IGNORECASE): + return req.read() + else: + raise InvalidUsage('Improper Usage', status_code=410) + @self.app.route('/im/api/', methods=['POST']) def pb(pb_classname): x_forwarded_headers = request.headers.getlist("X-Forwarded-For") @@ -117,6 +128,7 @@ class Server(object): # send_static_file will guess the correct MIME type return self.app.send_static_file(path) + @self.app.route('/proxy', methods=['GET']) def proxy_image(): url = request.args.get("url") @@ -215,15 +227,16 @@ class Server(object): raise InvalidUsage('No such api', status_code=410) def _response_post(self, pb_classname, request_form, remote_addr=None): + #load plugins here pb_class = self._find_class_by_name(pb_classname) - # classnames = map(lambda c: c.__name__, Pb.__subclasses__()) try: pb = pb_class(**request_form) pb.create() if not LOCAL: - pb.file_s3move() + pb.get_output_file().s3move() pb.db_send(remote_addr=remote_addr) - json_data = jsonify(pb.file_dict()) + json_data = jsonify(pb.get_output_file().as_dict()) + pb.cleanup() if pb.params.callback: # accounts for jsonp return "%s(%s)" % (pb.params.callback, json_data) return json_data diff --git a/share/frontend/imlandscape/js/pb.js b/share/frontend/imlandscape/js/pb.js index 9cf8df5..55e30ac 100644 --- a/share/frontend/imlandscape/js/pb.js +++ b/share/frontend/imlandscape/js/pb.js @@ -57,8 +57,8 @@ function loadNew() { console.log(textureURL); console.log(heightmapURL); stop_animating(); - var new_texture = '/proxy?url='+textureURL; - var new_heightmap = '/proxy?url='+heightmapURL; + var new_texture = '/im/proxy?url='+textureURL; + var new_heightmap = '/im/proxy?url='+heightmapURL; initGraphics(new_texture, new_heightmap, function(){ animate() } ); } diff --git a/sync_iasdfus_deleted.py b/sync_iasdfus_deleted.py index b654c0d..c0c4bac 100644 --- a/sync_iasdfus_deleted.py +++ b/sync_iasdfus_deleted.py @@ -4,7 +4,6 @@ import re from photoblaster.db.models import Iasdfus from photoblaster.db.models import ImCmd -#database = Database() def super_unquote(s): for i in xrange(0,20): @@ -14,18 +13,10 @@ def super_unquote(s): #searches for elements in the Iasdfus table that have deleted=1 #stores all the objects as a list in memory, there are 92,000 deleted_urls = Iasdfus.search(deleted=True).all() -print len(deleted_urls) -#well do you think I should try to study the flask-sqlalchemy sources and look for clues? +#print len(deleted_urls) #well i'm reading doc on it, they recommend create one session per all requests, and we here are creating new session per #each request, not sure if that matters I guess it does. #so in other words, in the flask-sqlalchemy pattern the session is created when the server is started -#and in our case, we are wrapping a session into each query -#so instead we need to invoke session as part of this script? -#well almost. I think need to make main class like Database, and use it like this -# and inside .rs() get it froem Database() object -# I think we need to stop trying to create new sessions every time, obviously there's -# something under the hood making it impossible to use that way in any scalable situation, you know? yeah -#so instead of calling sqlalchemy.session directly in the script #instantiate pb.db.Database() #and at the end of the script #database.close(), something like this? close() can be in destroy method for dataabase, it will go out of scope at the end of script @@ -38,7 +29,7 @@ print len(deleted_urls) #im/ff/wigglelogo_1347403794_frankhats_1347403811_frankhats.gif n = 0 for url in deleted_urls: - print "from iasdfus: (%s)" % (url.address) +# print "from iasdfus: (%s)" % (url.address) #iterates through try: parts = url.address.split("/") @@ -48,16 +39,15 @@ for url in deleted_urls: newfile = super_unquote(parts[2]) newfile_parts = re.split(r'\+?http', newfile) newfile = newfile_parts[0] - print "parts from iasdfus (newfile : %s, dir: %s)" % (newfile, dirpart) +# print "parts from iasdfus (newfile : %s, dir: %s)" % (newfile, dirpart) except IndexError: continue try: #searches ImCmd for that row, where dirpart and newfile are the same as the #values in the Iasdfus row - print "imcmd: %s %s\n" % (dirpart, newfile) #k so looks like it's stuck here regardless on item, so this probably session limit, or something like that - query = database.rs('ImCmd').search(**{"dir": dirpart, "newfile": newfile}) - print "imcmd done query n: %d\n" % (n) + query = ImCmd.search(**{"dir": dirpart, "newfile": newfile}) +# print "imcmd done query n: %d\n" % (n) n +=1 #can't find anything about it me too #so it doesn't have .free(), I think it doesni so it's some sort of session parameter? looks so seen it anywhere? have free only when it doesn't find anything it's still a Query objects @@ -66,16 +56,16 @@ for url in deleted_urls: #it seems like my theory might be right...seems like it to you right? not sure yet #processes the query matching_url = query.first() - print "got first\n" - #if not matching_url: - # print "nothing found\n" - # continue - #if matching_url.deleted == 1: - # print "is deleted\n" - # continue +# print "got first\n" + if not matching_url: + print "imcmd: %s %s\n" % (dirpart, newfile) + continue + if matching_url.deleted == 1: +# print "is deleted\n" + continue #update matching_url - #matching_url.update(deleted=1) - #print "update done\n" + matching_url.update(deleted=1) + print "update done\n" except AttributeError: raise #honestly can't imagine why I'm getting this error maybe we just need to implement another rollback exception? -- cgit v1.2.3-70-g09d2 From c952f69853241c8ee7d8fde282571f39cb7199b7 Mon Sep 17 00:00:00 2001 From: Pepper Date: Wed, 2 Mar 2016 18:08:20 -0500 Subject: about to merge newfile --- photoblaster/modules/base.py | 2 +- run_module_examples.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/photoblaster/modules/base.py b/photoblaster/modules/base.py index 382b96c..cae728e 100644 --- a/photoblaster/modules/base.py +++ b/photoblaster/modules/base.py @@ -42,7 +42,7 @@ class Pb(object): sys.stderr.write("ERROR:{} - {}\n".format(self.__class__.__name__, s)) raise PbProcessError - def _cleanup(self): + def cleanup(self): if not self._files_created: return map(lambda n: n.delete(), self._files_created) diff --git a/run_module_examples.py b/run_module_examples.py index 882de78..8a22c10 100644 --- a/run_module_examples.py +++ b/run_module_examples.py @@ -3,8 +3,8 @@ from photoblaster.modules import Pb for cls in Pb.__subclasses__(): print cls.__name__ - if cls.__name__ == "PbBreaker": + if cls.__name__ == "PbGradient": instance = cls.example_run() - print instance.get_output_file().as_dict() instance.get_output_file().s3move() + print instance.get_output_file().as_dict() instance.db_send() -- cgit v1.2.3-70-g09d2