def test_sync_value_to_iptc(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_iptc(test_description, metadata, 'Iptc.Application2.Caption') self.assertTrue(performed_sync) metadata.writeMetadata() metadata = pyexiv2.Image(file_path) metadata.readMetadata() self.assertEqual(metadata['Iptc.Application2.Caption'], 'Test file with description') self.assertFalse(sync_value_to_iptc(test_description, metadata, 'Iptc.Application2.Caption')) # Synchronize an empty string. empty_string = "" performed_sync = sync_value_to_iptc(empty_string, metadata, 'Iptc.Application2.Caption') self.assertTrue(performed_sync) metadata.writeMetadata() self.assertFalse('Iptc.Application2.Caption' in metadata.iptcKeys()) self.assertFalse(sync_value_to_iptc(empty_string, metadata, 'Iptc.Application2.Caption')) # Synchronize an iterable. test_keywords = ['IPTC', 'test', 'keywords'] performed_sync = sync_value_to_iptc(test_keywords, metadata, 'Iptc.Application2.Keywords') self.assertTrue(performed_sync) metadata.writeMetadata() self.assertEqual(metadata['Iptc.Application2.Keywords'], ('IPTC', 'test', 'keywords')) # Synchronize an empty iterable. empty_list = [] performed_sync = sync_value_to_iptc(empty_list, metadata, 'Iptc.Application2.Keywords') self.assertTrue(performed_sync) metadata.writeMetadata() self.assertFalse('Iptc.Application2.Keywords' in metadata.iptcKeys()) self.assertFalse(sync_value_to_iptc(empty_list, metadata, 'Iptc.Application2.Keywords')) # Syncing the None value has the same effect as an empty one. none_argument = None self.assertFalse('Iptc.Envelope.ARMId' in metadata.iptcKeys()) self.assertFalse(sync_value_to_iptc(none_argument, metadata, 'Iptc.Application2.DateCreated')) # Clean up. os.remove(file_path)
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