diff options
| -rw-r--r-- | photoblaster/_file.py | 23 | ||||
| -rw-r--r-- | photoblaster/modules/base.py | 4 | ||||
| -rwxr-xr-x | photoblaster/modules/pbbreaker.py | 76 | ||||
| -rwxr-xr-x | photoblaster/modules/pbgrid.py | 138 | ||||
| -rw-r--r-- | photoblaster/param/img_url.py | 53 | ||||
| -rw-r--r-- | photoblaster/params.py | 18 | ||||
| -rw-r--r-- | 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() |
