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)
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
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')
Example #5
0
 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)
Example #6
0
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