diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2009-04-21 09:23:46 +0200 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2009-04-21 09:23:46 +0200 |
commit | 279b974080eafb42af1f8da3920e2c4d04e63a0f (patch) | |
tree | 93588f4ab285712b8bae63e2f8c68d93088a4446 /src | |
parent | 8ee4a60dcfd299331ba30992fc324aeeeba694ab (diff) | |
download | pyexiv2-279b974080eafb42af1f8da3920e2c4d04e63a0f.tar.gz |
Unlike IPTC tags, XMP tags are not repeatable.
Diffstat (limited to 'src')
-rw-r--r-- | src/exiv2wrapper.cpp | 79 | ||||
-rw-r--r-- | src/exiv2wrapper.hpp | 9 | ||||
-rw-r--r-- | src/pyexiv2.py | 37 |
3 files changed, 87 insertions, 38 deletions
diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index 18eff7d..4c37fd6 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -344,39 +344,70 @@ boost::python::list Image::xmpKeys() boost::python::tuple Image::getXmpTag(std::string key) { - if(_dataRead) + if(!_dataRead) { - Exiv2::XmpKey xmpKey = Exiv2::XmpKey(key); - boost::python::list values; - unsigned int occurences = 0; - for (Exiv2::XmpMetadata::iterator i = _xmpData.begin(); - i != _xmpData.end(); - ++i) - { - if (i->key() == key) - { - values.append(i->toString()); - ++occurences; - } - } - if (occurences > 0) + throw Exiv2::Error(METADATA_NOT_READ); + } + + Exiv2::XmpKey xmpKey = Exiv2::XmpKey(key); + + if(_xmpData.findKey(xmpKey) == _xmpData.end()) + { + throw Exiv2::Error(KEY_NOT_FOUND, key); + } + + Exiv2::Xmpdatum xmpDatum = _xmpData[key]; + std::string sTagName = xmpKey.tagName(); + std::string sTagLabel = xmpKey.tagLabel(); + std::string sTagDesc(Exiv2::XmpProperties::propertyDesc(xmpKey)); + std::string sTagType(Exiv2::XmpProperties::propertyInfo(xmpKey)->xmpValueType_); + std::string sTagValue = xmpDatum.toString(); + return boost::python::make_tuple(key, sTagName, sTagLabel, sTagDesc, sTagType, sTagValue); +} + +/*void Image::setXmpTagValues(std::string key, boost::python::tuple values) +{ + if (!_dataRead) + { + throw Exiv2::Error(METADATA_NOT_READ); + } + + Exiv2::XmpKey xmpKey = Exiv2::XmpKey(key); + unsigned int index = 0; + unsigned int max = len(values); + Exiv2::XmpMetadata::iterator dataIterator = _xmpData.findKey(xmpKey); + while (index < max) + { + std::string value = boost::python::extract<std::string>(values[index++]); + if (dataIterator != _xmpData.end()) { - std::string sTagName = xmpKey.tagName(); - std::string sTagLabel = xmpKey.tagLabel(); - std::string sTagDesc(Exiv2::XmpProperties::propertyDesc(xmpKey)); - std::string sTagType(Exiv2::XmpProperties::propertyInfo(xmpKey)->xmpValueType_); - return boost::python::make_tuple(key, sTagName, sTagLabel, sTagDesc, sTagType, values); + // Override an existing value + dataIterator->setValue(value); + dataIterator = std::find_if(++dataIterator, _xmpData.end(), + Exiv2::FindMetadatumById::FindMetadatumById(xmpKey.tag(), + xmpKey.record())); } else { - throw Exiv2::Error(KEY_NOT_FOUND, key); + // Append a new value + Exiv2::Iptcdatum iptcDatum(iptcKey); + iptcDatum.setValue(value); + int state = _iptcData.add(iptcDatum); + if (state == 6) + { + throw Exiv2::Error(NON_REPEATABLE); + } } } - else + // Erase the remaining values if any + while (dataIterator != _iptcData.end()) { - throw Exiv2::Error(METADATA_NOT_READ); + _iptcData.erase(dataIterator); + dataIterator = std::find_if(dataIterator, _iptcData.end(), + Exiv2::FindMetadatumById::FindMetadatumById(iptcKey.tag(), + iptcKey.record())); } -} +}*/ /* boost::python::tuple Image::getThumbnailData() diff --git a/src/exiv2wrapper.hpp b/src/exiv2wrapper.hpp index 3dfd850..0e66f50 100644 --- a/src/exiv2wrapper.hpp +++ b/src/exiv2wrapper.hpp @@ -95,13 +95,8 @@ public: // tagvalue (list) boost::python::tuple getIptcTag(std::string key); - // Set the IPTC tag's value. If the tag was not previously set, it is + // Set the IPTC tag's values. If the tag was not previously set, it is // created. - // If the key references a repeatable tag, the parameter index (starting - // from 0 like a list index) is used to determine which of the - // repetitions is to be set. In case of an index greater than the - // highest existing one, adds a repetition of the tag. - //void setIptcTag(std::string key, std::string value, unsigned int index); void setIptcTagValues(std::string key, boost::python::tuple values); // Delete (all the repetitions of) the required IPTC tag. @@ -118,6 +113,8 @@ public: // tagvalue (list) boost::python::tuple getXmpTag(std::string key); + void setXmpTagValues(std::string key, boost::python::tuple values); + // Read and write access to the thumbnail embedded in the image. // Return a tuple containing the format of the thumbnail ("TIFF" or diff --git a/src/pyexiv2.py b/src/pyexiv2.py index 63202da..65bcce7 100644 --- a/src/pyexiv2.py +++ b/src/pyexiv2.py @@ -541,8 +541,8 @@ class IptcTag(MetadataTag): def _set_values(self, new_values): if self.metadata is not None: - raw_value = map(lambda x: IptcTag._convert_to_string(x, self.xtype), new_values) - self.metadata._set_iptc_tag_values(self.key, raw_value) + raw_values = map(lambda x: IptcTag._convert_to_string(x, self.xtype), new_values) + self.metadata._set_iptc_tag_values(self.key, raw_values) self._values = new_values def _del_values(self): @@ -720,12 +720,30 @@ class XmpTag(MetadataTag): _time_re = r'(?P<hours>\d{2})(:(?P<minutes>\d{2})(:(?P<seconds>\d{2})(.(?P<decimal>\d+))?)?(?P<tzd>%s))?' % _time_zone_re _date_re = re.compile(r'(?P<year>\d{4})(-(?P<month>\d{2})(-(?P<day>\d{2})(T(?P<time>%s))?)?)?' % _time_re) - def __init__(self, key, name, label, description, xtype, values): + def __init__(self, key, name, label, description, xtype, value): """ Constructor. """ - super(XmpTag, self).__init__(key, name, label, description, xtype, values) - self.values = map(lambda x: XmpTag._convert_to_python(x, xtype), values) + super(XmpTag, self).__init__(key, name, label, description, xtype, value) + self._value = XmpTag._convert_to_python(value, xtype) + + def _get_value(self): + return self._value + + def _set_value(self, new_value): + if self.metadata is not None: + raw_value = XmpTag._convert_to_string(new_value, self.xtype) + self.metadata._set_xmp_tag_value(self.key, raw_value) + self._value = new_value + + def _del_value(self): + if self.metadata is not None: + self.metadata._delete_xmp_tag(self.key) + del self._value + + # DOCME + value = property(fget=_get_value, fset=_set_value, fdel=_del_value, + doc=None) @staticmethod def _convert_to_python(value, xtype): @@ -1132,10 +1150,13 @@ class ImageMetadata(object): self._image.setIptcTagValues(key, values) def _set_xmp_tag(self, tag): - # TODO - raise NotImplementedError() + if type(tag) is not XmpTag: + raise TypeError('Expecting an XmpTag') + self._image.setXmpTagValue(tag.key, tag.to_string()) + self._tags['xmp'][tag.key] = tag + tag.metadata = self - def _set_xmp_tag_values(self, key, values): + def _set_xmp_tag_value(self, key, value): # Overwrite the tag value for an already existing tag. # The tag is already in cache. # Warning: this is not meant to be called directly as it doesn't update |