def close_selected_photos(self, button=None): """Discard all selected photos.""" for photo in selected.copy(): self.labels.layer.remove_marker(photo.label) del photos[photo.filename] modified.discard(photo) self.liststore.remove(photo.iter) self.labels.select_all.set_active(False)
def destroy(self): """Agony!""" self.label.unmap() self.label.destroy() self.camera.photos.discard(self) del photos[self.filename] modified.discard(self) self.liststore.remove(self.iter)
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
def destroy(self): """Agony!""" self.update_derived_properties() # To clear any callback... # TODO: Disconnect this from here if self in Label.cache: Label(self).destroy() if self.camera is not None: self.camera.remove_photo(self) modified.discard(self) if self.iter: Widgets.loaded_photos.remove(self.iter) del Photograph.cache[self.filename]
def write(self): """Save exif data to photo file on disk.""" if self.altitude is not None: self.exif[GPS + 'Altitude'] = float_to_rational(self.altitude) self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' self.exif[GPS + 'Latitude'] = decimal_to_dms(self.latitude) self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' self.exif[GPS + 'MapDatum'] = 'WGS-84' self.exif.write() modified.discard(self) self.liststore.set_value(self.iter, 1, self.long_summary())
def write(self): """Save exif data to photo file on disk.""" self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' self.exif[GPS + 'Altitude'] = Fraction(self.altitude) self.exif[GPS + 'Latitude'] = decimal_to_dms(self.latitude) self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' self.exif[GPS + 'MapDatum'] = 'WGS-84' self.exif[IPTC + 'City'] = [self.names[0] or ''] self.exif[IPTC + 'ProvinceState'] = [self.names[1] or ''] self.exif[IPTC + 'CountryName'] = [self.names[2] or ''] self.exif.write() modified.discard(self) Widgets.loaded_photos.set_value(self.iter, 1, str(self))
def save_all_files(self, widget=None): """Ensure all loaded files are saved.""" self.progressbar.show() total = len(modified) for i, photo in enumerate(list(modified), 1): self.redraw_interface(i / total, basename(photo.filename)) try: photo.write() except Exception as inst: self.status_message(str(inst)) else: modified.discard(photo) self.liststore.set_value(photo.iter, SUMMARY, photo.long_summary()) self.progressbar.hide() self.labels.selection.emit('changed')
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 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) photo.read() if uri not in photos: photo.label = self.labels.add(uri) photos[uri] = photo # If the user has selected the lookup method, then the timestamp # was probably calculated incorrectly the first time (before the # timezone was discovered). So call it again to get the correct value. if photo.camera.gst.get_string('timezone-method') == 'lookup': photo.calculate_timestamp() modified.discard(photo)
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)