summaryrefslogtreecommitdiff
path: root/pb/breaker.py
diff options
context:
space:
mode:
Diffstat (limited to 'pb/breaker.py')
-rwxr-xr-xpb/breaker.py268
1 files changed, 268 insertions, 0 deletions
diff --git a/pb/breaker.py b/pb/breaker.py
new file mode 100755
index 0000000..c982b14
--- /dev/null
+++ b/pb/breaker.py
@@ -0,0 +1,268 @@
+#!/usr/bin/python2.7
+import os
+import sys
+import random
+import re
+import pb.lib.utils as utils
+import urllib
+from pb.config import *
+
+DEFAULT_FINALFORMAT = "png";
+SUBTLE_BREAK_MARK = 'pron'
+EXTREME_BREAK_MARK = 'sugar'
+
+HEADER_OFFSET = 2000
+
+# 'CLASSIC':'jpg',
+# 'REDUX':'pcds',
+# 'BLURRY_BREAK':'viff',
+# 'BLURRY_BREAK_2':'mat',
+# 'SWIPE':'miff',
+# 'RGB_WASH':'psd',
+# 'RGB_WASH_2':'psb',
+# 'NOISY_BREAK':'palm',
+# 'NOISY_BREAK_2':'fig',
+# 'BROKEN_VIGNETTE':'pbm',
+# 'FAX_MACHINE':'cals',
+# 'STRIPES':'exr',
+# 'PHOTOCOPY':'art',
+
+class Breaker():
+ def __init__(self, **kwargs):
+ self.params = {}
+ self.tag = "imBreak"
+ self.commands = [];
+ self._required_keys = [
+ "url",
+ "breaktype",
+ "finalformat",
+ "breakmode",
+ "breakangle",
+ "username",
+ "expanded"
+ ]
+ self.now = utils.now()
+ self.files_created = []
+ for k in self._required_keys:
+ if k in kwargs:
+ if k == 'breaktype':
+ self.params['breaktype'] = self._get_breaktype(kwargs[k])
+ elif k == 'url':
+ self.params[k] = kwargs[k]
+ else:
+ self.params[k] = utils.bool_correct(utils.sanitize(kwargs[k]))
+ else:
+ self.params[k] = False;
+
+
+ self.params = utils.dotdict(self.params)
+
+ self.basename, self._first_format = self._get_filename();
+ self._downloaded_file = os.path.join(WORKING_DIR, "IMBREAKTMP{}.{}".format(self.basename, self._first_format)) # same here
+
+ try:
+ utils.download(self.params.url, self._downloaded_file)
+ self.files_created.append(self._downloaded_file)
+ except Exception as e:
+ sys.stderr.write(str(e))
+ raise;
+ self._gif_frames = utils.gif_frames(self._downloaded_file)
+ self._gif_frames = self._gif_frames if len(self._gif_frames) > 1 else False
+ self.width, self.height = utils.dimensions(self._downloaded_file) # same here
+
+ if not self.params.finalformat:
+ self.params.finalformat = DEFAULT_FINALFORMAT
+ if self._gif_frames:
+ self.params.finalformat = 'gif'
+ if self.params.breaktype == 'miff':
+ self.params.finalformat = 'jpg'
+ self.params.breakmode = 'subtle'
+ #final filepath is stored in self.filepath
+ self.filename = "{}.{}".format(self.basename, self.params.finalformat)
+ self.filepath = os.path.join(WORKING_DIR, self.filename)
+ self._conversion_file = os.path.join(WORKING_DIR, "IMBREAKTMP{}.{}".format(self.basename, self.params.breaktype)) # this
+
+
+ def _call_cmd(self, cmd, error=""):
+ try:
+ utils.call_cmd(cmd)
+ self.commands.append(" ".join(cmd));
+ except Exception:
+ raise Exception("Unable to call cmd {}".format(str(cmd)))
+
+ def _get_breaktype(self, key):
+ #{{{ conversion table
+ breaktypeTranslate = {
+ 'CLASSIC':'jpg',
+ 'REDUX':'pcds',
+ 'BLURRY_BREAK':'viff',
+ 'BLURRY_BREAK_2':'mat',
+ 'SWIPE':'miff',
+ 'RGB_WASH':'psd',
+ 'RGB_WASH_2':'psb',
+ 'NOISY_BREAK':'palm',
+ 'NOISY_BREAK_2':'fig',
+ 'BROKEN_VIGNETTE':'pbm',
+ 'FAX_MACHINE':'cals',
+ 'STRIPES':'exr',
+ 'PHOTOCOPY':'art',
+ }
+ #}}}
+ return breaktypeTranslate[key]
+
+ def _get_filename (self):
+ url = self.params.url
+ name_part = "";
+ file_format = "";
+ if "?" in url:
+ url = url.split("?")[0]
+ if "/" in url:
+ url = urllib.unquote(url).replace(" ","")
+ name_part = url.split("/")[-1]
+ try:
+ parts = name_part.split(".")
+ name_part = utils.sanitize(parts[-2])
+ file_format = utils.sanitize(parts[-1])
+ if not name_part or not file_format:
+ sys.stderr.write( "Incompatible input file type")
+ raise;
+ except Exception as e:
+ sys.stderr.write( "Incompatible input file type")
+ raise;
+ else:
+ sys.stderr.write( "Incompatible url")
+ raise;
+ if (len(name_part) > 20):
+ name_part = name_part[:-20]
+ return "{}{}_{}_{}".format(self.tag, name_part, self.now, self.params.username or ""), file_format
+
+#{{{#########rotatefunctions#######################################
+ def _rotate(self):
+ cmd = [BIN_CONVERT,self._downloaded_file,"-rotate",self.params.breakangle,"+repage",self._downloaded_file]
+ self._call_cmd(cmd)
+
+ def _rotate_back(self):
+ angle = str(360-int(self.params.breakangle))
+ cmd = [BIN_CONVERT,self.filepath,"-rotate",angle,"+repage",self.filepath]
+ self._call_cmd(cmd)
+ if not self.params.expanded:
+ cmd = [BIN_CONVERT,self.filepath,"-gravity","Center","-crop","{}x{}+0+0".format(
+ self.width, self.height),"+repage",self.filepath]
+ self._call_cmd(cmd)
+#}}}
+ def _subtle_break(self):
+ #assume the header is no longer than HEADER_OFFSET bytes
+ breakpoint = random.randint(HEADER_OFFSET, len(self.file_data))
+ newfile = ""
+ newfile = self.file_data[0:breakpoint];
+ newfile += SUBTLE_BREAK_MARK;
+ newfile += self.file_data[breakpoint:]
+ self.file_data = newfile[0:len(self.file_data)]
+
+ def _extreme_break(self):
+ increment = len(self.file_data)/10;
+ i = 0
+ newfile = "";
+ for b in self.file_data:
+ if i > HEADER_OFFSET and not (i % increment):
+ b += EXTREME_BREAK_MARK
+ newfile += b
+ i += 1
+ self.file_data = newfile[0:len(self.file_data)]
+
+ def _choose_frame(self):
+ frame = random.choice(self._gif_frames)
+ cmd = [BIN_CONVERT, frame, self._downloaded_file]
+ self._call_cmd(cmd)
+
+ def _enforce_jpg(self):
+ if self.params.breaktype in [ "exr", "bmp", "miff" ] and not re.match(r'jpe?g', self._first_format, re.IGNORECASE):
+ jpg_file = os.path.join(WORKING_DIR, "{}.{}".format(self.basename, "jpg"))
+ cmd = [BIN_CONVERT,self._downloaded_file,jpg_file]
+ self._call_cmd(cmd)
+ cmd = ["rm",self._downloaded_file]
+ self._call_cmd(cmd)
+
+
+ def _first_conversion(self):
+ if self._first_format == self.params.breaktype:
+ self._downloaded_file = self._conversion_file
+ return
+ cmd = [BIN_CONVERT, self._downloaded_file, self._conversion_file]
+ self._call_cmd(cmd)
+ self.files_created.append(self._conversion_file)
+
+ def _read_data(self, filepath):
+ f = open(filepath, 'r');
+ data = f.read()
+ f.close()
+ return data
+
+ def _prepare_filedata(self):
+ if self._gif_frames:
+ self._choose_frame()
+ if self.params.breakangle:
+ self._rotate()
+ self._enforce_jpg();
+ self._first_conversion();
+ self.file_data = self._read_data(self._conversion_file)
+ if not self.file_data:
+ sys.stderr.write("Unable to get file_data")
+ raise;
+
+ def _add_false_data(self, breakmode):
+ if breakmode == "subtle":
+ self._subtle_break()
+ elif breakmode == "extreme":
+ self._extreme_break()
+ f = open(self._conversion_file, 'w')
+ f.write(self.file_data)
+ f.close();
+
+#{{{ SHRINK (UNUSED)
+ def _shrink(self):
+ cmd = [ BIN_CONVERT, "-resize", "500x500", self._downloaded_file, self._downloaded_file ];
+ self._call_cmd(cmd)
+#}}}
+
+ def _final_conversion(self):
+ cmd = [BIN_CONVERT, self._conversion_file, self.filepath]
+ self._call_cmd(cmd)
+ def psd_psbfilepath(num):
+ return os.path.join(WORKING_DIR, "{}-{}.{}".format(self.basename, num, self.params.finalformat))
+ if self.params.breaktype == 'psd':
+ cmd = ['mv', psd_psbfilepath(1), self.filepath]
+ self._call_cmd(cmd)
+ self.files_created.append(psd_psbfilepath(0))
+ if self.params.breaktype == 'psb':
+ cmd = ['mv', psd_psbfilepath(0), self.filepath]
+ self._call_cmd(cmd)
+ self.files_created.append(psd_psbfilepath(1))
+
+ if self.params.breakangle:
+ self._rotate_back()
+
+ def _cleanup(self):
+ cmd = ["rm"]+self.files_created
+ self._call_cmd(cmd)
+
+ def create(self, breakmode=""):
+ if not breakmode: breakmode = self.params.breakmode
+ self._prepare_filedata();
+ self._add_false_data(breakmode);
+ self._final_conversion()
+ self._cleanup()
+
+if __name__ == "__main__":
+ TEST_PARAMS = {
+ "url" : "http://i.asdf.us/im/27/1424816234661dumpfmpfifferkinggr_1424816412_pfifferking.gif" ,
+ "breaktype" : "RGB_WASH",
+ "finalformat" : "png",
+ "breakmode" : "extreme",
+ "breakangle" : "10",
+ "username" : "donkey",
+ "expanded" : "false"
+ }
+ b = Breaker(**TEST_PARAMS)
+ b.create();
+ print b.filepath