diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2009-02-24 10:19:40 +0100 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2009-02-24 10:19:40 +0100 |
commit | 8ae2364a45e96c8afbb07ebb0499004092c1ba71 (patch) | |
tree | c8b2c2785e4202465eb76fbd246c7b5dfc4dac3f | |
parent | d28e750d9810c7ddd89335efc50e591158c26da0 (diff) | |
download | pyexiv2-8ae2364a45e96c8afbb07ebb0499004092c1ba71.tar.gz |
IPTC Time conversion.
-rw-r--r-- | src/pyexiv2.py | 25 | ||||
-rw-r--r-- | unittest/iptc.py | 19 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/pyexiv2.py b/src/pyexiv2.py index bf78535..46a1e6c 100644 --- a/src/pyexiv2.py +++ b/src/pyexiv2.py @@ -445,6 +445,11 @@ class IptcTag(MetadataTag): property). """ + # strptime is not flexible enough to handle all valid Time formats, we use a + # custom regular expression + _time_zone_re = r'(?P<sign>\+|-)(?P<ohours>\d{2}):(?P<ominutes>\d{2})' + _time_re = re.compile(r'(?P<hours>\d{2}):(?P<minutes>\d{2}):(?P<seconds>\d{2})(?P<tzd>%s)' % _time_zone_re) + def __init__(self, key, name, label, description, xtype, values): """ Constructor. @@ -506,6 +511,26 @@ class IptcTag(MetadataTag): except ValueError: raise IptcValueError(value, xtype) + elif xtype == 'Time': + # According to the IPTC specification, the format for a string field + # representing a time is '%H%M%S±%H%M'. However, the string returned + # by exiv2 using method TimeValue::toString() is formatted using + # pattern '%H:%M:%S±%H:%M'. + match = IptcTag._time_re.match(value) + if match is None: + raise IptcValueError(value, xtype) + gd = match.groupdict() + try: + tzinfo = FixedOffset(gd['sign'], int(gd['ohours']), + int(gd['ominutes'])) + except TypeError: + raise IptcValueError(value, xtype) + try: + return datetime.time(int(gd['hours']), int(gd['minutes']), + int(gd['seconds']), tzinfo=tzinfo) + except (TypeError, ValueError): + raise IptcValueError(value, xtype) + # TODO: other types raise NotImplementedError('IPTC conversion for type [%s]' % xtype) diff --git a/unittest/iptc.py b/unittest/iptc.py index c339da0..43e5313 100644 --- a/unittest/iptc.py +++ b/unittest/iptc.py @@ -25,7 +25,7 @@ # ****************************************************************************** import unittest -from pyexiv2 import IptcTag, IptcValueError +from pyexiv2 import IptcTag, IptcValueError, FixedOffset import datetime @@ -65,4 +65,21 @@ class TestIptcTag(unittest.TestCase): self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '2009-10-32', xtype) self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '2009-02-24T22:12:54', xtype) + def test_convert_to_python_time(self): + xtype = 'Time' + # Valid values + self.assertEqual(IptcTag._convert_to_python('05:03:54+00:00', xtype), + datetime.time(5, 3, 54, tzinfo=FixedOffset())) + self.assertEqual(IptcTag._convert_to_python('05:03:54+06:00', xtype), + datetime.time(5, 3, 54, tzinfo=FixedOffset('+', 6, 0))) + self.assertEqual(IptcTag._convert_to_python('05:03:54-10:30', xtype), + datetime.time(5, 3, 54, tzinfo=FixedOffset('-', 10, 30))) + # Invalid values + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, 'invalid', xtype) + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '23:12:42', xtype) + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '25:12:42+00:00', xtype) + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '21:77:42+00:00', xtype) + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '21:12:98+00:00', xtype) + self.failUnlessRaises(IptcValueError, IptcTag._convert_to_python, '081242+0000', xtype) + # TODO: other types |