Instead of re- inventing the wheel, used the existing wheel. Used conv_lat_lon() from PlaceUtils to handle GPS Coordinates.

svn: r18014
This commit is contained in:
Rob G. Healey 2011-08-08 23:59:06 +00:00
parent b46a74df36
commit 36aa9f3c86

View File

@ -260,17 +260,6 @@ class EditExifMetadata(Gramplet):
self.dbstate.db.connect('media-update', self.update) self.dbstate.db.connect('media-update', self.update)
self.connect_signal('Media', self.update) self.connect_signal('Media', self.update)
def __build_shaded_tree(self):
"""
Build the GUI interface.
"""
top = gtk.TreeView()
titles = [(_('Key'), 1, 180),
(_('Value'), 2, 310)]
self.model = ListModel(top, titles, list_mode ="tree")
return top
def __build_gui(self): def __build_gui(self):
""" """
will display all exif metadata and all buttons. will display all exif metadata and all buttons.
@ -359,7 +348,8 @@ class EditExifMetadata(Gramplet):
new_hbox.pack_start(button, expand =False, fill =True, padding =5) new_hbox.pack_start(button, expand =False, fill =True, padding =5)
# add viewing model # add viewing model
main_vbox.pack_start(self.__build_shaded_tree(), expand =False, fill =True, padding =5) self.view = MetadataView()
main_vbox.pack_start(self.view, expand =False, fill =True, padding =5)
# Separator line before the Total # Separator line before the Total
main_vbox.pack_start(gtk.HSeparator(), expand =False, fill =True, padding =5) main_vbox.pack_start(gtk.HSeparator(), expand =False, fill =True, padding =5)
@ -394,7 +384,6 @@ class EditExifMetadata(Gramplet):
# Help will never be disabled # Help will never be disabled
""" """
db = self.dbstate.db db = self.dbstate.db
self.model.clear
# deactivate all buttons except Help # deactivate all buttons except Help
self.deactivate_buttons(["Convert", "Edit", "ImageTypes", "Delete"]) self.deactivate_buttons(["Convert", "Edit", "ImageTypes", "Delete"])
@ -408,6 +397,9 @@ class EditExifMetadata(Gramplet):
for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]: for widget in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
self.exif_widgets[widget].set_text("") self.exif_widgets[widget].set_text("")
# set Message Ares to Select
self.exif_widgets["MessageArea"].set_text(_("Select an image to begin..."))
active_handle = self.get_active("Media") active_handle = self.get_active("Media")
if not active_handle: if not active_handle:
self.set_has_data(False) self.set_has_data(False)
@ -425,6 +417,15 @@ class EditExifMetadata(Gramplet):
self.set_has_data(False) self.set_has_data(False)
return return
# check image read privileges
_readable = os.access(self.image_path, os.R_OK)
if not _readable:
self.exif_widgets["MessageArea"].set_text(_("Image is NOT readable,\n"
"Please choose a different image..."))
return
### No longer any reason to return because of errors ###
# display file description/ title # display file description/ title
self.exif_widgets["MediaLabel"].set_text(_html_escape(self.orig_image.get_description())) self.exif_widgets["MediaLabel"].set_text(_html_escape(self.orig_image.get_description()))
@ -432,14 +433,6 @@ class EditExifMetadata(Gramplet):
mime_type = self.orig_image.get_mime_type() mime_type = self.orig_image.get_mime_type()
self.exif_widgets["MimeType"].set_text(gen.mime.get_description(mime_type)) self.exif_widgets["MimeType"].set_text(gen.mime.get_description(mime_type))
# check image read privileges
_readable = os.access(self.image_path, os.R_OK)
if not _readable:
self.exif_widgets["MessageArea"].set_text(_("Image is NOT readable,\n"
"Please choose a different image..."))
self.set_has_data(False)
return
# check image write privileges # check image write privileges
_writable = os.access(self.image_path, os.W_OK) _writable = os.access(self.image_path, os.W_OK)
if not _writable: if not _writable:
@ -450,57 +443,45 @@ class EditExifMetadata(Gramplet):
# get dirpath/ basename, and extension # get dirpath/ basename, and extension
self.basename, self.extension = os.path.splitext(self.image_path) self.basename, self.extension = os.path.splitext(self.image_path)
# not a exiv2 compatible image type... if (mime_type and mime_type.startswith("image/")):
if self.extension not in _VALIDIMAGEMAP.values():
# Convert message if self.extension not in _VALIDIMAGEMAP.values():
self.exif_widgets["MessageArea"].set_text(_("Please convert this "
"image to an Exiv2- compatible image type..."))
imgtype_format = _validconvert # Convert message
self._VCONVERTMAP = dict((index, imgtype) for index, imgtype in enumerate(imgtype_format)) self.exif_widgets["MessageArea"].set_text(_("Please convert this "
"image to an Exiv2- compatible image type..."))
for index in xrange(1, len(imgtype_format) ): imgtype_format = _validconvert
self.exif_widgets["ImageTypes"].append_text(imgtype_format[index]) self._VCONVERTMAP = dict((index, imgtype) for index, imgtype in enumerate(imgtype_format))
self.exif_widgets["ImageTypes"].set_active(0)
self.activate_buttons(["ImageTypes"]) for index in xrange(1, len(imgtype_format) ):
self.exif_widgets["ImageTypes"].append_text(imgtype_format[index])
self.exif_widgets["ImageTypes"].set_active(0)
if mime_type: self.activate_buttons(["ImageTypes"])
if mime_type.startswith("image/"):
# creates, and reads the plugin image instance
self.plugin_image = self.setup_image(self.image_path)
if self.plugin_image:
# get image width and height
if not OLD_API:
self.exif_widgets["ImageSize"].show()
width, height = self.plugin_image.dimensions
self.exif_widgets["ImageSize"].set_text(_("Image "
"Size : %04d x %04d pixels") % (width, height) )
# check for thumbnails
has_thumb = self.__check4thumbnails()
if has_thumb:
self.activate_buttons(["Thumbnail"])
# display all Exif tags for this image,
# XmpTag and IptcTag has been purposefully excluded
self.__display_exif_tags(self.image_path)
# activate these buttons
self.activate_buttons(["Edit"])
# has mime, but not an image
else: else:
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image...")) # creates, and reads the plugin image instance
return self.plugin_image = self.setup_image(self.image_path)
# has no mime # activate Edit button
else: self.activate_buttons(["Edit"])
self.exif_widgets["MessageArea"].set_text(_("Please choose a different image..."))
return # get image width and height
if not OLD_API:
self.exif_widgets["ImageSize"].show()
width, height = self.plugin_image.dimensions
self.exif_widgets["ImageSize"].set_text(_("Image "
"Size : %04d x %04d pixels") % (width, height) )
# check for thumbnails
has_thumb = self.__check4thumbnails()
if has_thumb:
self.activate_buttons(["Thumbnail"])
# display all Exif tags for this image,
# XmpTag and IptcTag has been purposefully excluded
self.__display_exif_tags(self.image_path)
def __check4thumbnails(self): def __check4thumbnails(self):
""" """
@ -524,8 +505,10 @@ class EditExifMetadata(Gramplet):
""" """
Display the exif tags. Display the exif tags.
""" """
self.exif_widgets["MessageArea"].set_text(_("Displaying Exif metadata..."))
# display exif tags in the treeview # display exif tags in the treeview
has_data = MetadataView().display_exif_tags(full_path) has_data = self.view.display_exif_tags(full_path)
# update set_has_data functionality # update set_has_data functionality
self.set_has_data(has_data) self.set_has_data(has_data)
@ -957,13 +940,12 @@ class EditExifMetadata(Gramplet):
self._setup_widget_tips(fields =True, buttons = True) self._setup_widget_tips(fields =True, buttons = True)
# display all data fields and their values... # display all data fields and their values...
self.edit_area() self.edit_area(_get_exif_keypairs(self.plugin_image) )
def __build_edit_gui(self): def __build_edit_gui(self):
""" """
will build the edit screen ... will build the edit screen ...
""" """
main_vbox = gtk.VBox() main_vbox = gtk.VBox()
main_vbox.set_border_width(10) main_vbox.set_border_width(10)
main_vbox.set_size_request(480, 460) main_vbox.set_size_request(480, 460)
@ -1161,7 +1143,6 @@ class EditExifMetadata(Gramplet):
""" """
Handles the Delete Dialog... Handles the Delete Dialog...
""" """
QuestionDialog(_("Edit Image Exif Metadata"), _("WARNING! You are about to completely " QuestionDialog(_("Edit Image Exif Metadata"), _("WARNING! You are about to completely "
"delete the Exif metadata from this image?"), _("Delete"), "delete the Exif metadata from this image?"), _("Delete"),
self.strip_metadata) self.strip_metadata)
@ -1192,79 +1173,78 @@ class EditExifMetadata(Gramplet):
for widget in _TOOLTIPS.keys(): for widget in _TOOLTIPS.keys():
self.exif_widgets[widget].set_text("") self.exif_widgets[widget].set_text("")
def edit_area(self, mediadatatags =None): def edit_area(self, mediadatatags):
""" """
displays the image Exif metadata in the Edit Area... displays the image Exif metadata in the Edit Area...
""" """
if mediadatatags is None: if mediadatatags:
mediadatatags = _get_exif_keypairs(self.plugin_image) mediadatatags = [key for key in mediadatatags if key in _DATAMAP]
mediadatatags = [key for key in mediadatatags if key in _DATAMAP]
for key in mediadatatags: for key in mediadatatags:
widget = _DATAMAP[key] widget = _DATAMAP[key]
tag_value = self.__get_value(key) tag_value = self.__get_value(key)
if tag_value: if tag_value:
if widget in ["Description", "Artist", "Copyright"]: if widget in ["Description", "Artist", "Copyright"]:
self.exif_widgets[widget].set_text(tag_value) self.exif_widgets[widget].set_text(tag_value)
# Last Changed/ Modified... # Last Changed/ Modified...
elif widget in ["Modified", "Original"]: elif widget in ["Modified", "Original"]:
use_date = format_datetime(tag_value) use_date = format_datetime(tag_value)
if use_date: if use_date:
self.exif_widgets[widget].set_text(use_date) self.exif_widgets[widget].set_text(use_date)
# set Modified Datetime to non-editable... # set Modified Datetime to non-editable...
if (widget == "Modified" and use_date): if (widget == "Modified" and use_date):
self.exif_widgets[widget].set_editable(False) self.exif_widgets[widget].set_editable(False)
# LatitudeRef, Latitude, LongitudeRef, Longitude... # LatitudeRef, Latitude, LongitudeRef, Longitude...
elif widget == "Latitude": elif widget == "Latitude":
latitude, longitude = tag_value, self.__get_value(_DATAMAP["Longitude"]) latitude, longitude = tag_value, self.__get_value(_DATAMAP["Longitude"])
# if latitude and longitude exist, display them? # if latitude and longitude exist, display them?
if (latitude and longitude): if (latitude and longitude):
# split latitude metadata into (degrees, minutes, and seconds) # split latitude metadata into (degrees, minutes, and seconds)
latdeg, latmin, latsec = rational_to_dms(latitude) latdeg, latmin, latsec = rational_to_dms(latitude)
# split longitude metadata into degrees, minutes, and seconds # split longitude metadata into degrees, minutes, and seconds
longdeg, longmin, longsec = rational_to_dms(longitude) longdeg, longmin, longsec = rational_to_dms(longitude)
# check to see if we have valid GPS coordinates? # check to see if we have valid GPS coordinates?
latfail = any(coords == False for coords in [latdeg, latmin, latsec]) latfail = any(coords == False for coords in [latdeg, latmin, latsec])
longfail = any(coords == False for coords in [longdeg, longmin, longsec]) longfail = any(coords == False for coords in [longdeg, longmin, longsec])
if (not latfail and not longfail): if (not latfail and not longfail):
# Latitude Direction Reference # Latitude Direction Reference
latref = self.__get_value(_DATAMAP["LatitudeRef"] ) latref = self.__get_value(_DATAMAP["LatitudeRef"] )
# Longitude Direction Reference # Longitude Direction Reference
longref = self.__get_value(_DATAMAP["LongitudeRef"] ) longref = self.__get_value(_DATAMAP["LongitudeRef"] )
# set display for Latitude GPS coordinates # set display for Latitude GPS coordinates
latitude = """%s° %s %s%s""" % (latdeg, latmin, latsec, latref) latitude = """%s° %s %s%s""" % (latdeg, latmin, latsec, latref)
self.exif_widgets["Latitude"].set_text(latitude) self.exif_widgets["Latitude"].set_text(latitude)
# set display for Longitude GPS coordinates # set display for Longitude GPS coordinates
longitude = """%s° %s %s%s""" % (longdeg, longmin, longsec, longref) longitude = """%s° %s %s%s""" % (longdeg, longmin, longsec, longref)
self.exif_widgets["Longitude"].set_text(longitude) self.exif_widgets["Longitude"].set_text(longitude)
self.exif_widgets["Latitude"].validate() self.exif_widgets["Latitude"].validate()
self.exif_widgets["Longitude"].validate() self.exif_widgets["Longitude"].validate()
elif widget == "Altitude": elif widget == "Altitude":
altitude = tag_value altitude = tag_value
altref = self.__get_value(_DATAMAP["AltitudeRef"]) altref = self.__get_value(_DATAMAP["AltitudeRef"])
if (altitude and altref): if (altitude and altref):
altitude = convert_value(altitude) altitude = convert_value(altitude)
if altitude: if altitude:
if altref == "1": if altref == "1":
altitude = "-" + altitude altitude = "-" + altitude
self.exif_widgets[widget].set_text(altitude) self.exif_widgets[widget].set_text(altitude)
# Media Object Title... # Media Object Title...
self.media_title = self.orig_image.get_description() self.media_title = self.orig_image.get_description()
@ -1300,13 +1280,6 @@ class EditExifMetadata(Gramplet):
else: else:
plugininstance.write() plugininstance.write()
def close_window(self, widgetWindow):
"""
closes the window title by widgetWindow.
"""
lambda w: widgetWindow.destroy()
def convert_format(self, latitude, longitude, format): def convert_format(self, latitude, longitude, format):
""" """
Convert GPS coordinates into a specified format. Convert GPS coordinates into a specified format.
@ -1339,6 +1312,7 @@ class EditExifMetadata(Gramplet):
and sets the key = widgetvaluee image metadata and sets the key = widgetvaluee image metadata
""" """
db = self.dbstate.db db = self.dbstate.db
addon_widgets = [(widget) for widget in _TOOLTIPS.keys() if widget not in ["MediaTitle", "EditMessage"] ]
mediatitle = self.exif_widgets["MediaTitle"].get_text() mediatitle = self.exif_widgets["MediaTitle"].get_text()
description = self.exif_widgets["Description"].get_text() description = self.exif_widgets["Description"].get_text()
@ -1356,17 +1330,15 @@ class EditExifMetadata(Gramplet):
len(longitude) + len(longitude) +
len(altitude) ) len(altitude) )
if not mediadatatags: if not mediadatatags:
widgets4clearing = [(widget) for widget in _TOOLTIPS.key()
if widget not in ["MediaTitle", "EditMessage"] ]
for widgetname in widgets4clearing: for widgetname in addon_widgets:
self.__set_value(_DATAMAP[widgetname], '') self.__set_value(_DATAMAP[widgetname], '')
# set Edit Message to Cleared... # set Edit Message to Cleared...
self.exif_widgets["EditMessage"].set_text(_("All Exif metadata has been cleared...")) self.exif_widgets["EditMessage"].set_text(_("All Exif metadata has been cleared..."))
else: else:
for widgetname in _TOOLTIPS.keys(): for widgetname in addon_widgets:
# Update dynamically updated Modified field... # Update dynamically updated Modified field...
if widgetname == "Modified": if widgetname == "Modified":
@ -1402,39 +1374,23 @@ class EditExifMetadata(Gramplet):
# Latitude/ Longitude... # Latitude/ Longitude...
elif widgetname == "Latitude": elif widgetname == "Latitude":
if (latitude and longitude): if (latitude and longitude):
if (latitude.count(" ") == longitude.count(" ") == 0):
latitude, longitude = self.convert2dms(latitude, longitude) latitude, longitude = self.convert2dms(latitude, longitude)
if (latitude and longitude):
# remove symbols before saving...
latitude, longitude = _removesymbolsb4saving(latitude, longitude)
# split Latitude/ Longitude into its (d, m, s, dir)...
latitude = coordinate_splitup(latitude)
longitude = coordinate_splitup(longitude)
if "N" in latitude:
latref = "N" latref = "N"
elif "S" in latitude: if "-" in latitude:
latref = "S" latref = "S"
elif "-" in latitude: latitude = latitude.replace("-", "")
latref = "-"
latitude.remove(latref)
if latref == "-": latref = "S"
if "E" in longitude:
longref = "E" longref = "E"
elif "W" in longitude: if "-" in longitude:
longref = "W" longref = "W"
elif "-" in longitude: longitude = longitude.replace("-", "")
longref = "-"
longitude.remove(longref)
if longref == "-": longref = "W" # convert Latitude/ Longitude into pyexiv2.Rational()...
latitude = coords_to_rational(latitude)
# convert Latitude/ Longitude into pyexiv2.Rational()... longitude = coords_to_rational(longitude)
latitude = coords_to_rational(latitude)
longitude = coords_to_rational(longitude)
# Altitude, and Altitude Reference... # Altitude, and Altitude Reference...
elif widgetname == "Altitude": elif widgetname == "Altitude":
@ -1471,13 +1427,20 @@ class EditExifMetadata(Gramplet):
for widgetname in ["Modified", "Original"]: for widgetname in ["Modified", "Original"]:
self.__set_value(_DATAMAP[widgetname], self.dates[widgetname] if not None else '') self.__set_value(_DATAMAP[widgetname], self.dates[widgetname] if not None else '')
# Latitude Reference and Latitude # Latitude Reference, Latitude, Longitude Reference, and Longitude...
self.__set_value(_DATAMAP["LatitudeRef"], latref) # if equal to None, then convert failed?
self.__set_value(_DATAMAP["Latitude"], latitude) if (not latitude and not longitude):
self.__set_value(_DATAMAP["LatitudeRef"], '')
self.__set_value(_DATAMAP["Latitude"], '')
# Longitude Reference and Longitude self.__set_value(_DATAMAP["LongitudeRef"], '')
self.__set_value(_DATAMAP["LongitudeRef"], longref) self.__set_value(_DATAMAP["Longitude"], '')
self.__set_value(_DATAMAP["Longitude"], longitude) else:
self.__set_value(_DATAMAP["LatitudeRef"], latref)
self.__set_value(_DATAMAP["Latitude"], latitude)
self.__set_value(_DATAMAP["LongitudeRef"], longref)
self.__set_value(_DATAMAP["Longitude"], longitude)
# Altitude Reference and Altitude # Altitude Reference and Altitude
self.__set_value(_DATAMAP["AltitudeRef"], altituderef) self.__set_value(_DATAMAP["AltitudeRef"], altituderef)
@ -1493,7 +1456,6 @@ class EditExifMetadata(Gramplet):
""" """
Will completely and irrevocably erase all Exif metadata from this image. Will completely and irrevocably erase all Exif metadata from this image.
""" """
# make sure the image has Exif metadata... # make sure the image has Exif metadata...
mediadatatags = _get_exif_keypairs(self.plugin_image) mediadatatags = _get_exif_keypairs(self.plugin_image)
if mediadatatags: if mediadatatags:
@ -1525,28 +1487,12 @@ class EditExifMetadata(Gramplet):
self.exif_widgets["MessageArea"].set_text(_("There was an error " self.exif_widgets["MessageArea"].set_text(_("There was an error "
"in stripping the Exif metadata from this image...")) "in stripping the Exif metadata from this image..."))
def _removesymbolsb4saving(latitude, longitude):
"""
will recieve a DMS with symbols and return it without them
@param: latitude -- Latitude GPS coordinates def close_window(self, widgetWindow):
@param: longitude -- GPS Longitude coordinates """
""" closes the window title by widgetWindow.
"""
# check to see if latitude/ longitude exist? lambda w: widgetWindow.destroy()
if (latitude and longitude):
# remove degrees, minutes, seconds symbols if they exist in
# Latitude/ Longitude...
for symbol in ["°", "#", "", "", "'", '', '"']:
if symbol in latitude:
latitude = latitude.replace(symbol, "")
if symbol in longitude:
longitude = longitude.replace(symbol, "")
return latitude, longitude
def string_to_rational(coordinate): def string_to_rational(coordinate):
""" """
@ -1558,37 +1504,22 @@ def string_to_rational(coordinate):
else: else:
return pyexiv2.Rational(int(coordinate), 1) return pyexiv2.Rational(int(coordinate), 1)
def coordinate_splitup(coordinates):
"""
will split up the coordinates into a list
"""
# Latitude, Longitude...
if (":" in coordinates and coordinates.find(" ") == -1):
return [(coordinate) for coordinate in coordinates.split(":")]
elif (" " in coordinates and coordinates.find(":") == -1):
return [(coordinate) for coordinate in coordinates.split(" ")]
return None
def coords_to_rational(coordinates): def coords_to_rational(coordinates):
""" """
returns the rational equivalent for (degrees, minutes, seconds)... returns the rational equivalent for (degrees, minutes, seconds)...
""" """
return [string_to_rational(coordinate) for coordinate in coordinates.split(":")]
return [string_to_rational(coordinate) for coordinate in coordinates]
def altitude2rational(meters_): def altitude2rational(meters_):
"""convert Altitude to pyexiv2.Rational""" """
convert Altitude to pyexiv2.Rational
"""
return [string_to_rational(meters_)] return [string_to_rational(meters_)]
def convert_value(value): def convert_value(value):
""" """
will take a value from the coordinates and return its value will take a value from the coordinates and return its value
""" """
if isinstance(value, (Fraction, pyexiv2.Rational)): if isinstance(value, (Fraction, pyexiv2.Rational)):
return str((Decimal(value.numerator) / Decimal(value.denominator))) return str((Decimal(value.numerator) / Decimal(value.denominator)))
@ -1600,7 +1531,6 @@ def rational_to_dms(coordinates):
[Fraction(40, 1), Fraction(0, 1), Fraction(1079, 20)] [Fraction(40, 1), Fraction(0, 1), Fraction(1079, 20)]
""" """
# coordinates look like: # coordinates look like:
# [Rational(38, 1), Rational(38, 1), Rational(150, 50)] # [Rational(38, 1), Rational(38, 1), Rational(150, 50)]
# or [Fraction(38, 1), Fraction(38, 1), Fraction(318, 100)] # or [Fraction(38, 1), Fraction(38, 1), Fraction(318, 100)]
@ -1610,7 +1540,6 @@ def _get_exif_keypairs(plugin_image):
""" """
Will be used to retrieve and update the Exif metadata from the image. Will be used to retrieve and update the Exif metadata from the image.
""" """
if plugin_image: if plugin_image:
return [key for key in (plugin_image.exifKeys() if OLD_API return [key for key in (plugin_image.exifKeys() if OLD_API
else plugin_image.exif_keys) ] else plugin_image.exif_keys) ]