diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2009-03-12 20:00:30 +0100 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2009-03-12 20:00:30 +0100 |
commit | 1fee371f1496cd2f13b410e00469b307dd56d703 (patch) | |
tree | 9175a751f78702ac7b37f11d691f4c1b784a5e40 | |
parent | 41eea2f150be218f5a4edd2fa1175fa333fdf385 (diff) | |
download | pyexiv2-1fee371f1496cd2f13b410e00469b307dd56d703.tar.gz |
First version of an ImageMetadata class, meant to replace the Image class.
-rw-r--r-- | src/exiv2wrapper_python.cpp | 6 | ||||
-rw-r--r-- | src/pyexiv2.py | 60 | ||||
-rwxr-xr-x | unittest/TestsRunner.py | 2 | ||||
-rw-r--r-- | unittest/metadata.py | 110 |
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) |