Example #1
0
    def test_sync_value_to_exif(self):
        # Create an image.
        file_descriptor, file_path = tempfile.mkstemp(suffix='.jpg')
        os.close(file_descriptor)
        Image.new('RGB', (1, 1)).save(file_path, 'JPEG')
        metadata = pyexiv2.Image(file_path)
        metadata.readMetadata()

        # Synchronize a string.
        test_description = 'Test file with description'
        performed_sync = sync_value_to_exif(test_description, metadata,
                                            'Exif.Image.ImageDescription')
        self.assertTrue(performed_sync)
        metadata.writeMetadata()
        self.assertEqual(metadata['Exif.Image.ImageDescription'],
                         'Test file with description')
        self.assertFalse(sync_value_to_exif(test_description, metadata,
                                            'Exif.Image.ImageDescription'))

        # Synchronize an empty string.
        empty_string = ''
        performed_sync = sync_value_to_exif(empty_string, metadata,
                                            'Exif.Image.ImageDescription')
        self.assertTrue(performed_sync)
        metadata.writeMetadata()
        self.assertFalse('Exif.Image.ImageDescription' in metadata.exifKeys())
        self.assertFalse(sync_value_to_exif(empty_string, metadata,
                                            'Exif.Image.ImageDescription'))

        # Synchronizing the None value has the same effect as an empty string.
        none_argument = None
        self.assertFalse('Exif.Image.Orientation' in metadata.exifKeys())
        self.assertFalse(sync_value_to_exif(none_argument, metadata,
                                            'Exif.Image.Orientation'))

        # Clean up.
        os.remove(file_path)
Example #2
0
    def sync_metadata_to_file(self):
        """\
        Synchronizes the image metadata from the object to the filesystem.

        This stores certain properties of the object to the image file
        itself as Exif and/or IPTC tags, allowing the information to be
        portable outside of this application. Metadata is only actually
        written to the filesystem if the values do not match up, however.

        Returns True if metadata needed to be written to the file;
        False otherwise.

        """
        if not self.metadata_sync_enabled:
            return False

        try:
            image_metadata = pyexiv2.Image(self.image.path)
            image_metadata.readMetadata()
        except IOError:
            self.metadata_sync_enabled = False
            self.save()
            return False

        mod = False # whether or not file actually needs written to

        # sync description
        mod = sync_value_to_exif_and_iptc(self.description, image_metadata,
                                          'Exif.Image.ImageDescription',
                                          'Iptc.Application2.Caption') or mod

        # sync artist
        mod = sync_value_to_exif_and_iptc(self.artist, image_metadata,
                                          'Exif.Image.Artist',
                                          'Iptc.Application2.Byline') or mod

        # sync country
        mod = sync_value_to_iptc(self.country, image_metadata,
                                 'Iptc.Application2.CountryName') or mod

        # sync province_state
        mod = sync_value_to_iptc(self.province_state, image_metadata,
                                 'Iptc.Application2.ProvinceState') or mod

        # sync city
        mod = sync_value_to_iptc(self.city, image_metadata,
                                 'Iptc.Application2.City') or mod

        # sync location
        mod = sync_value_to_iptc(self.location, image_metadata,
                                 'Iptc.Application2.SubLocation') or mod

        # sync time_created
        mod = sync_datetime_to_exif_and_iptc(self.time_created,
            image_metadata, 'Exif.Photo.DateTimeOriginal',
            'Iptc.Application2.DateCreated', 'Iptc.Application2.TimeCreated')\
            or mod

        # sync keywords
        mod = sync_value_to_iptc(self.keyword_list, image_metadata,
                                 'Iptc.Application2.Keywords') or mod

        # sync image_width
        mod = sync_value_to_exif(self.image_width, image_metadata,
                                 get_image_width_key(self.is_jpeg)) or mod

        # sync image_height
        mod = sync_value_to_exif(self.image_height, image_metadata,
                                 get_image_height_key(self.is_jpeg)) or mod

        if mod:
            try:
                image_metadata.writeMetadata()
            except IOError:
                self.metadata_sync_enabled = False
                self.save()
                return False

        return mod