def test_exif(self): # datetime d = datetime.datetime(1899, 12, 31) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 00:00:00') d = datetime.datetime(1899, 12, 31, 23) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:00:00') d = datetime.datetime(1899, 12, 31, 23, 59) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:59:00') d = datetime.datetime(1899, 12, 31, 23, 59, 59) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:59:59') d = datetime.datetime(1899, 12, 31, 23, 59, 59, 999999) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:59:59') d = datetime.datetime(1899, 12, 31, 23, 59, 59, tzinfo=FixedOffset()) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:59:59') d = datetime.datetime(1899, 12, 31, 23, 59, 59, tzinfo=FixedOffset(hours=5)) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31 23:59:59') d = datetime.datetime(2011, 8, 8, 19, 3, 37) self.assertEqual(DateTimeFormatter.exif(d), '2011:08:08 19:03:37') # date d = datetime.date(1899, 12, 31) self.assertEqual(DateTimeFormatter.exif(d), '1899:12:31') d = datetime.date(2011, 8, 8) self.assertEqual(DateTimeFormatter.exif(d), '2011:08:08') # invalid type self.assertRaises(TypeError, DateTimeFormatter.exif, None) self.assertRaises(TypeError, DateTimeFormatter.exif, 3.14)
def _convert_to_string(self, value): """ Convert one value to its corresponding string representation, suitable to pass to libexiv2. :param value: the value to be converted :return: the value converted to its corresponding string representation :rtype: string :raise ExifValueError: if the conversion fails """ if self.type == 'Ascii': if isinstance(value, datetime.datetime): return DateTimeFormatter.exif(value) elif isinstance(value, datetime.date): if self.key == 'Exif.GPSInfo.GPSDateStamp': # Special case return DateTimeFormatter.exif(value) else: return '%s 00:00:00' % DateTimeFormatter.exif(value) elif isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: raise ExifValueError(value, self.type) elif self.type in ('Byte', 'SByte'): if isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: try: return(str(value)) except: raise ExifValueError(value, self.type) elif self.type == 'Comment': if value is not None and self.raw_value is not None and \ self.raw_value.startswith('charset='): charset, val = self.raw_value.split(' ', 1) charset = charset.split('=')[1].strip('"') encoding = self._match_encoding(charset) try: val = value.encode(encoding) except UnicodeError: # Best effort, do not fail just because the original # encoding of the tag cannot encode the new value. pass else: return 'charset="%s" %s' % (charset, val) if isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: raise ExifValueError(value, self.type) elif self.type == 'Short': if isinstance(value, int) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SShort': if isinstance(value, int): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Long': if isinstance(value, (int, long)) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SLong': if isinstance(value, (int, long)): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Rational': if is_fraction(value) and value.numerator >= 0: return fraction_to_string(value) else: try: return(str(value)) except: raise ExifValueError(value, self.type) elif self.type == 'SRational': if is_fraction(value): return fraction_to_string(value) else: try: return(str(value)) except: raise ExifValueError(value, self.type) elif self.type == 'Undefined': if isinstance(value, unicode): try: return string_to_undefined(value.encode('utf-8')) except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return string_to_undefined(value) else: raise ExifValueError(value, self.type) raise ExifValueError(value, self.type)
def test_exif_invalid(bad_ts): with pytest.raises(TypeError): DateTimeFormatter.exif(bad_ts)
def test_exif_valid(formatted, ts): assert DateTimeFormatter.exif(ts) == formatted
def _convert_to_string(self, value): """ Convert one value to its corresponding string representation, suitable to pass to libexiv2. :param value: the value to be converted :return: the value converted to its corresponding string representation :rtype: string :raise ExifValueError: if the conversion fails """ if self.type == 'Ascii': if isinstance(value, datetime.datetime): return DateTimeFormatter.exif(value) elif isinstance(value, datetime.date): if self.key == 'Exif.GPSInfo.GPSDateStamp': # Special case return DateTimeFormatter.exif(value) else: return '%s 00:00:00' % DateTimeFormatter.exif(value) else: return value elif self.type in ('Byte', 'SByte'): if isinstance(value, str): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, bytes): return value else: raise ExifValueError(value, self.type) elif self.type == 'Comment': return self._convert_to_bytes(value) elif self.type == 'Short': if isinstance(value, int) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SShort': if isinstance(value, int): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Long': if isinstance(value, int) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SLong': if isinstance(value, int): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Rational': if is_fraction(value) and value.numerator >= 0: return fraction_to_string(value) else: raise ExifValueError(value, self.type) elif self.type == 'SRational': if is_fraction(value): return fraction_to_string(value) else: raise ExifValueError(value, self.type) elif self.type == 'Undefined': if isinstance(value, str): try: return string_to_undefined(value) except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, bytes): return string_to_undefined(value) else: raise ExifValueError(value, self.type) raise ExifValueError(value, self.type)
def _convert_to_string(self, value): """ Convert one value to its corresponding string representation, suitable to pass to libexiv2. :param value: the value to be converted :return: the value converted to its corresponding string representation :rtype: string :raise ExifValueError: if the conversion fails """ if self.type == 'Ascii': if isinstance(value, datetime.datetime): return DateTimeFormatter.exif(value) elif isinstance(value, datetime.date): if self.key == 'Exif.GPSInfo.GPSDateStamp': # Special case return DateTimeFormatter.exif(value) else: return '%s 00:00:00' % DateTimeFormatter.exif(value) elif isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: raise ExifValueError(value, self.type) elif self.type in ('Byte', 'SByte'): if isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: raise ExifValueError(value, self.type) elif self.type == 'Comment': if value is not None and self.raw_value is not None and \ self.raw_value.startswith('charset='): charset, val = self.raw_value.split(' ', 1) charset = charset.split('=')[1].strip('"') encoding = self._match_encoding(charset) try: val = value.encode(encoding) except UnicodeError: # Best effort, do not fail just because the original # encoding of the tag cannot encode the new value. pass else: return 'charset="%s" %s' % (charset, val) if isinstance(value, unicode): try: return value.encode('utf-8') except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return value else: raise ExifValueError(value, self.type) elif self.type == 'Short': if isinstance(value, int) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SShort': if isinstance(value, int): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Long': if isinstance(value, (int, long)) and value >= 0: return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'SLong': if isinstance(value, (int, long)): return str(value) else: raise ExifValueError(value, self.type) elif self.type == 'Rational': if is_fraction(value) and value.numerator >= 0: return fraction_to_string(value) else: raise ExifValueError(value, self.type) elif self.type == 'SRational': if is_fraction(value): return fraction_to_string(value) else: raise ExifValueError(value, self.type) elif self.type == 'Undefined': if isinstance(value, unicode): try: return string_to_undefined(value.encode('utf-8')) except UnicodeEncodeError: raise ExifValueError(value, self.type) elif isinstance(value, str): return string_to_undefined(value) else: raise ExifValueError(value, self.type) raise ExifValueError(value, self.type)