def stamp(self): imageTool = ImageFileInfoTool(self.out, self.system) filesToStamp = [] for filename in self.getNormalizedPathArgument(): if isdir(filename): for child in listdir(filename): # doesn't descend into subdirs child = "%s/%s" % (filename, child) filesToStamp.append(child) else: filesToStamp.append(filename) for filename in sorted(filesToStamp): if not imageTool.isImageFilename(filename): self.out.put( "Skipping %s because it doesn't look like an image file." % filename, self.out.LOG_LEVEL_WARN ) continue try: fileInfo = imageTool.getFileInfo(filename, okToUseFileName=True) except: fileInfo = False self.out.put("File is broken or has no data!", self.out.LOG_LEVEL_WARN) self.out.put(traceback.format_exc(), self.out.LOG_LEVEL_DEBUG) if not fileInfo: self.out.put("Unable to stamp file: %s" % basename(filename), self.out.LOG_LEVEL_WARN) continue self.out.put("Stamping %s..." % filename, self.out.LOG_LEVEL_WARN) self.rename(filename, fileInfo)
def doRunSteps(self, imageTool=None): if imageTool == None: self.imageTool = ImageFileInfoTool(self.out, self.system) else: self.imageTool = imageTool for filename in self.getNormalizedPathArgument(): if self.imageTool.isImageFilename(filename): self.processImageFile(filename)
def setUp(self): self.out = JobOutput() self.out.disableLogFile() self.sys = PySystemMock(self.out) self.dateStamper = ImageDateStamper(self.out, self.sys) self.testDir = '%s/test' % realpath(dirname(__file__)) self.dateStamper.arguments['path'] = [self.testDir] self.infoGrabber = ImageFileInfoTool(self.out, self.sys) self.scaler = ImageScaler(self.out, self.sys)
class ImageToolsTest(unittest.TestCase): out = None sys = None dateStamper = None infoGrabber = None scaler = None testDir = None def setUp(self): self.out = JobOutput() self.out.disableLogFile() self.sys = PySystemMock(self.out) self.dateStamper = ImageDateStamper(self.out, self.sys) self.testDir = '%s/test' % realpath(dirname(__file__)) self.dateStamper.arguments['path'] = [self.testDir] self.infoGrabber = ImageFileInfoTool(self.out, self.sys) self.scaler = ImageScaler(self.out, self.sys) def testTrivialShouldPass(self): pass def testGetFileInfoFromFilename(self): expectedResult = {'year':'2011', 'month':'02', 'day':'12', 'title':'The title of the Picture', 'extension':'Jpg'} self.assertEqual(self.infoGrabber.getFileInfoFromFilename('2011-02.12-The title of the Picture.Jpg'), expectedResult) self.assertEqual(self.infoGrabber.getFileInfoFromFilename('2011.02-12 _ The title of the Picture.Jpg'), expectedResult) expectedResult['hour'] = '11' expectedResult['minute'] = '33' self.assertEqual(self.infoGrabber.getFileInfoFromFilename('2011-02.12 11:33-The title of the Picture.Jpg'), expectedResult) self.assertEqual(self.infoGrabber.getFileInfoFromFilename('2011.02_12.11.33 The title of the Picture.Jpg'), expectedResult) self.assertEqual(self.infoGrabber.getFileInfoFromFilename('2011 02 12 11:33 The title of the Picture.Jpg'), expectedResult) def testGetTargetFileName(self): # very brief. Partly we're testing that Jpg is not converted to jpg; otherwise, very stupid test. fileInfo = {'year':'11', 'month':'2', 'day':'12', 'hour':'11', 'minute':'33', 'title':'The title of the Picture', 'extension':'Jpg'} self.assertEqual(self.dateStamper.getTargetFileName(fileInfo), '11-2-12 The title of the Picture.Jpg') fileInfo['year'] = '2011' fileInfo['month'] = '02' self.assertEqual(self.dateStamper.getTargetFileName(fileInfo), '2011-02-12 The title of the Picture.Jpg') self.dateStamper.arguments['time'] = True self.assertEqual(self.dateStamper.getTargetFileName(fileInfo), '2011-02-12 11.33 The title of the Picture.Jpg') def testGetFileNamesToStamp(self): fileNames = ['2011-07-30 P0002394.JPG', 'ImageDateStamperTest.pyc', 'Named image file.JPG', 'Non Image File.txt'] self.assertEqual(self.dateStamper.getFileNamesToStamp(), fileNames) def testGetFileInfo(self): self.assertEqual([], self.infoGrabber.getFileInfo('%s/Named image file.JPG' % self.testDir)) def testScaleImage(self): self.scaler.scaleImageFile('/home/luke/Public/AllStarTest/2011.07.25 picture folder name with spaces/subfolder/P1040425.JPG')
def doRunSteps(self, imageTool=None): if imageTool == None: imageTool = ImageFileInfoTool(self.out, self.system) for fullPath in self.getNormalizedPathArgument(): fullPath = imageTool.renameFileIfNecessary(fullPath) self.copyToAllStars(fullPath)
class ImageScaler(Job): def defineCustomArguments(self, parser): parser.add_argument('-l', '--limit-size', metavar='x', default=DEFAULT_SCALE_SIZE, help="Limit the size of the longest dimension of the original to x pixels (default %d)" % DEFAULT_SCALE_SIZE, ) parser.add_argument('-g', '--greyscale', action='store_true', default=False, help="Convert to greyscale", ) parser.add_argument('path', nargs='*', help="Path(s) of the image(s) to scale, space separated if multiple", ) def doRunSteps(self, imageTool=None): if imageTool == None: self.imageTool = ImageFileInfoTool(self.out, self.system) else: self.imageTool = imageTool for filename in self.getNormalizedPathArgument(): if self.imageTool.isImageFilename(filename): self.processImageFile(filename) def processImageFile(self, sourceFileName): self.out.indent("Scaling file: %s" % sourceFileName) targetFileName = self.getTargetFileName(sourceFileName) self.out.put("reading image file...", self.out.LOG_LEVEL_DEBUG) sourceImage = Image.open(sourceFileName) self.processImage(sourceImage, targetFileName) try: self.imageTool.copyExifMetadata(sourceFileName, targetFileName) except: # probably in debug mode - no .scaled.jpg file was created if not self.inDebugMode(): self.out.put("ERROR: Unable to copy EXIF metadata to %s. Was it scaled/saved correctly?" % targetFileName, self.out.LOG_LEVEL_ERROR) self.out.unIndent() def processImage(self, sourceImage, targetFileName): size = (self.arguments['limit_size'], self.arguments['limit_size']) if self.arguments['greyscale']: self.out.put("converting image to greyscale...", self.out.LOG_LEVEL_VERBOSE) sourceImage = sourceImage.convert("L") self.out.put("scaling image...", self.out.LOG_LEVEL_DEBUG) sourceImage.thumbnail(size, Image.ANTIALIAS) if self.inDebugMode(): # if we're running in mock mode, then we shouldn't be changing anything on the filesystem. self.out.put("DEBUG: Not writing image file because we're in mock mode") else: self.out.put("writing image file...", self.out.LOG_LEVEL_DEBUG) sourceImage.save(targetFileName) def getTargetFileName(self, sourceFileName): self.out.put("Setting target filename...", self.out.LOG_LEVEL_VERBOSE) (base, ext) = splitext(sourceFileName) targetFileName = base + FILENAME_SCALED_SUFFIX + ext.lower() self.out.put("source path: %s" % sourceFileName, self.out.LOG_LEVEL_VERBOSE) self.out.put("target path: %s" % targetFileName, self.out.LOG_LEVEL_VERBOSE) return targetFileName def inDebugMode(self): return self.system.__class__ == PySystemMock