Ejemplo n.º 1
0
 def read(self):
     """Load exif data from disk."""
     self.exif      = ImageMetadata(self.filename)
     self.timestamp = None
     self.altitude  = None
     self.latitude  = None
     self.longitude = None
     self.timezone  = None
     self.manual    = False
     try:
         self.exif.read()
     except TypeError:
         raise IOError
     
     self.camera = get_camera(self)
     
     # Try to get a thumbnail.
     try:
         self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size(
                 self.filename, self.thm_size, self.thm_size)
     except GObject.GError:
         if len(self.exif.previews) > 0:
             data = self.exif.previews[-1].data
         elif len(self.exif.exif_thumbnail.data) > 0:
             data = self.exif.exif_thumbnail.data
         else:
             raise IOError
         
         self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale(
             Gio.MemoryInputStream.new_from_data(data, None),
             self.thm_size, self.thm_size, True, None)
     
     # If we're reloading, then hide the label and clear the ListStore,
     # but if we're loading afresh then we'll need a new iter...
     if self.label is not None:
         self.label.hide()
     if self.thm_size < 250:
         if self.iter is None:
             self.iter = self.liststore.append()
         self.liststore.set_row(self.iter,
             [self.filename, self.long_summary(), self.thumb, self.timestamp])
     
     self.calculate_timestamp()
     try:
         self.latitude = dms_to_decimal(
             *self.exif[GPS + 'Latitude'].value +
             [self.exif[GPS + 'LatitudeRef'].value]
         )
         self.longitude = dms_to_decimal(
             *self.exif[GPS + 'Longitude'].value +
             [self.exif[GPS + 'LongitudeRef'].value]
         )
     except KeyError:
         pass
     try:
         self.altitude = float(self.exif[GPS + 'Altitude'].value)
         if int(self.exif[GPS + 'AltitudeRef'].value) > 0:
             self.altitude *= -1
     except KeyError:
         pass
Ejemplo n.º 2
0
 def read(self):
     """Discard all state and (re)initialize from disk."""
     self.exif = fetch_exif(self.filename)
     self.manual = False
     self.modified_timeout = None
     self.latitude = 0.0
     self.longitude = 0.0
     self.altitude = 0.0
     self.timestamp = 0
     
     self.names = (None, None, None)
     self.geotimezone = ''
     
     try:
         self.orig_time = self.exif[
             'Exif.Photo.DateTimeOriginal'].value.timetuple()
     except KeyError:
         pass
     
     try:
         self.latitude = dms_to_decimal(
             *self.exif[GPS + 'Latitude'].value +
             [self.exif[GPS + 'LatitudeRef'].value]
         )
         self.longitude = dms_to_decimal(
             *self.exif[GPS + 'Longitude'].value +
             [self.exif[GPS + 'LongitudeRef'].value]
         )
     except KeyError:
         pass
     try:
         self.altitude = float(self.exif[GPS + 'Altitude'].value)
         if int(self.exif[GPS + 'AltitudeRef'].value) > 0:
             self.altitude *= -1
     except KeyError:
         pass
     
     modified.discard(self)
     self.calculate_timestamp()
     
     if self.iter is None:
         self.iter = Widgets.loaded_photos.append()
     Widgets.loaded_photos.set_row(self.iter, [self.filename,
                                               str(self),
                                               self.thumb,
                                               self.timestamp])
     
     # Get the camera info
     self.camera_info = {'Make': '', 'Model': ''}
     keys = ['Exif.Image.' + key for key in self.camera_info.keys()
                 + ['CameraSerialNumber']] + ['Exif.Photo.BodySerialNumber']
     for key in keys:
         try:
             self.camera_info.update(
                 {key.split('.')[-1]: self.exif[key].value})
         except KeyError:
             pass
Ejemplo n.º 3
0
 def read(self):
     """Load exif data from disk."""
     self.exif      = ImageMetadata(self.filename)
     self.timestamp = None
     self.altitude  = None
     self.latitude  = None
     self.longitude = None
     self.timezone  = None
     self.manual    = False
     try:
         self.exif.read()
     except TypeError:
         raise IOError
     
     Camera(self.exif)
     
     # Try to get a thumbnail.
     try:
         self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size(
                 self.filename, self.thm_size, self.thm_size)
     except GObject.GError:
         if len(self.exif.previews) > 0:
             data = self.exif.previews[-1].data
         elif len(self.exif.exif_thumbnail.data) > 0:
             data = self.exif.exif_thumbnail.data
         else:
             raise IOError
         
         self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale(
             Gio.MemoryInputStream.new_from_data(data, None),
             self.thm_size, self.thm_size, True, None)
     
     self.calculate_timestamp()
     try:
         self.latitude = dms_to_decimal(
             *self.exif[GPS + 'Latitude'].value +
             [self.exif[GPS + 'LatitudeRef'].value]
         )
         self.longitude = dms_to_decimal(
             *self.exif[GPS + 'Longitude'].value +
             [self.exif[GPS + 'LongitudeRef'].value]
         )
     except KeyError:
         pass
     try:
         self.altitude = float(self.exif[GPS + 'Altitude'].value)
         if int(self.exif[GPS + 'AltitudeRef'].value) > 0:
             self.altitude *= -1
     except KeyError:
         pass
Ejemplo n.º 4
0
    def read(self):
        """Load exif data from disk."""
        self.exif = ImageMetadata(self.filename)
        self.timestamp = None
        self.altitude = None
        self.latitude = None
        self.longitude = None
        self.timezone = None
        self.manual = False
        try:
            self.exif.read()
        except TypeError:
            raise IOError

        Camera(self.exif)

        # Try to get a thumbnail.
        try:
            self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size(
                self.filename, self.thm_size, self.thm_size)
        except GObject.GError:
            if len(self.exif.previews) > 0:
                data = self.exif.previews[-1].data
            elif len(self.exif.exif_thumbnail.data) > 0:
                data = self.exif.exif_thumbnail.data
            else:
                raise IOError

            self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale(
                Gio.MemoryInputStream.new_from_data(data, None), self.thm_size,
                self.thm_size, True, None)

        self.calculate_timestamp()
        try:
            self.latitude = dms_to_decimal(
                *self.exif[GPS + 'Latitude'].value +
                [self.exif[GPS + 'LatitudeRef'].value])
            self.longitude = dms_to_decimal(
                *self.exif[GPS + 'Longitude'].value +
                [self.exif[GPS + 'LongitudeRef'].value])
        except KeyError:
            pass
        try:
            self.altitude = float(self.exif[GPS + 'Altitude'].value)
            if int(self.exif[GPS + 'AltitudeRef'].value) > 0:
                self.altitude *= -1
        except KeyError:
            pass
Ejemplo n.º 5
0
    def test_gps_math(self):
        """Test coordinate conversion functions."""
        rats_to_fracs = lambda rats: [Fraction(rat.to_float()) for rat in rats]

        # Really important that this method is bulletproof
        self.assertFalse(valid_coords(None, None))
        self.assertFalse(valid_coords('', ''))
        self.assertFalse(valid_coords(True, True))
        self.assertFalse(valid_coords(False, False))
        self.assertFalse(valid_coords(45, 270))
        self.assertFalse(valid_coords(100, 50))
        self.assertFalse(valid_coords([], 50))
        self.assertFalse(valid_coords(45, {'grunt':42}))
        self.assertFalse(valid_coords(self, 50))
        self.assertFalse(valid_coords(45, valid_coords))
        self.assertFalse(valid_coords("ya", "dun goofed"))

        # St. John's broke the math. I'm not sure why.
        # Seriously. Revert commit 362dd6eb and watch this explode.
        stjohns = Coordinates()
        stjohns.latitude = 47.56494
        stjohns.longitude = -52.70931
        stjohns.lookup_geoname()
        self.assertEqual(stjohns.city, "St. John's")

        # Pick 100 random coordinates on the globe, convert them from decimal
        # to sexagesimal and then back, and ensure that they are always equal.
        for _ in range(100):
            # Oh, and test altitudes too
            altitude = round(random_coord(1000), 6)
            fraction = float_to_rational(altitude)
            self.assertAlmostEqual(
                abs(altitude),
                fraction.numerator / fraction.denominator,
                3
            )

            decimal_lat = round(random_coord(80),  6)
            decimal_lon = round(random_coord(180), 6)

            self.assertTrue(valid_coords(decimal_lat, decimal_lon))

            dms_lat = decimal_to_dms(decimal_lat)
            dms_lon = decimal_to_dms(decimal_lon)

            self.assertEqual(len(dms_lat), 3)
            self.assertEqual(
                dms_lat[0].numerator,
                floor(abs(decimal_lat))
            )

            self.assertEqual(len(dms_lon), 3)
            self.assertEqual(
                dms_lon[0].numerator,
                floor(abs(decimal_lon))
            )

            self.assertAlmostEqual(
                decimal_lat,
                dms_to_decimal(*rats_to_fracs(dms_lat) + ['N' if decimal_lat >= 0 else 'S']),
                10 # equal to 10 places
            )
            self.assertAlmostEqual(
                decimal_lon,
                dms_to_decimal(*rats_to_fracs(dms_lon) + ['E' if decimal_lon >= 0 else 'W']),
                10 # equal to 10 places
            )
Ejemplo n.º 6
0
 def test_gps_math(self):
     """Test coordinate conversion functions."""
     rats_to_fracs = lambda rats: [Fraction(rat.to_float()) for rat in rats]
     
     # Really important that this method is bulletproof
     self.assertFalse(valid_coords(None, None))
     self.assertFalse(valid_coords('', ''))
     self.assertFalse(valid_coords(True, True))
     self.assertFalse(valid_coords(False, False))
     self.assertFalse(valid_coords(45, 270))
     self.assertFalse(valid_coords(100, 50))
     self.assertFalse(valid_coords([], 50))
     self.assertFalse(valid_coords(45, {'grunt':42}))
     self.assertFalse(valid_coords(self, 50))
     self.assertFalse(valid_coords(45, valid_coords))
     self.assertFalse(valid_coords("ya", "dun goofed"))
     
     # St. John's broke the math. I'm not sure why.
     # Seriously. Revert commit 362dd6eb and watch this explode.
     stjohns = Coordinates()
     stjohns.latitude = 47.56494
     stjohns.longitude = -52.70931
     stjohns.lookup_geoname()
     self.assertEqual(stjohns.city, "St. John's")
     
     # Pick 100 random coordinates on the globe, convert them from decimal
     # to sexagesimal and then back, and ensure that they are always equal.
     for i in range(100):
         # Oh, and test altitudes too
         altitude = round(random_coord(1000), 6)
         fraction = float_to_rational(altitude)
         self.assertAlmostEqual(
             abs(altitude),
             fraction.numerator / fraction.denominator,
             3
         )
         
         decimal_lat = round(random_coord(80),  6)
         decimal_lon = round(random_coord(180), 6)
         
         self.assertTrue(valid_coords(decimal_lat, decimal_lon))
         
         dms_lat = decimal_to_dms(decimal_lat)
         dms_lon = decimal_to_dms(decimal_lon)
         
         self.assertEqual(len(dms_lat), 3)
         self.assertEqual(
             dms_lat[0].numerator,
             floor(abs(decimal_lat))
         )
         
         self.assertEqual(len(dms_lon), 3)
         self.assertEqual(
             dms_lon[0].numerator,
             floor(abs(decimal_lon))
         )
         
         self.assertAlmostEqual(
             decimal_lat,
             dms_to_decimal(*rats_to_fracs(dms_lat) + ['N' if decimal_lat >= 0 else 'S']),
             10 # equal to 10 places
         )
         self.assertAlmostEqual(
             decimal_lon,
             dms_to_decimal(*rats_to_fracs(dms_lon) + ['E' if decimal_lon >= 0 else 'W']),
             10 # equal to 10 places
         )