aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Tilloy <olivier@tilloy.net>2009-02-24 10:19:40 +0100
committerOlivier Tilloy <olivier@tilloy.net>2009-02-24 10:19:40 +0100
commit8ae2364a45e96c8afbb07ebb0499004092c1ba71 (patch)
treec8b2c2785e4202465eb76fbd246c7b5dfc4dac3f
parentd28e750d9810c7ddd89335efc50e591158c26da0 (diff)
downloadpyexiv2-8ae2364a45e96c8afbb07ebb0499004092c1ba71.tar.gz
IPTC Time conversion.
-rw-r--r--src/pyexiv2.py25
-rw-r--r--unittest/iptc.py19
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