def update_preview(self, chooser, label, image): """Display photo thumbnail and geotag data in file chooser.""" label.set_label(self.strings.preview) image.set_from_stock(Gtk.STOCK_FILE, Gtk.IconSize.DIALOG) try: photo = Photograph(chooser.get_preview_filename(), 300) photo.read() except IOError: return image.set_from_pixbuf(photo.thumb) label.set_label( '\n'.join([photo.short_summary(), photo.maps_link()]))
def update_preview(self, chooser, label, image): """Display photo thumbnail and geotag data in file chooser.""" label.set_label(self.strings.preview) image.set_from_stock(Gtk.STOCK_FILE, Gtk.IconSize.DIALOG) try: photo = Photograph(chooser.get_preview_filename(), lambda x: None, 300) photo.read() except IOError: return image.set_from_pixbuf(photo.thumb) label.set_label('\n'.join([photo.short_summary(), photo.maps_link()]))
def load_img_from_file(self, uri): """Create or update a row in the ListStore. Checks if the file has already been loaded, and if not, creates a new row in the ListStore. Either way, it then populates that row with photo metadata as read from disk. Effectively, this is used both for loading new photos, and reverting old photos, discarding any changes. Raises IOError if filename refers to a file that is not a photograph. """ photo = photos.get(uri) or Photograph(uri, self.modify_summary) photo.read() if uri not in photos: photo.iter = self.liststore.append() photo.label = self.labels.add(uri) photos[uri] = photo photo.position_label() modified.discard(photo) self.liststore.set_row( photo.iter, [uri, photo.long_summary(), photo.thumb, photo.timestamp]) auto_timestamp_comparison(photo)
def test_string_functions(self): """Ensure that strings print properly.""" environ['TZ'] = 'America/Edmonton' tzset() # Make a photo with a dummy ChamplainLabel. label = Struct() label.get_text = lambda: DEMOFILES[5] photo = Photograph(label.get_text(), lambda x: None) photo.read() photo.label = label photo.latitude = None photo.longitude = None self.assertEqual(photo.pretty_coords(), 'Not geotagged') photo.latitude = 10.0 photo.longitude = 10.0 self.assertEqual(photo.pretty_coords(), 'N 10.00000, E 10.00000') photo.latitude = -10.0 photo.longitude = -10.0 self.assertEqual(photo.pretty_coords(), 'S 10.00000, W 10.00000') photo.timestamp = None self.assertIsNone(photo.pretty_time()) photo.timestamp = 999999999 self.assertEqual(photo.pretty_time(), '2001-09-08 07:46:39 PM') photo.altitude = None self.assertIsNone(photo.pretty_elevation()) photo.altitude = -10.20005 self.assertEqual(photo.pretty_elevation(), '10.2m below sea level') photo.altitude = 600.71 self.assertEqual(photo.pretty_elevation(), '600.7m above sea level') self.assertEqual(photo.short_summary(), """2001-09-08 07:46:39 PM S 10.00000, W 10.00000 600.7m above sea level""") self.assertEqual(photo.long_summary(), """<span size="larger">IMG_2411.JPG</span> <span style="italic" size="smaller">2001-09-08 07:46:39 PM S 10.00000, W 10.00000 600.7m above sea level</span>""") self.assertRegexpMatches( get_obj('maps_link').get_label(), r'href="http://maps.google.com' )
def test_demo_data(self): """Load the demo data and ensure that we're reading it in properly.""" # Start with a fresh state. system('git checkout demo') self.assertEqual(len(points), 0) self.assertEqual(len(polygons), 0) self.assertEqual(app.metadata.alpha, float('inf')) self.assertEqual(app.metadata.omega, float('-inf')) # No buttons should be sensitive yet because nothing's loaded. buttons = {} for button in ('save', 'revert', 'apply', 'close', 'clear'): buttons[button] = get_obj(button + '_button') self.assertFalse(buttons[button].get_sensitive()) # Load only the photos first. for filename in DEMOFILES: if filename[-3:] != 'gpx': self.assertRaises(IOError, gui.load_gpx_from_file, filename) gui.load_img_from_file(filename) # Nothing is yet selected or modified, so buttons still insensitive. for button in buttons.values(): self.assertFalse(button.get_sensitive()) # Something loaded in the liststore? self.assertEqual(len(gui.liststore), 6) self.assertTrue(gui.liststore.get_iter_first()) for photo in photos.values(): self.assertFalse(photo in modified) self.assertFalse(photo in selected) self.assertFalse(photo.label.get_property('visible')) # Pristine demo data shouldn't have any tags. self.assertIsNone(photo.altitude) self.assertIsNone(photo.latitude) self.assertIsNone(photo.longitude) self.assertFalse(photo.manual) # Test that missing the provincestate doesn't break the geoname. photo.latitude = 47.56494 photo.longitude = -52.70931 photo.lookup_geoname() self.assertEqual(photo.pretty_geoname(), "St. John's,\nNewfoundland and Labrador,\nCanada") photo.set_geodata(['Anytown', None, 'US', 'timezone']) self.assertEqual(photo.pretty_geoname(), 'Anytown, United States') self.assertEqual(photo.timezone, 'timezone') # Add some crap photo.manual = True photo.latitude = 10.0 photo.altitude = 650 photo.longitude = 45.0 self.assertTrue(photo.valid_coords()) # photo.read() should discard all the crap we added above. # This is in response to a bug where I was using pyexiv2 wrongly # and it would load data from disk without discarding old data. photo.read() self.assertEqual(photo.pretty_geoname(), '') self.assertIsNone(photo.altitude) self.assertIsNone(photo.latitude) self.assertIsNone(photo.longitude) self.assertFalse(photo.valid_coords()) self.assertFalse(photo.manual) self.assertEqual(photo.filename, photo.label.get_name()) self.assertEqual(photo.timestamp, gui.liststore.get_value(photo.iter, app.TIMESTAMP)) # Test the select-all button. select_all = get_obj('select_all_button') select_all.set_active(True) self.assertEqual(len(selected), len(gui.liststore)) select_all.set_active(False) self.assertEqual(len(selected), 0) # Load the GPX gpx_filename=join(PKG_DATA_DIR, '..', 'demo', '20101016.gpx') self.assertRaises(IOError, gui.load_img_from_file, gpx_filename) gui.load_gpx_from_file(gpx_filename) self.assertTrue(buttons['clear'].get_sensitive()) gui.labels.selection.emit('changed') # Check that the GPX is loaded self.assertEqual(len(points), 374) self.assertEqual(len(polygons), 1) self.assertEqual(app.metadata.alpha, 1287259751) self.assertEqual(app.metadata.omega, 1287260756) # The save button should be sensitive because loading GPX modifies # photos, but nothing is selected so the others are insensitive. self.assertTrue(buttons['save'].get_sensitive()) for button in ('revert', 'apply', 'close'): self.assertFalse(buttons[button].get_sensitive()) for photo in photos.values(): self.assertTrue(photo in modified) self.assertIsNotNone(photo.latitude) self.assertIsNotNone(photo.longitude) self.assertTrue(photo.valid_coords()) self.assertTrue(photo.label.get_property('visible')) # Unload the GPX data. buttons['clear'].emit('clicked') self.assertEqual(len(points), 0) self.assertEqual(len(polygons), 0) self.assertFalse(buttons['clear'].get_sensitive()) # Save all photos buttons['save'].emit('clicked') self.assertEqual(len(modified), 0) for button in ('save', 'revert'): self.assertFalse(buttons[button].get_sensitive()) gui.labels.selection.select_all() self.assertEqual(len(selected), 6) for button in ('save', 'revert'): self.assertFalse(buttons[button].get_sensitive()) for button in ('apply', 'close'): self.assertTrue(buttons[button].get_sensitive()) # Close all the photos. files = [photo.filename for photo in selected] buttons['close'].emit('clicked') for button in ('save', 'revert', 'apply', 'close'): self.assertFalse(buttons[button].get_sensitive()) self.assertEqual(len(photos), 0) self.assertEqual(len(modified), 0) self.assertEqual(len(selected), 0) # Re-read the photos back from disk to make sure that the saving # was successful. for filename in files: photo = Photograph(filename, lambda x: None) photo.read() self.assertTrue(photo.valid_coords()) self.assertGreater(photo.altitude, 600) self.assertEqual(photo.pretty_geoname(), 'Edmonton, Alberta, Canada')
def test_string_functions(self): """Ensure that strings print properly.""" environ['TZ'] = 'America/Edmonton' tzset() # Make a photo with a dummy ChamplainLabel. label = Struct() label.get_text = lambda: DEMOFILES[5] label.get_parent = lambda: None photo = Photograph(label.get_text()) photo.read() photo.label = label photo.latitude = None photo.longitude = None self.assertEqual(photo.pretty_coords(), 'Not geotagged') photo.latitude = 10.0 photo.longitude = 10.0 self.assertEqual(photo.pretty_coords(), 'N 10.00000, E 10.00000') photo.latitude = -10.0 photo.longitude = -10.0 self.assertEqual(photo.pretty_coords(), 'S 10.00000, W 10.00000') photo.timestamp = None self.assertIsNone(photo.pretty_time()) photo.timestamp = 999999999 self.assertEqual(photo.pretty_time(), '2001-09-08 07:46:39 PM') photo.altitude = None self.assertIsNone(photo.pretty_elevation()) photo.altitude = -10.20005 self.assertEqual(photo.pretty_elevation(), '10.2m below sea level') photo.altitude = 600.71 self.assertEqual(photo.pretty_elevation(), '600.7m above sea level') self.assertEqual(photo.short_summary(), """2001-09-08 07:46:39 PM S 10.00000, W 10.00000 600.7m above sea level""") self.assertEqual(photo.long_summary(), """<span size="larger">IMG_2411.JPG</span> <span style="italic" size="smaller">2001-09-08 07:46:39 PM S 10.00000, W 10.00000 600.7m above sea level</span>""")
def test_demo_data(self): """Load the demo data and ensure that we're reading it in properly.""" self.assertEqual(len(points), 0) self.assertEqual(len(known_trackfiles), 0) self.assertEqual(app.metadata.alpha, float('inf')) self.assertEqual(app.metadata.omega, float('-inf')) # No buttons should be sensitive yet because nothing's loaded. buttons = {} for button in ('save', 'revert', 'close'): buttons[button] = get_obj(button + '_button') self.assertFalse(buttons[button].get_sensitive()) # Load only the photos first. for filename in DEMOFILES: if filename[-3:] != 'gpx': self.assertRaises(IOError, gui.load_gpx_from_file, filename) gui.open_files([filename]) # Nothing is yet selected or modified, so buttons still insensitive. for button in buttons.values(): self.assertFalse(button.get_sensitive()) # Something loaded in the liststore? self.assertEqual(len(gui.liststore), 6) self.assertTrue(gui.liststore.get_iter_first()) for photo in photos.values(): self.assertFalse(photo in modified) self.assertFalse(photo in selected) # Pristine demo data shouldn't have any tags. self.assertIsNone(photo.altitude) self.assertIsNone(photo.latitude) self.assertIsNone(photo.longitude) self.assertFalse(photo.manual) # Test that missing the provincestate doesn't break the geoname. photo.latitude = 47.56494 photo.longitude = -52.70931 photo.lookup_geoname() self.assertEqual(photo.pretty_geoname(), "St. John's, Newfoundland and Labrador, Canada") photo.set_geodata(['Anytown', None, 'US', 'timezone']) self.assertEqual(photo.pretty_geoname(), 'Anytown, United States') self.assertEqual(photo.timezone, 'timezone') # Add some crap photo.manual = True photo.latitude = 10.0 photo.altitude = 650 photo.longitude = 45.0 self.assertTrue(photo.valid_coords()) # photo.read() should discard all the crap we added above. # This is in response to a bug where I was using pyexiv2 wrongly # and it would load data from disk without discarding old data. photo.read() self.assertEqual(photo.pretty_geoname(), '') self.assertIsNone(photo.altitude) self.assertIsNone(photo.latitude) self.assertIsNone(photo.longitude) self.assertFalse(photo.valid_coords()) self.assertFalse(photo.manual) self.assertEqual(photo.filename, photo.label.get_name()) # Load the GPX gpx_filename = join(PKG_DATA_DIR, '..', 'demo', '20101016.gpx') self.assertRaises(IOError, gui.load_img_from_file, gpx_filename) gui.open_files([gpx_filename]) gui.labels.selection.emit('changed') # Check that the GPX is loaded self.assertEqual(len(points), 374) self.assertEqual(len(known_trackfiles), 1) self.assertEqual(app.metadata.alpha, 1287259751) self.assertEqual(app.metadata.omega, 1287260756) # The save button should be sensitive because loading GPX modifies # photos, but nothing is selected so the others are insensitive. self.assertTrue(buttons['save'].get_sensitive()) for button in ('revert', 'close'): self.assertFalse(buttons[button].get_sensitive()) for photo in photos.values(): self.assertTrue(photo in modified) self.assertIsNotNone(photo.latitude) self.assertIsNotNone(photo.longitude) self.assertTrue(photo.valid_coords()) self.assertTrue(photo.label.get_property('visible')) # Unload the GPX data. clear_all_gpx() self.assertEqual(len(points), 0) self.assertEqual(len(known_trackfiles), 0) # Save all photos buttons['save'].emit('clicked') self.assertEqual(len(modified), 0) for button in ('save', 'revert'): self.assertFalse(buttons[button].get_sensitive()) gui.labels.selection.select_all() self.assertEqual(len(selected), 6) for button in ('save', 'revert'): self.assertFalse(buttons[button].get_sensitive()) self.assertTrue(buttons['close'].get_sensitive()) # Close all the photos. files = [photo.filename for photo in selected] buttons['close'].emit('clicked') for button in ('save', 'revert', 'close'): self.assertFalse(buttons[button].get_sensitive()) self.assertEqual(len(photos), 0) self.assertEqual(len(modified), 0) self.assertEqual(len(selected), 0) # Re-read the photos back from disk to make sure that the saving # was successful. for filename in files: photo = Photograph(filename) photo.read() self.assertTrue(photo.valid_coords()) self.assertGreater(photo.altitude, 600) self.assertEqual(photo.pretty_geoname(), 'Edmonton, Alberta, Canada')