aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/exiv2wrapper_python.cpp6
-rw-r--r--src/pyexiv2.py60
-rwxr-xr-xunittest/TestsRunner.py2
-rw-r--r--unittest/metadata.py110
4 files changed, 175 insertions, 3 deletions
diff --git a/src/exiv2wrapper_python.cpp b/src/exiv2wrapper_python.cpp
index 4c171bd..7d6867b 100644
--- a/src/exiv2wrapper_python.cpp
+++ b/src/exiv2wrapper_python.cpp
@@ -54,18 +54,18 @@ BOOST_PYTHON_MODULE(libexiv2python)
// .def("writeMetadata", &Image::writeMetadata)
.def("exifKeys", &Image::exifKeys)
- .def("_Image__getExifTag", &Image::getExifTag)
+ .def("getExifTag", &Image::getExifTag)
// .def("_Image__getExifTagToString", &Image::getExifTagToString)
// .def("_Image__setExifTag", &Image::setExifTag)
// .def("_Image__deleteExifTag", &Image::deleteExifTag)
.def("iptcKeys", &Image::iptcKeys)
- .def("_Image__getIptcTag", &Image::getIptcTag)
+ .def("getIptcTag", &Image::getIptcTag)
// .def("_Image__setIptcTag", &Image::setIptcTag)
// .def("_Image__deleteIptcTag", &Image::deleteIptcTag)
.def("xmpKeys", &Image::xmpKeys)
- .def("_Image__getXmpTag", &Image::getXmpTag)
+ .def("getXmpTag", &Image::getXmpTag)
// .def("tagDetails", &Image::tagDetails)
diff --git a/src/pyexiv2.py b/src/pyexiv2.py
index b1e7dfc..46128ea 100644
--- a/src/pyexiv2.py
+++ b/src/pyexiv2.py
@@ -941,6 +941,66 @@ class XmpTag(MetadataTag):
return r
+class ImageMetadata(object):
+
+ """
+ DOCME
+ """
+
+ def __init__(self, filename):
+ self.filename = filename
+ if type(filename) is unicode:
+ self.filename = filename.encode('utf-8')
+ self._image = None
+ self._keys = {'exif': None, 'iptc': None, 'xmp': None}
+ self._tags = {'exif': {}, 'iptc': {}, 'xmp': {}}
+
+ def _instantiate_image(self, filename):
+ # This method is meant to be overridden in unit tests to easily replace
+ # the internal image reference by a mock.
+ return libexiv2python.Image(filename)
+
+ def read(self):
+ """
+ DOCME
+ """
+ if self._image is None:
+ self._image = self._instantiate_image(self.filename)
+ self._image.readMetadata()
+
+ def write(self):
+ """
+ DOCME
+ """
+ self._image.writeMetadata()
+
+ @property
+ def exif_keys(self):
+ if self._keys['exif'] is None:
+ self._keys['exif'] = self._image.exifKeys()
+ return self._keys['exif']
+
+ @property
+ def iptc_keys(self):
+ if self._keys['iptc'] is None:
+ self._keys['iptc'] = self._image.iptcKeys()
+ return self._keys['iptc']
+
+ @property
+ def xmp_keys(self):
+ if self._keys['xmp'] is None:
+ self._keys['xmp'] = self._image.xmpKeys()
+ return self._keys['xmp']
+
+ def _get_exif_tag(self, key):
+ try:
+ return self._tags['exif'][key]
+ except KeyError:
+ tag = ExifTag(*self._image.getExifTag(key))
+ self._tags['exif'][key] = tag
+ return tag
+
+
class Image(libexiv2python.Image):
"""
diff --git a/unittest/TestsRunner.py b/unittest/TestsRunner.py
index db96cc3..d4f52dc 100755
--- a/unittest/TestsRunner.py
+++ b/unittest/TestsRunner.py
@@ -38,6 +38,7 @@ from rational import TestRational
from exif import TestExifTag
from iptc import TestIptcTag
from xmp import TestXmpTag
+from metadata import TestImageMetadata
if __name__ == '__main__':
@@ -53,5 +54,6 @@ if __name__ == '__main__':
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestExifTag))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestIptcTag))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestXmpTag))
+ suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestImageMetadata))
# Run the test suite
unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/unittest/metadata.py b/unittest/metadata.py
new file mode 100644
index 0000000..43f252e
--- /dev/null
+++ b/unittest/metadata.py
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+
+# ******************************************************************************
+#
+# Copyright (C) 2009 Olivier Tilloy <olivier@tilloy.net>
+#
+# This file is part of the pyexiv2 distribution.
+#
+# pyexiv2 is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# pyexiv2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyexiv2; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
+#
+# Author: Olivier Tilloy <olivier@tilloy.net>
+#
+# ******************************************************************************
+
+import unittest
+from pyexiv2 import ImageMetadata, ExifTag
+
+
+class ImageMock(object):
+
+ def __init__(self, filename):
+ self.filename = filename
+ self.read = False
+ self.written = False
+ self.tags = {'exif': {}, 'iptc': {}, 'xmp': {}}
+
+ def readMetadata(self):
+ self.read = True
+
+ def writeMetadata(self):
+ self.written = True
+
+ def exifKeys(self):
+ return self.tags['exif'].keys()
+
+ def getExifTag(self, key):
+ return self.tags['exif'][key]
+
+ def iptcKeys(self):
+ return self.tags['iptc'].keys()
+
+ def getIptcTag(self, key):
+ return self.tags['iptc'][key]
+
+ def xmpKeys(self):
+ return self.tags['xmp'].keys()
+
+ def getXmpTag(self, key):
+ return self.tags['xmp'][key]
+
+
+class TestImageMetadata(unittest.TestCase):
+
+ def setUp(self):
+ self.metadata = ImageMetadata('nofile')
+ self.metadata._instantiate_image = lambda filename: ImageMock(filename)
+
+ def _set_exif_tags(self):
+ tags = {}
+ tags['Exif.Image.Make'] = \
+ ('Exif.Image.Make', 'Make', 'Manufacturer', 'blabla', 'Ascii',
+ 'EASTMAN KODAK COMPANY', 'EASTMAN KODAK COMPANY')
+ tags['Exif.Image.DateTime'] = \
+ ('Exif.Image.DateTime', 'DateTime', 'Date and Time', 'blabla',
+ 'Ascii', '2009:02:09 13:33:20', '2009:02:09 13:33:20')
+ tags['Exif.Photo.ExifVersion'] = \
+ ('Exif.Photo.ExifVersion', 'ExifVersion', 'Exif Version', 'blabla',
+ 'Undefined', '48 50 50 49 ', '2.21')
+ self.metadata._image.tags['exif'] = tags
+
+ def test_read(self):
+ self.assertEqual(self.metadata._image, None)
+ self.metadata.read()
+ self.failIfEqual(self.metadata._image, None)
+ self.failUnless(self.metadata._image.read)
+
+ def test_write(self):
+ self.metadata.read()
+ self.failIf(self.metadata._image.written)
+ self.metadata.write()
+ self.failUnless(self.metadata._image.written)
+
+ def test_exif_keys(self):
+ self.metadata.read()
+ self._set_exif_tags()
+ self.assertEqual(self.metadata._keys['exif'], None)
+ keys = self.metadata.exif_keys
+ self.assertEqual(len(keys), 3)
+ self.assertEqual(self.metadata._keys['exif'], keys)
+
+ def test_get_exif_tag(self):
+ self.metadata.read()
+ self._set_exif_tags()
+ self.assertEqual(self.metadata._tags['exif'], {})
+ key = 'Exif.Image.Make'
+ tag = self.metadata._get_exif_tag(key)
+ self.assertEqual(type(tag), ExifTag)
+ self.assertEqual(self.metadata._tags['exif'][key], tag)