コード例 #1
0
ファイル: image_metadata.py プロジェクト: a1russell/photasm
    def test_read_datetime_from_exif_and_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()

        keys = ('Exif.Photo.DateTimeOriginal',
                'Iptc.Application2.DateCreated',
                'Iptc.Application2.TimeCreated',)
        # Note that metadata doesn't have microsecond precision.
        exif_val = datetime.datetime(2007, 9, 28, 3, 0)
        iptc_val = datetime.datetime(2007, 10, 10, 5, 0)
        iptc_date = iptc_val.date()
        iptc_time = iptc_val.time()

        # Read metadata from image after conflicting Exif and IPTC
        # have been added to the image. Exif should be preferred.
        metadata['Exif.Photo.DateTimeOriginal'] = exif_val
        try:
            metadata['Iptc.Application2.DateCreated'] = iptc_date
        except TypeError:
            pass
        try:
            metadata['Iptc.Application2.TimeCreated'] = iptc_time
        except TypeError:
            pass
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
                         exif_val)

        # Read metadata value when image contains only Exif.
        _del_img_key(metadata, 'Iptc.Application2.DateCreated')
        _del_img_key(metadata, 'Iptc.Application2.TimeCreated')
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
                         exif_val)

        # Read metadata value when image contains only IPTC.
        _del_img_key(metadata, 'Exif.Photo.DateTimeOriginal')
        try:
            metadata['Iptc.Application2.DateCreated'] = iptc_date
        except TypeError:
            pass
        try:
            metadata['Iptc.Application2.TimeCreated'] = iptc_time
        except TypeError:
            pass
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
                         iptc_val)

        # Attempt to read nonexistent metadata.
        _del_img_key(metadata, 'Iptc.Application2.DateCreated')
        _del_img_key(metadata, 'Iptc.Application2.TimeCreated')
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
            None)

        # Attempt to read incomplete metadata containing only IPTC date.
        try:
            metadata['Iptc.Application2.DateCreated'] = iptc_date
        except TypeError:
            pass
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
            None)

        # Attempt to read incomplete metadata containing only IPTC time.
        _del_img_key(metadata, 'Iptc.Application2.DateCreated')
        try:
            metadata['Iptc.Application2.TimeCreated'] = iptc_time
        except TypeError:
            pass
        metadata.writeMetadata()
        self.assertEqual(read_datetime_from_exif_and_iptc(metadata, *keys),
                         None)

        # Clean up.
        os.remove(file_path)
コード例 #2
0
ファイル: models.py プロジェクト: a1russell/photasm
    def sync_metadata_from_file(self, commit=True):
        """\
        Synchronizes the image metadata from the filesystem to the object.

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

        Returns True if metadata needed to be written to the database;
        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_instance = False  # whether or not database needs written to

        # sync description
        mod_attr = not value_synced_with_exif_and_iptc(
            self.description, image_metadata,
            'Exif.Image.ImageDescription', 'Iptc.Application2.Caption')
        mod_instance = mod_attr or mod_instance
        if mod_attr:
            value = read_value_from_exif_and_iptc(image_metadata,
                'Exif.Image.ImageDescription', 'Iptc.Application2.Caption')
            if value is None:
                value = str()
            self.description = value

        # sync artist
        mod_attr = not value_synced_with_exif_and_iptc(
            self.artist, image_metadata,
            'Exif.Image.Artist', 'Iptc.Application2.Byline')
        mod_instance = mod_attr or mod_instance
        if mod_attr:
            value = read_value_from_exif_and_iptc(image_metadata,
                'Exif.Image.Artist', 'Iptc.Application2.Byline')
            if value is None:
                value = str()
            self.artist = value

        # sync country
        mod_attr = not value_synced_with_iptc(self.country, image_metadata,
                                              'Iptc.Application2.CountryName')
        mod_instance = mod_attr or mod_instance
        if ('Iptc.Application2.CountryName' in image_metadata.iptcKeys() and
            mod_attr):
            value = image_metadata['Iptc.Application2.CountryName']
            if value is None:
                value = str()
            self.country = value

        # sync province_state
        mod_attr = not value_synced_with_iptc(
            self.province_state, image_metadata,
            'Iptc.Application2.ProvinceState')
        mod_instance = mod_attr or mod_instance
        if ('Iptc.Application2.ProvinceState' in image_metadata.iptcKeys() and
            mod_attr):
            value = image_metadata['Iptc.Application2.ProvinceState']
            if value is None:
                value = str()
            self.province_state = value

        # sync city
        mod_attr = not value_synced_with_iptc(self.city, image_metadata,
                                              'Iptc.Application2.City')
        mod_instance = mod_attr or mod_instance
        if 'Iptc.Application2.City' in image_metadata.iptcKeys() and mod_attr:
            value = image_metadata['Iptc.Application2.City']
            if value is None:
                value = str()
            self.city = value

        # sync location
        mod_attr = not value_synced_with_iptc(self.location, image_metadata,
                                              'Iptc.Application2.SubLocation')
        mod_instance = mod_attr or mod_instance
        if ('Iptc.Application2.SubLocation' in image_metadata.iptcKeys() and
            mod_attr):
            value = image_metadata['Iptc.Application2.SubLocation']
            if value is None:
                value = str()
            self.location = value

        # sync time_created
        mod_attr = not datetime_synced_with_exif_and_iptc(
            self.time_created, image_metadata,
            'Exif.Photo.DateTimeOriginal', 'Iptc.Application2.DateCreated',
            'Iptc.Application2.TimeCreated')
        mod_instance = mod_attr or mod_instance
        if mod_attr:
            self.time_created = read_datetime_from_exif_and_iptc(
                image_metadata, 'Exif.Photo.DateTimeOriginal',
                'Iptc.Application2.DateCreated',
                'Iptc.Application2.TimeCreated')

        # sync keywords
        mod_attr = not value_synced_with_iptc(self.keyword_list,
            image_metadata, 'Iptc.Application2.Keywords')
        mod_instance = mod_attr or mod_instance
        if ('Iptc.Application2.Keywords' in image_metadata.iptcKeys() and
            mod_attr):
            self.keyword_list = image_metadata['Iptc.Application2.Keywords']

        if mod_instance and commit:
            self.save()

        return mod_instance