Exemplo n.º 1
0
 def test_read_only(self):
     r = GPSCoordinate(62, 58, 2, 'W')
     try:
         r.degrees = 5
     except AttributeError:
         pass
     else:
         self.fail('Degrees is not read-only.')
     try:
         r.minutes = 5
     except AttributeError:
         pass
     else:
         self.fail('Minutes is not read-only.')
     try:
         r.seconds = 5
     except AttributeError:
         pass
     else:
         self.fail('Seconds is not read-only.')
     try:
         r.direction = 'S'
     except AttributeError:
         pass
     else:
         self.fail('Direction is not read-only.')
Exemplo n.º 2
0
 def test_from_string(self):
     self.assertEqual(GPSCoordinate.from_string('54,59.380000N'),
                      GPSCoordinate(54, 59, 23, 'N'))
     self.assertEqual(GPSCoordinate.from_string('1,54.850000W'),
                      GPSCoordinate(1, 54, 51, 'W'))
     self.assertRaises(ValueError, GPSCoordinate.from_string, '51N')
     self.assertRaises(ValueError, GPSCoordinate.from_string, '48 24 3 S')
     self.assertRaises(ValueError, GPSCoordinate.from_string, '48°24\'3"S')
     self.assertRaises(ValueError, GPSCoordinate.from_string, 'invalid')
Exemplo n.º 3
0
 def test_from_string(self):
     self.assertEqual(GPSCoordinate.from_string('54,59.380000N'),
                      GPSCoordinate(54, 59, 23, 'N'))
     self.assertEqual(GPSCoordinate.from_string('1,54.850000W'),
                      GPSCoordinate(1, 54, 51, 'W'))
     self.assertRaises(ValueError, GPSCoordinate.from_string, '51N')
     self.assertRaises(ValueError, GPSCoordinate.from_string, '48 24 3 S')
     self.assertRaises(ValueError, GPSCoordinate.from_string, '48°24\'3"S')
     self.assertRaises(ValueError, GPSCoordinate.from_string, 'invalid')
Exemplo n.º 4
0
 def test_constructor(self):
     r = GPSCoordinate(62, 58, 2, 'W')
     self.assertEqual(r.degrees, 62)
     self.assertEqual(r.minutes, 58)
     self.assertEqual(r.seconds, 2)
     self.assertEqual(r.direction, 'W')
     r = GPSCoordinate(92, 58, 2, 'W')
     self.assertEqual(r.degrees, 92)
     self.assertEqual(r.minutes, 58)
     self.assertEqual(r.seconds, 2)
     self.assertEqual(r.direction, 'W')
     self.assertRaises(ValueError, GPSCoordinate, -23, 58, 2, 'W')
     self.assertRaises(ValueError, GPSCoordinate, 91, 58, 2, 'S')
     self.assertRaises(ValueError, GPSCoordinate, 62, -23, 2, 'W')
     self.assertRaises(ValueError, GPSCoordinate, 62, 61, 2, 'W')
     self.assertRaises(ValueError, GPSCoordinate, 62, 58, -23, 'W')
     self.assertRaises(ValueError, GPSCoordinate, 62, 58, 61, 'W')
     self.assertRaises(ValueError, GPSCoordinate, 62, 58, 2, 'A')
Exemplo n.º 5
0
 def test_read_only(self):
     r = GPSCoordinate(62, 58, 2, 'W')
     try:
         r.degrees = 5
     except AttributeError:
         pass
     else:
         self.fail('Degrees is not read-only.')
     try:
         r.minutes = 5
     except AttributeError:
         pass
     else:
         self.fail('Minutes is not read-only.')
     try:
         r.seconds = 5
     except AttributeError:
         pass
     else:
         self.fail('Seconds is not read-only.')
     try:
         r.direction = 'S'
     except AttributeError:
         pass
     else:
         self.fail('Direction is not read-only.')
Exemplo n.º 6
0
    def _convert_to_python(self, value, type_):
        """Convert a raw value to its corresponding python type.

        Args:
        value -- the raw value to be converted
        type_ -- the simple type of the raw value

        Return: the value converted to its corresponding python type

        Raise XmpValueError: if the conversion fails
        """
        if type_ == 'Boolean':
            if value == 'True':
                return True

            elif value == 'False':
                return False

            else:
                raise XmpValueError(value, type_)

        elif type_ == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type_)

            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])

            else:
                month = 1

            if gd['day'] is not None:
                day = int(gd['day'])

            else:
                day = 1

            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type_)

            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type_)

                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])

                else:
                    seconds = 0

                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)

                else:
                    microseconds = 0

                if gd['tzd'] == 'Z':
                    tzinfo = FixedOffset()

                else:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))

                try:
                    return datetime.datetime(int(gd['year']), month, day,
                                             int(gd['hours']),
                                             int(gd['minutes']), seconds,
                                             microseconds, tzinfo)
                except ValueError:
                    raise XmpValueError(value, type_)

        elif type_ == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type_)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type_)

        elif type_ == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('AgentName', 'ProperName', 'Text'):
            if isinstance(value, bytes):
                try:
                    value = str(value, 'utf-8')
                except TypeError:
                    raise XmpValueError(value, type_)
            return value

        elif type_ == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('URI', 'URL'):
            if isinstance(value, bytes):
                try:
                    value = value.decode('utf-8')
                except UnicodeDecodeError:
                    # Unknow encoding, return the raw value
                    pass
            return value

        elif type_ == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        raise NotImplementedError('XMP conversion for type [%s]' % type_)
Exemplo n.º 7
0
 def test_to_string(self):
     self.assertEqual(str(GPSCoordinate(54, 59, 23, 'N')), '54,59,23N')
Exemplo n.º 8
0
def test_from_string_invalid(bad_str):
    with pytest.raises(ValueError):
        GPS.from_string(bad_str)
Exemplo n.º 9
0
def test_from_string_valid(str, deg, min, sec, dir):
    assert GPS.from_string(str) == GPS(deg, min, sec, dir)
Exemplo n.º 10
0
 }),
 ('Xmp.exif.ApertureValue', FRt, FR(8, 1)),
 ('Xmp.exif.BrightnessValue', FRt, FR(333, 1280)),
 ('Xmp.exif.ColorSpace', int, 1),
 ('Xmp.exif.DateTimeOriginal', Dt, DT(2002, 7, 13, 15, 58, 28)),
 ('Xmp.exif.ExifVersion', str, '0200'),
 ('Xmp.exif.ExposureBiasValue', FRt, FR(-13, 20)),
 ('Xmp.exif.ExposureProgram', int, 4),
 ('Xmp.exif.FNumber', FRt, FR(3, 5)),
 ('Xmp.exif.FileSource', int, 0),
 ('Xmp.exif.FlashpixVersion', str, '0100'),
 ('Xmp.exif.FocalLength', FRt, FR(0, 1)),
 ('Xmp.exif.FocalPlaneResolutionUnit', int, 2),
 ('Xmp.exif.FocalPlaneXResolution', FRt, FR(3085, 256)),
 ('Xmp.exif.FocalPlaneYResolution', FRt, FR(3085, 256)),
 ('Xmp.exif.GPSLatitude', GPS, GPS.from_string('54,59.380000N')),
 ('Xmp.exif.GPSLongitude', GPS, GPS.from_string('1,54.850000W')),
 ('Xmp.exif.GPSMapDatum', str, 'WGS84'),
 ('Xmp.exif.GPSTimeStamp', Dt, DT(2002, 7, 13, 14, 58, 24)),
 ('Xmp.exif.GPSVersionID', str, '2.0.0.0'),
 ('Xmp.exif.ISOSpeedRatings', list, [0]),
 ('Xmp.exif.MeteringMode', int, 5),
 ('Xmp.exif.PixelXDimension', int, 2400),
 ('Xmp.exif.PixelYDimension', int, 1600),
 ('Xmp.exif.SceneType', int, 0),
 ('Xmp.exif.SensingMethod', int, 2),
 ('Xmp.exif.ShutterSpeedValue', FRt, FR(30827, 3245)),
 ('Xmp.pdf.Keywords', str, 'Communications'),
 ('Xmp.photoshop.AuthorsPosition', str, 'Photographer'),
 ('Xmp.photoshop.CaptionWriter', str, 'Ian Britton'),
 ('Xmp.photoshop.Category', str, 'BUS'),
Exemplo n.º 11
0
    def _convert_to_python(self, value, type_):
        """Convert a raw value to its corresponding python type.

        Args:
        value -- the raw value to be converted
        type_ -- the simple type of the raw value

        Return: the value converted to its corresponding python type

        Raise XmpValueError: if the conversion fails
        """
        if type_ == 'Boolean':
            if value == 'True':
                return True

            elif value == 'False':
                return False

            else:
                raise XmpValueError(value, type_)

        elif type_ == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type_)

            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])

            else:
                month = 1

            if gd['day'] is not None:
                day = int(gd['day'])

            else:
                day = 1

            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type_)

            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type_)

                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])

                else:
                    seconds = 0

                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)

                else:
                    microseconds = 0

                if gd['tzd'] is not None and gd[
                        'tzd'] == 'Z' and gd['sign'] is None and gd[
                            'ohours'] is None and gd['ominutes'] is None:
                    tzinfo = FixedOffset()

                elif gd['sign'] is not None and gd[
                        'ohours'] is not None and gd['ominutes'] is not None:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))
                else:
                    tzinfo = None
                    # TODO: Decide if following is way to hande
                    # ======================================================================
                    # ERROR: test_convert_to_python_date (xmp.TestXmpTag)
                    # ----------------------------------------------------------------------
                    # Traceback (most recent call last):
                    #   File "c:\Users\BSFau\Cloudstation\BSFsoftDev\axternal\py3exiv2\py3exiv2\test\xmp.py", line 91, in test_convert_to_python_date
                    #     datetime.datetime(1999, 10, 13, 5, 3, tzinfo=FixedOffset()),
                    # TypeError: can't subtract offset-naive and offset-aware datetimes
                    # ----------------------------------------------------------------------

                    # u_tm = datetime.datetime.utcfromtimestamp(0)
                    # l_tm = datetime.datetime.fromtimestamp(0)
                    # tzinfo = datetime.timezone(l_tm - u_tm)
                try:
                    if tzinfo is not None:
                        return datetime.datetime(int(gd['year']), month, day,
                                                 int(gd['hours']),
                                                 int(gd['minutes']), seconds,
                                                 microseconds, tzinfo)
                    else:
                        return datetime.datetime(int(gd['year']), month, day,
                                                 int(gd['hours']),
                                                 int(gd['minutes']), seconds,
                                                 microseconds)

                except ValueError:
                    raise XmpValueError(value, type_)

        elif type_ == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type_)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type_)

        elif type_ == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('AgentName', 'ProperName', 'Text'):
            if isinstance(value, bytes):
                try:
                    value = str(value, 'utf-8')
                except TypeError:
                    raise XmpValueError(value, type_)
            return value

        elif type_ == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('URI', 'URL'):
            if isinstance(value, bytes):
                try:
                    value = value.decode('utf-8')
                except UnicodeDecodeError:
                    # Unknow encoding, return the raw value
                    pass
            return value

        elif type_ == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        raise NotImplementedError('XMP conversion for type [%s]' % type_)
Exemplo n.º 12
0
    def _convert_to_python(self, value, type):
        """
        Convert a raw value to its corresponding python type.

        :param value: the raw value to be converted
        :type value: string
        :param type: the simple type of the raw value
        :type type: string

        :return: the value converted to its corresponding python type

        :raise XmpValueError: if the conversion fails
        """
        if type == 'Boolean':
            if value == 'True':
                return True
            elif value == 'False':
                return False
            else:
                raise XmpValueError(value, type)

        elif type == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type)
            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])
            else:
                month = 1
            if gd['day'] is not None:
                day = int(gd['day'])
            else:
                day = 1
            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type)
            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type)
                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])
                else:
                    seconds = 0
                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)
                else:
                    microseconds = 0
                if gd['tzd'] == 'Z':
                    tzinfo = FixedOffset()
                else:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))
                try:
                    return datetime.datetime(int(gd['year']), month, day,
                                             int(gd['hours']), int(gd['minutes']),
                                             seconds, microseconds, tzinfo)
                except ValueError:
                    raise XmpValueError(value, type)

        elif type == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type)

        elif type == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type in ('AgentName', 'ProperName', 'Text'):
            try:
                return unicode(value, 'utf-8')
            except TypeError:
                raise XmpValueError(value, type)

        elif type == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type in ('URI', 'URL'):
            return value

        elif type == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        raise NotImplementedError('XMP conversion for type [%s]' % type)