Clean up of import section, added node category -- thanks Nick Hall. Cleanup of code.
svn: r17894
This commit is contained in:
parent
29d4daeec9
commit
58657454f5
@ -25,10 +25,10 @@
|
|||||||
# Python Modules
|
# Python Modules
|
||||||
# *****************************************************************************
|
# *****************************************************************************
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
import datetime
|
||||||
import calendar
|
import calendar
|
||||||
import time
|
import time
|
||||||
from PIL import Image, ImageEnhance, ImageFilter
|
from PIL import Image
|
||||||
|
|
||||||
# abilty to escape certain characters from output...
|
# abilty to escape certain characters from output...
|
||||||
from xml.sax.saxutils import escape as _html_escape
|
from xml.sax.saxutils import escape as _html_escape
|
||||||
@ -55,7 +55,6 @@ from gen.ggettext import gettext as _
|
|||||||
|
|
||||||
from DateHandler import displayer as _dd
|
from DateHandler import displayer as _dd
|
||||||
from DateHandler import parser as _dp
|
from DateHandler import parser as _dp
|
||||||
from gen.lib.date import Date
|
|
||||||
|
|
||||||
from gen.plug import Gramplet
|
from gen.plug import Gramplet
|
||||||
|
|
||||||
@ -71,81 +70,136 @@ from PlaceUtils import conv_lat_lon
|
|||||||
from gen.db import DbTxn
|
from gen.db import DbTxn
|
||||||
|
|
||||||
from ListModel import ListModel
|
from ListModel import ListModel
|
||||||
|
import pyexiv2
|
||||||
|
|
||||||
#####################################################################
|
# v0.1 has a different API to v0.2 and above
|
||||||
# Check for pyexiv2 library...
|
|
||||||
#####################################################################
|
|
||||||
# pyexiv2 download page (C) Olivier Tilloy
|
|
||||||
_DOWNLOAD_LINK = "http://tilloy.net/dev/pyexiv2/download.html"
|
|
||||||
|
|
||||||
# make sure the pyexiv2 library is installed and at least a minimum version
|
|
||||||
software_version = False
|
|
||||||
Min_VERSION = (0, 1, 3)
|
|
||||||
Min_VERSION_str = "pyexiv2-%d.%d.%d" % Min_VERSION
|
|
||||||
Pref_VERSION_str = "pyexiv2-%d.%d.%d" % (0, 3, 0)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import pyexiv2
|
|
||||||
software_version = pyexiv2.version_info
|
|
||||||
|
|
||||||
except ImportError, msg:
|
|
||||||
WarningDialog(_("You need to install, %s or greater, for this addon to work...\n"
|
|
||||||
"I would recommend installing, %s, and it may be downloaded from here: \n%s") % (
|
|
||||||
Min_VERSION_str, Pref_VERSION_str, _DOWNLOAD_LINK), str(msg))
|
|
||||||
raise Exception(_("Failed to load 'Edit Image Exif Metadata'..."))
|
|
||||||
|
|
||||||
# This only happends if the user has pyexiv2-0.1.3 installed on their computer...
|
|
||||||
except AttributeError:
|
|
||||||
software_version = pyexiv2.__version__
|
|
||||||
|
|
||||||
# v0.1 has a different API than v0.2 and above...
|
|
||||||
if hasattr(pyexiv2, 'version_info'):
|
if hasattr(pyexiv2, 'version_info'):
|
||||||
LesserVersion = False
|
OLD_API = False
|
||||||
else:
|
else:
|
||||||
# version_info attribute does not exist prior to v0.2.0
|
# version_info attribute does not exist prior to v0.2.0
|
||||||
LesserVersion = True
|
OLD_API = True
|
||||||
|
|
||||||
# the library is either not installed or does not meet minimum required version for this addon....
|
# -----------------------------------------------
|
||||||
if (software_version and (software_version < Min_VERSION)):
|
# Support Functions
|
||||||
msg = _("The minimum required version for pyexiv2 must be %s \n"
|
# -----------------------------------------------
|
||||||
"or greater. Or you do not have the python library installed yet. "
|
def _format_datetime(exif_dt):
|
||||||
"You may download it from here: %s\n\n I recommend getting, %s") % (
|
"""
|
||||||
Min_VERSION_str, _DOWNLOAD_LINK, Pref_VERSION_str)
|
Convert a python datetime object into a string for display, using the
|
||||||
WarningDialog(msg)
|
standard Gramps date format.
|
||||||
raise Exception(msg)
|
"""
|
||||||
|
if type(exif_dt) is not datetime:
|
||||||
|
return ''
|
||||||
|
|
||||||
# check to make sure that exiv2 is installed and some kind of delete command...
|
date_part = gen.lib.date.Date()
|
||||||
system_platform = os.sys.platform
|
date_part.set_yr_mon_day(exif_dt.year, exif_dt.month, exif_dt.day)
|
||||||
if system_platform == "Win32":
|
date_str = _dd.display(date_part)
|
||||||
EXIV2_OUND_ = "exiv2.exe" if Utils.search_for("exiv2.exe") else False
|
time_str = _('%(hr)02d:%(min)02d:%(sec)02d') % {'hr': exif_dt.hour,
|
||||||
elif system_platform == "linux2":
|
'min': exif_dt.minute,
|
||||||
EXIV2_FOUND_ = "exiv2" if Utils.search_for("exiv2") else False
|
'sec': exif_dt.second}
|
||||||
else:
|
return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str}
|
||||||
EXIV2_FOUND_ = "exiv2" if Utils.search_for("exiv2") else False
|
|
||||||
|
def _format_gps(tag_value):
|
||||||
|
"""
|
||||||
|
Convert a (degrees, minutes, seconds) tuple into a string for display.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return "%d° %02d' %05.2f\"" % (tag_value[0], tag_value[1], tag_value[2])
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Constants
|
# Constants
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# available image types for exiv2 and pyexiv2
|
# available image types for exiv2 and pyexiv2
|
||||||
_vtypes = [".tiff", ".jpeg", ".png", ".exv", ".dng", ".bmp", ".nef", ".psd",
|
_vtypes = [".jpeg", ".jpg", ".jfif", ".exv", ".dng", ".bmp", ".nef", ".png", ".psd",
|
||||||
".jp2", ".pef", ".srw", ".pgf"]
|
".jp2", ".pef", ".srw", ".pgf", ".tiff"]
|
||||||
_vtypes.sort()
|
_vtypes.sort()
|
||||||
_VTYPEMAP = dict( (index, imgtype_) for index, imgtype_ in enumerate(_vtypes) )
|
_VALIDIMAGEMAP = dict( (index, imgtype_) for index, imgtype_ in enumerate(_vtypes) )
|
||||||
|
|
||||||
# valid converting types for PIL.Image...
|
# valid converting types for PIL.Image...
|
||||||
_validconvert = list( (_("-- Image Types --"), ".bmp", ".gif", ".jpg", ".msp",
|
_validconvert = list( (_("-- Image Types --"), ".bmp", ".gif", ".jpg", ".msp",
|
||||||
".pcx", ".png", ".ppm", ".tiff", ".xbm") )
|
".pcx", ".png", ".ppm", ".tiff", ".xbm") )
|
||||||
|
|
||||||
|
DESCRIPTION = _("Description")
|
||||||
|
ORIGIN = _("Origin")
|
||||||
|
IMAGE = _('Image')
|
||||||
|
CAMERA = _('Camera')
|
||||||
|
GPS = _('GPS')
|
||||||
|
ADVANCED = _("Advanced")
|
||||||
|
|
||||||
|
# All of the exiv2 tag reference...
|
||||||
|
TAGS = [
|
||||||
|
# Description subclass...
|
||||||
|
(DESCRIPTION, 'Exif.Image.XPSubject', None, None),
|
||||||
|
(DESCRIPTION, 'Exif.Image.Rating', None, None),
|
||||||
|
(DESCRIPTION, 'Exif.Image.XPKeywords', None, None),
|
||||||
|
(DESCRIPTION, 'Exif.Image.XPComment', None, None),
|
||||||
|
|
||||||
|
# Origin subclass...
|
||||||
|
(ORIGIN, 'Exif.Image.Artist', None, None),
|
||||||
|
(ORIGIN, 'Exif.Photo.DateTimeOriginal', None, _format_datetime),
|
||||||
|
(ORIGIN, 'Exif.Photo.DateTimeDigitized', None, _format_datetime),
|
||||||
|
(ORIGIN, 'Exif.Image.Software', None, None),
|
||||||
|
(ORIGIN, 'Xmp.MicrosoftPhoto.DateAcquired', None, None),
|
||||||
|
(ORIGIN, 'Exif.Image.Copyright', None, None),
|
||||||
|
(ORIGIN, 'Exif.Image.TimeZoneOffset', None, None),
|
||||||
|
(ORIGIN, 'Exif.Image.SubjectDistance', None, None),
|
||||||
|
|
||||||
|
# Image subclass...
|
||||||
|
(IMAGE, 'Exif.Image.ImageDescription', None, None),
|
||||||
|
(IMAGE, 'Exif.Photo.DateTimeOriginal', None, _format_datetime),
|
||||||
|
(IMAGE, 'Exif.Photo.PixelXDimension', None, None),
|
||||||
|
(IMAGE, 'Exif.Photo.PixelYDimension', None, None),
|
||||||
|
(IMAGE, 'Exif.Image.Compression', None, None),
|
||||||
|
(IMAGE, 'Exif.Image.DocumentName', None, None),
|
||||||
|
(IMAGE, 'Exif.Image.Orientation', None, None),
|
||||||
|
(IMAGE, 'Exif.Image.ImageID', None, None),
|
||||||
|
(IMAGE, 'Exif.Photo.ExifVersion', None, None),
|
||||||
|
|
||||||
|
# Camera subclass...
|
||||||
|
(CAMERA, 'Exif.Image.Make', None, None),
|
||||||
|
(CAMERA, 'Exif.Image.Model', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.FNumber', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.ExposureTime', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.ISOSpeedRatings', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.FocalLength', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.MeteringMode', None, None),
|
||||||
|
(CAMERA, 'Exif.Photo.Flash', None, None),
|
||||||
|
(CAMERA, 'Exif.Image.SelfTimerMode', None, None),
|
||||||
|
(CAMERA, 'Exif.Image.CameraSerialNumber', None, None),
|
||||||
|
|
||||||
|
# GPS subclass...
|
||||||
|
(GPS, 'Exif.GPSInfo.GPSLatitude',
|
||||||
|
'Exif.GPSInfo.GPSLatitudeRef', _format_gps),
|
||||||
|
(GPS, 'Exif.GPSInfo.GPSLongitude',
|
||||||
|
'Exif.GPSInfo.GPSLongitudeRef', _format_gps),
|
||||||
|
(GPS, 'Exif.GPSInfo.GPSAltitude',
|
||||||
|
'Exif.GPSInfo.GPSAltitudeRef', None),
|
||||||
|
(GPS, 'Exif.Image.GPSTag', None, None),
|
||||||
|
(GPS, 'Exif.GPSInfo.GPSTimeStamp', None, _format_gps),
|
||||||
|
(GPS, 'Exif.GPSInfo.GPSSatellites', None, None),
|
||||||
|
|
||||||
|
# Advanced subclass...
|
||||||
|
(ADVANCED, 'Xmp.MicrosoftPhoto.LensManufacturer', None, None),
|
||||||
|
(ADVANCED, 'Xmp.MicrosoftPhoto.LensModel', None, None),
|
||||||
|
(ADVANCED, 'Xmp.MicrosoftPhoto.FlashManufacturer', None, None),
|
||||||
|
(ADVANCED, 'Xmp.MicrosoftPhoto.FlashModel', None, None),
|
||||||
|
(ADVANCED, 'Xmp.MicrosoftPhoto.CameraSerialNumber', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.Contrast', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.LightSource', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.ExposureProgram', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.Saturation', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.Sharpness', None, None),
|
||||||
|
(ADVANCED, 'Exif.Photo.WhiteBalance', None, None),
|
||||||
|
(ADVANCED, 'Exif.Image.ExifTag', None, None),
|
||||||
|
(ADVANCED, 'Exif.Image.BatteryLevel', None, None) ]
|
||||||
|
|
||||||
# set up Exif keys for Image Exif metadata keypairs...
|
# set up Exif keys for Image Exif metadata keypairs...
|
||||||
_DATAMAP = {
|
_DATAMAP = {
|
||||||
"Xmp.xmp.Label" : "ExifLabel",
|
|
||||||
"Exif.Image.ImageDescription" : "Description",
|
"Exif.Image.ImageDescription" : "Description",
|
||||||
"Exif.Image.DateTime" : "Modified",
|
"Exif.Image.DateTime" : "Modified",
|
||||||
"Exif.Image.Artist" : "Artist",
|
"Exif.Image.Artist" : "Artist",
|
||||||
"Exif.Image.Copyright" : "Copyright",
|
"Exif.Image.Copyright" : "Copyright",
|
||||||
"Exif.Photo.DateTimeOriginal" : "Original",
|
"Exif.Photo.DateTimeOriginal" : "Original",
|
||||||
"Exif.Photo.DateTimeDigitized" : "Digitized",
|
"Exif.Photo.DateTimeDigitized" : "Digitized",
|
||||||
"Xmp.xmp.ModifyDate" : "ModifyDate",
|
|
||||||
"Exif.GPSInfo.GPSLatitudeRef" : "LatitudeRef",
|
"Exif.GPSInfo.GPSLatitudeRef" : "LatitudeRef",
|
||||||
"Exif.GPSInfo.GPSLatitude" : "Latitude",
|
"Exif.GPSInfo.GPSLatitude" : "Latitude",
|
||||||
"Exif.GPSInfo.GPSLongitudeRef" : "LongitudeRef",
|
"Exif.GPSInfo.GPSLongitudeRef" : "LongitudeRef",
|
||||||
@ -158,9 +212,6 @@ _DATAMAP.update( (val, key) for key, val in _DATAMAP.items() )
|
|||||||
# define tooltips for all data entry fields...
|
# define tooltips for all data entry fields...
|
||||||
_TOOLTIPS = {
|
_TOOLTIPS = {
|
||||||
|
|
||||||
# Exif Label/ Title...
|
|
||||||
"ExifLabel" : _("This is equivalent to the Title field in the media object editor."),
|
|
||||||
|
|
||||||
# Description...
|
# Description...
|
||||||
"Description" : _("Provide a short descripion for this image."),
|
"Description" : _("Provide a short descripion for this image."),
|
||||||
|
|
||||||
@ -179,18 +230,17 @@ _TOOLTIPS = {
|
|||||||
"Original" : _("The original date/ time when the image was first created/ taken as in a photograph.\n"
|
"Original" : _("The original date/ time when the image was first created/ taken as in a photograph.\n"
|
||||||
"Example: 1830-01-1 09:30:59"),
|
"Example: 1830-01-1 09:30:59"),
|
||||||
|
|
||||||
# GPS Latitude Coordinates...
|
# GPS Latitude coordinates...
|
||||||
"Latitude" : _("Enter the Latitude GPS Coordinates for this image,\n"
|
"Latitude" : _("Enter the Latitude GPS coordinates for this image,\n"
|
||||||
"Example: 43.722965, 43 43 22 N, 38° 38′ 03″ N, 38 38 3"),
|
"Example: 43.722965, 43 43 22 N, 38° 38′ 03″ N, 38 38 3"),
|
||||||
|
|
||||||
# GPS Longitude Coordinates...
|
# GPS Longitude coordinates...
|
||||||
"Longitude" : _("Enter the Longitude GPS Coordinates for this image,\n"
|
"Longitude" : _("Enter the Longitude GPS coordinates for this image,\n"
|
||||||
"Example: 10.396378, 10 23 46 E, 105° 6′ 6″ W, -105 6 6"),
|
"Example: 10.396378, 10 23 46 E, 105° 6′ 6″ W, -105 6 6"),
|
||||||
|
|
||||||
# GPS Altitude (in meters)...
|
# GPS Altitude (in meters)...
|
||||||
"Altitude" : _("This is the measurement of Above or Below Sea Level. It is measured in meters."
|
"Altitude" : _("This is the measurement of Above or Below Sea Level. It is measured in meters."
|
||||||
"Example: 200.558, -200.558") }
|
"Example: 200.558, -200.558") }
|
||||||
|
|
||||||
_TOOLTIPS = dict( (key, tooltip) for key, tooltip in _TOOLTIPS.items() )
|
_TOOLTIPS = dict( (key, tooltip) for key, tooltip in _TOOLTIPS.items() )
|
||||||
|
|
||||||
# define tooltips for all buttons...
|
# define tooltips for all buttons...
|
||||||
@ -246,14 +296,11 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
vbox = self.__build_gui()
|
vbox = self.__build_gui()
|
||||||
self.connect_signal("Media", self.update)
|
self.connect_signal("Media", self.update)
|
||||||
|
self.connect_signal("media-update", self.update)
|
||||||
|
|
||||||
self.gui.get_container_widget().remove(self.gui.textview)
|
self.gui.get_container_widget().remove(self.gui.textview)
|
||||||
self.gui.get_container_widget().add_with_viewport(vbox)
|
self.gui.get_container_widget().add_with_viewport(vbox)
|
||||||
|
|
||||||
# display all button tooltips only...
|
|
||||||
# 1st argument is for Fields, 2nd argument is for Buttons...
|
|
||||||
self._setup_widget_tips([False, True])
|
|
||||||
|
|
||||||
def __build_gui(self):
|
def __build_gui(self):
|
||||||
"""
|
"""
|
||||||
will display all exif metadata and all buttons.
|
will display all exif metadata and all buttons.
|
||||||
@ -350,12 +397,11 @@ class EditExifMetadata(Gramplet):
|
|||||||
hed_box.add( self.__create_button(
|
hed_box.add( self.__create_button(
|
||||||
"Edit", False, [self.display_edit_window], gtk.STOCK_EDIT) )
|
"Edit", False, [self.display_edit_window], gtk.STOCK_EDIT) )
|
||||||
|
|
||||||
if EXIV2_FOUND_:
|
# Delete All Metadata button...
|
||||||
# Delete All Metadata button...
|
hed_box.add(self.__create_button(
|
||||||
hed_box.add(self.__create_button(
|
"Delete", False, [self.__wipe_dialog], gtk.STOCK_DELETE) )
|
||||||
"Delete", False, [self.__wipe_dialog], gtk.STOCK_DELETE) )
|
|
||||||
|
|
||||||
new_vbox = self.build_shaded_display()
|
new_vbox = self.__build_shaded_display()
|
||||||
main_vbox.pack_start(new_vbox, expand =False, fill =False, padding =10)
|
main_vbox.pack_start(new_vbox, expand =False, fill =False, padding =10)
|
||||||
|
|
||||||
# number of key/value pairs shown...
|
# number of key/value pairs shown...
|
||||||
@ -378,12 +424,18 @@ class EditExifMetadata(Gramplet):
|
|||||||
*** disable all buttons at first, then activate as needed...
|
*** disable all buttons at first, then activate as needed...
|
||||||
# Help will never be disabled...
|
# Help will never be disabled...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
db = self.dbstate.db
|
db = self.dbstate.db
|
||||||
|
|
||||||
|
# display all button tooltips only...
|
||||||
|
# 1st argument is for Fields, 2nd argument is for Buttons...
|
||||||
|
self._setup_widget_tips(fields =False, buttons =True)
|
||||||
|
|
||||||
# clears all labels and display area...
|
# clears all labels and display area...
|
||||||
for widgetname_ in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
for widgetname_ in ["MediaLabel", "MimeType", "ImageSize", "MessageArea", "Total"]:
|
||||||
self.exif_widgets[widgetname_].set_text("")
|
self.exif_widgets[widgetname_].set_text("")
|
||||||
self.model.clear()
|
self.model.clear()
|
||||||
|
self.sections = {}
|
||||||
|
|
||||||
# deactivate Convert and ImageType buttons...
|
# deactivate Convert and ImageType buttons...
|
||||||
self.deactivate_buttons(["Convert", "ImageType"])
|
self.deactivate_buttons(["Convert", "ImageType"])
|
||||||
@ -408,19 +460,16 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.set_has_data(False)
|
self.set_has_data(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# display file description/ title...
|
||||||
|
self.exif_widgets["MediaLabel"].set_text(_html_escape(self.orig_image.get_description() ) )
|
||||||
|
|
||||||
|
# Mime type information...
|
||||||
|
mime_type = self.orig_image.get_mime_type()
|
||||||
|
self.exif_widgets["MimeType"].set_text("%s, %s" % (
|
||||||
|
mime_type, gen.mime.get_description(mime_type) ) )
|
||||||
|
|
||||||
# get dirpath/ basename, and extension...
|
# get dirpath/ basename, and extension...
|
||||||
self.basename, self.extension = os.path.splitext(self.image_path)
|
self._filepath_fname, self.extension = os.path.splitext(self.image_path)
|
||||||
|
|
||||||
# remove the extension out of the list of convertible image types...
|
|
||||||
# What would make sense to be able to convert to your current image type?
|
|
||||||
PILConvert = _validconvert
|
|
||||||
if self.extension in PILConvert:
|
|
||||||
PILConvert.remove(self.extension)
|
|
||||||
self._VCONVERTMAP = dict( (index, imgtype_) for index, imgtype_ in enumerate(PILConvert) )
|
|
||||||
|
|
||||||
for imgtype_ in self._VCONVERTMAP.values():
|
|
||||||
self.exif_widgets["ImageType"].append_text(imgtype_)
|
|
||||||
self.exif_widgets["ImageType"].set_active(0)
|
|
||||||
|
|
||||||
# check image read privileges...
|
# check image read privileges...
|
||||||
_readable = os.access(self.image_path, os.R_OK)
|
_readable = os.access(self.image_path, os.R_OK)
|
||||||
@ -436,28 +485,30 @@ class EditExifMetadata(Gramplet):
|
|||||||
"You will NOT be able to save Exif metadata...."))
|
"You will NOT be able to save Exif metadata...."))
|
||||||
self.deactivate_buttons(["Edit"])
|
self.deactivate_buttons(["Edit"])
|
||||||
|
|
||||||
# Mime type information...
|
# if image file type is not an Exiv2 acceptable image type, offer to convert it....
|
||||||
mime_type = self.orig_image.get_mime_type()
|
if self.extension not in _VALIDIMAGEMAP.values():
|
||||||
self.exif_widgets["MimeType"].set_text(gen.mime.get_description(mime_type))
|
|
||||||
|
|
||||||
# if image file type is not an Exiv2 acceptable image type,
|
# remove the extension out of the list of convertible image types...
|
||||||
# offer to convert it....
|
# What would make sense to be able to convert to your current image type?
|
||||||
if self.extension not in _VTYPEMAP.values():
|
PILConvert = _validconvert
|
||||||
|
if self.extension in PILConvert:
|
||||||
|
PILConvert.remove(self.extension)
|
||||||
|
self._VCONVERTMAP = dict( (index, imgtype_) for index, imgtype_ in enumerate(PILConvert) )
|
||||||
|
|
||||||
|
for imgtype_ in self._VCONVERTMAP.values():
|
||||||
|
self.exif_widgets["ImageType"].append_text(imgtype_)
|
||||||
|
self.exif_widgets["ImageType"].set_active(0)
|
||||||
self.activate_buttons(["ImageType"])
|
self.activate_buttons(["ImageType"])
|
||||||
|
|
||||||
# determine if it is a mime image object?
|
# determine if it is a mime image object?
|
||||||
if mime_type:
|
if mime_type:
|
||||||
if mime_type.startswith("image"):
|
if mime_type.startswith("image"):
|
||||||
|
|
||||||
# display file description/ title...
|
|
||||||
self.exif_widgets["MediaLabel"].set_text(_html_escape(
|
|
||||||
self.orig_image.get_description() ) )
|
|
||||||
|
|
||||||
# creates, and reads the plugin image instance...
|
# creates, and reads the plugin image instance...
|
||||||
self.plugin_image = self.setup_image(self.image_path)
|
self.plugin_image = self.setup_image(self.image_path)
|
||||||
if self.plugin_image:
|
if self.plugin_image:
|
||||||
|
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0
|
if OLD_API: # prior to pyexiv2-0.2.0
|
||||||
try:
|
try:
|
||||||
ttype, tdata = self.plugin_image.getThumbnailData()
|
ttype, tdata = self.plugin_image.getThumbnailData()
|
||||||
width, height = tdata.dimensions
|
width, height = tdata.dimensions
|
||||||
@ -474,6 +525,11 @@ class EditExifMetadata(Gramplet):
|
|||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
thumbnail = False
|
thumbnail = False
|
||||||
|
|
||||||
|
# get image width and height...
|
||||||
|
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))
|
||||||
|
|
||||||
# if a thumbnail exists, then activate the buttton?
|
# if a thumbnail exists, then activate the buttton?
|
||||||
if thumbnail:
|
if thumbnail:
|
||||||
self.activate_buttons(["Thumbnail"])
|
self.activate_buttons(["Thumbnail"])
|
||||||
@ -482,12 +538,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.activate_buttons(["Edit"])
|
self.activate_buttons(["Edit"])
|
||||||
|
|
||||||
# display all exif metadata...
|
# display all exif metadata...
|
||||||
mediadatatags = _get_exif_keypairs(self.plugin_image)
|
self.display_metadata(self.orig_image)
|
||||||
if mediadatatags:
|
|
||||||
self.display_metadata(mediadatatags)
|
|
||||||
else:
|
|
||||||
# set Message Area to None...
|
|
||||||
self.exif_widgets["MessageArea"].set_text(_("No Exif metadata for this image..."))
|
|
||||||
|
|
||||||
# has mime, but not an image...
|
# has mime, but not an image...
|
||||||
else:
|
else:
|
||||||
@ -507,20 +558,19 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# get convert image type and check it?
|
# get convert image type and check it?
|
||||||
ext_value = self.exif_widgets["ImageType"].get_active()
|
ext_value = self.exif_widgets["ImageType"].get_active()
|
||||||
if (self.extension not in _VTYPEMAP.values() and ext_value >= 1):
|
if (self.extension not in _VALIDIMAGEMAP.values() and ext_value >= 1):
|
||||||
|
|
||||||
# if Convert button is not active, set it to active state
|
# if Convert button is not active, set it to active state
|
||||||
# so that the user may convert this image?
|
# so that the user may convert this image?
|
||||||
if not self.exif_widgets["Convert"].get_sensitive():
|
if not self.exif_widgets["Convert"].get_sensitive():
|
||||||
self.activate_buttons(["Convert"])
|
self.activate_buttons(["Convert"])
|
||||||
|
|
||||||
def _setup_widget_tips(self, _ttypes):
|
def _setup_widget_tips(self, fields =None, buttons =None):
|
||||||
"""
|
"""
|
||||||
set up widget tooltips...
|
set up widget tooltips...
|
||||||
* data fields
|
* data fields
|
||||||
* buttons
|
* buttons
|
||||||
"""
|
"""
|
||||||
fields, buttons = _ttypes
|
|
||||||
|
|
||||||
# if True, setup tooltips for all Data Entry Fields...
|
# if True, setup tooltips for all Data Entry Fields...
|
||||||
if fields:
|
if fields:
|
||||||
@ -540,7 +590,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
* setup the tooltips for the buttons,
|
* setup the tooltips for the buttons,
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0
|
if OLD_API: # prior to pyexiv2-0.2.0
|
||||||
metadata = pyexiv2.Image(full_path)
|
metadata = pyexiv2.Image(full_path)
|
||||||
try:
|
try:
|
||||||
metadata.readMetadata()
|
metadata.readMetadata()
|
||||||
@ -576,7 +626,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
if not os.path.isfile(full_path):
|
if not os.path.isfile(full_path):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0
|
if OLD_API: # prior to pyexiv2-0.2.0
|
||||||
metadata = pyexiv2.Image(full_path)
|
metadata = pyexiv2.Image(full_path)
|
||||||
try:
|
try:
|
||||||
metadata.readMetadata()
|
metadata.readMetadata()
|
||||||
@ -597,69 +647,81 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def display_metadata(self, mediadatatags_ =None):
|
def display_metadata(self, media):
|
||||||
"""
|
"""
|
||||||
displays all of the image's Exif metadata in a grey-shaded tree view...
|
displays all of the image's Exif metadata in a grey-shaded tree view...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# clear display area...
|
|
||||||
self.model.clear()
|
|
||||||
|
|
||||||
# get All Exif metadata...
|
|
||||||
metadatatags_ = _get_exif_keypairs(self.plugin_image)
|
metadatatags_ = _get_exif_keypairs(self.plugin_image)
|
||||||
if not metadatatags_:
|
if not metadatatags_:
|
||||||
self.exif_widgets["MessageArea"].set_text(_("No Exif metadata to display..."))
|
self.exif_widgets["MessageArea"].set_text(_("No Exif metadata for this image..."))
|
||||||
|
self.set_has_data(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# clear display area...
|
||||||
|
self.model.clear()
|
||||||
|
|
||||||
# set Message Area to Display...
|
# set Message Area to Display...
|
||||||
self.exif_widgets["MessageArea"].set_text(_("Displaying all Exif metadata keypairs..."))
|
self.exif_widgets["MessageArea"].set_text(_("Displaying all Exif metadata keypairs..."))
|
||||||
|
|
||||||
if not LesserVersion: # pyexiv2-0.2.0 and above...
|
# pylint: disable-msg=E1101
|
||||||
|
full_path = Utils.media_path_full(self.dbstate.db, media.get_path())
|
||||||
|
|
||||||
|
if OLD_API: # prior to v0.2.0
|
||||||
|
try:
|
||||||
|
metadata = pyexiv2.Image(full_path)
|
||||||
|
except IOError:
|
||||||
|
self.set_has_data(False)
|
||||||
|
return
|
||||||
|
|
||||||
# image Dimensions...
|
metadata.readMetadata()
|
||||||
self.exif_widgets["ImageSize"].show()
|
for section, key, key2, func in TAGS:
|
||||||
width, height = self.plugin_image.dimensions
|
if key in metadata.exifKeys():
|
||||||
self.exif_widgets["ImageSize"].set_text(_("Image Size : %04d x %04d pixels") % (width, height))
|
if section not in self.sections:
|
||||||
|
node = self.model.add([section, ''])
|
||||||
|
self.sections[section] = node
|
||||||
|
else:
|
||||||
|
node = self.sections[section]
|
||||||
|
label = metadata.tagDetails(key)[0]
|
||||||
|
if func:
|
||||||
|
human_value = func(metadata[key])
|
||||||
|
else:
|
||||||
|
human_value = metadata.interpretedExifValue(key)
|
||||||
|
if key2:
|
||||||
|
human_value += ' ' + metadata.interpretedExifValue(key2)
|
||||||
|
self.model.add((label, human_value), node =node)
|
||||||
|
self.model.tree.expand_all()
|
||||||
|
|
||||||
# Activate Delete button if ImageMagick or jhead is found?...
|
else: # v0.2.0 and above
|
||||||
|
metadata = pyexiv2.ImageMetadata(full_path)
|
||||||
|
try:
|
||||||
|
metadata.read()
|
||||||
|
except IOError:
|
||||||
|
self.set_has_data(False)
|
||||||
|
return
|
||||||
|
|
||||||
|
for section, key, key2, func in TAGS:
|
||||||
|
if key in metadatatags_:
|
||||||
|
if section not in self.sections:
|
||||||
|
node = self.model.add([section, ''])
|
||||||
|
self.sections[section] = node
|
||||||
|
else:
|
||||||
|
node = self.sections[section]
|
||||||
|
tag = metadata[key]
|
||||||
|
if func:
|
||||||
|
human_value = func(tag.value)
|
||||||
|
else:
|
||||||
|
human_value = tag.human_value
|
||||||
|
if key2:
|
||||||
|
human_value += ' ' + metadata[key2].human_value
|
||||||
|
self.model.add((tag.label, human_value), node=node)
|
||||||
|
self.model.tree.expand_all()
|
||||||
|
|
||||||
|
self.set_has_data(self.model.count > 0)
|
||||||
|
|
||||||
|
# activate Delete button...
|
||||||
self.activate_buttons(["Delete"])
|
self.activate_buttons(["Delete"])
|
||||||
|
|
||||||
for keytag_ in metadatatags_:
|
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0
|
|
||||||
label = metadata.tagDetails(keytag_)[0]
|
|
||||||
|
|
||||||
# if keytag_ is one of the dates, display as the user wants it in preferences
|
|
||||||
if keytag_ in [_DATAMAP["Modified"], _DATAMAP["Original"], _DATAMAP["Digitized"] ]:
|
|
||||||
human_value = _format_datetime(self.plugin_image[keytag_])
|
|
||||||
else:
|
|
||||||
human_value = self.plugin_image.interpretedExifValue(keytag_)
|
|
||||||
|
|
||||||
else: # pyexiv2-0.2.0 and above
|
|
||||||
tag = self.plugin_image[keytag_]
|
|
||||||
|
|
||||||
# if keytag_ is one of the dates, display as the user wants it in preferences
|
|
||||||
if keytag_ in [_DATAMAP["Modified"], _DATAMAP["Original"], _DATAMAP["Digitized"] ]:
|
|
||||||
_value = self._get_value(keytag_)
|
|
||||||
if _value:
|
|
||||||
label = tag.label
|
|
||||||
human_value = _format_datetime(_value)
|
|
||||||
else:
|
|
||||||
human_value = False
|
|
||||||
|
|
||||||
elif ("Xmp" in keytag_ or "Iptc" in keytag_):
|
|
||||||
label = self.plugin_image[keytag_]
|
|
||||||
human_value = self._get_value(keytag_)
|
|
||||||
|
|
||||||
else:
|
|
||||||
label = tag.label
|
|
||||||
human_value = tag.human_value
|
|
||||||
|
|
||||||
if human_value:
|
|
||||||
|
|
||||||
# add to model for display...
|
|
||||||
self.model.add((label, human_value))
|
|
||||||
|
|
||||||
self.set_has_data(self.model.count > 0)
|
|
||||||
self.exif_widgets["Total"].set_text(_("Number of Key/ Value pairs : %04d") % self.model.count)
|
self.exif_widgets["Total"].set_text(_("Number of Key/ Value pairs : %04d") % self.model.count)
|
||||||
|
|
||||||
def __create_button(self, pos, text, callback =[], icon =False, sensitive =False):
|
def __create_button(self, pos, text, callback =[], icon =False, sensitive =False):
|
||||||
@ -708,7 +770,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
return label
|
return label
|
||||||
|
|
||||||
def build_shaded_display(self):
|
def __build_shaded_display(self):
|
||||||
"""
|
"""
|
||||||
Build the GUI interface.
|
Build the GUI interface.
|
||||||
"""
|
"""
|
||||||
@ -716,7 +778,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
top = gtk.TreeView()
|
top = gtk.TreeView()
|
||||||
titles = [(_('Key'), 1, 180),
|
titles = [(_('Key'), 1, 180),
|
||||||
(_('Value'), 2, 310)]
|
(_('Value'), 2, 310)]
|
||||||
self.model = ListModel(top, titles)
|
self.model = ListModel(top, titles, list_mode="tree")
|
||||||
|
|
||||||
return top
|
return top
|
||||||
|
|
||||||
@ -725,13 +787,33 @@ class EditExifMetadata(Gramplet):
|
|||||||
will allow a display area for a thumbnail pop-up window.
|
will allow a display area for a thumbnail pop-up window.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dirpath, filename = os.path.split(self.image_path)
|
tip = _("Click Close to close this Thumbnail View Area.")
|
||||||
|
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0
|
self.tbarea = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
self.tbarea.tooltip = tip
|
||||||
|
self.tbarea.set_title(_("Thumbnail View Area"))
|
||||||
|
self.tbarea.set_default_size((width + 40), (height + 40))
|
||||||
|
self.tbarea.set_border_width(10)
|
||||||
|
self.tbarea.connect('destroy', lambda w: self.tbarea.destroy() )
|
||||||
|
|
||||||
|
pbloader, width, height = self.__get_thumbnail_data()
|
||||||
|
|
||||||
|
new_vbox = self.build_thumbnail_gui(pbloader, width, height)
|
||||||
|
self.tbarea.add(new_vbox)
|
||||||
|
self.tbarea.show()
|
||||||
|
|
||||||
|
def __get_thumbnail_data(self):
|
||||||
|
"""
|
||||||
|
returns the thumbnail width and height from the active media object if there is any?
|
||||||
|
"""
|
||||||
|
|
||||||
|
dirpath, filename = os.path.split(self.image_path)
|
||||||
|
pbloader, width, height = [False]*3
|
||||||
|
|
||||||
|
if OLD_API: # prior to pyexiv2-0.2.0
|
||||||
try:
|
try:
|
||||||
ttype, tdata = self.plugin_image.getThumbnailData()
|
ttype, tdata = self.plugin_image.getThumbnailData()
|
||||||
width, height = tdata.dimensions
|
width, height = tdata.dimensions
|
||||||
|
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
||||||
self.close_window(self.tbarea)
|
self.close_window(self.tbarea)
|
||||||
@ -747,30 +829,18 @@ class EditExifMetadata(Gramplet):
|
|||||||
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
||||||
self.close_window(self.tbarea)
|
self.close_window(self.tbarea)
|
||||||
|
|
||||||
|
# Get the largest preview available...
|
||||||
|
preview = previews[-1]
|
||||||
|
width, height = preview.dimensions
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
print(_('Error: %s does not contain an EXIF thumbnail.') % filename)
|
||||||
self.close_window(self.tbarea)
|
self.close_window(self.tbarea)
|
||||||
|
|
||||||
# Get the largest preview available...
|
|
||||||
preview = previews[-1]
|
|
||||||
width, height = preview.dimensions
|
|
||||||
|
|
||||||
# Create a GTK pixbuf loader to read the thumbnail data
|
# Create a GTK pixbuf loader to read the thumbnail data
|
||||||
pbloader = gtk.gdk.PixbufLoader()
|
pbloader = gtk.gdk.PixbufLoader()
|
||||||
pbloader.write(preview.data)
|
pbloader.write(preview.data)
|
||||||
|
|
||||||
tip = _("Click Close to close this Thumbnail Viewing Area.")
|
return pbloader, width, height
|
||||||
|
|
||||||
self.tbarea = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
||||||
self.tbarea.tooltip = tip
|
|
||||||
self.tbarea.set_title(_("Thumbnail Viewing Area"))
|
|
||||||
self.tbarea.set_default_size((width + 40), (height + 40))
|
|
||||||
self.tbarea.set_border_width(10)
|
|
||||||
self.tbarea.connect('destroy', lambda w: self.tbarea.destroy() )
|
|
||||||
|
|
||||||
new_vbox = self.build_thumbnail_gui(pbloader, width, height)
|
|
||||||
self.tbarea.add(new_vbox)
|
|
||||||
self.tbarea.show()
|
|
||||||
|
|
||||||
def build_thumbnail_gui(self, pbloader, width, height):
|
def build_thumbnail_gui(self, pbloader, width, height):
|
||||||
"""
|
"""
|
||||||
@ -815,7 +885,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
full_path = self.image_path
|
full_path = self.image_path
|
||||||
|
|
||||||
# get image filepath and its filename...
|
# get image filepath and its filename...
|
||||||
filepath, basename = os.path.split(self.basename)
|
filepath, basename = os.path.split(self._filepath_fname)
|
||||||
|
|
||||||
# get extension selected for converting this image...
|
# get extension selected for converting this image...
|
||||||
ext_type = self.exif_widgets["ImageType"].get_active()
|
ext_type = self.exif_widgets["ImageType"].get_active()
|
||||||
@ -830,7 +900,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
im.save(dest_file)
|
im.save(dest_file)
|
||||||
|
|
||||||
# identify pyexiv2 source image file...
|
# identify pyexiv2 source image file...
|
||||||
if LesserVersion: # prior to pyexiv2-0.2.0...
|
if OLD_API: # prior to pyexiv2-0.2.0...
|
||||||
src_meta = pyexiv2.Image(full_path)
|
src_meta = pyexiv2.Image(full_path)
|
||||||
src_meta.readMetadata()
|
src_meta.readMetadata()
|
||||||
else:
|
else:
|
||||||
@ -840,7 +910,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
# check to see if source image file has any Exif metadata?
|
# check to see if source image file has any Exif metadata?
|
||||||
if _get_exif_keypairs(src_meta):
|
if _get_exif_keypairs(src_meta):
|
||||||
|
|
||||||
if LesserVersion:
|
if OLD_API:
|
||||||
# Identify the destination image file...
|
# Identify the destination image file...
|
||||||
dest_meta = pyexiv2.Image(dest_file)
|
dest_meta = pyexiv2.Image(dest_file)
|
||||||
dest_meta.readMetadata()
|
dest_meta.readMetadata()
|
||||||
@ -895,10 +965,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.exif_widgets["MessageArea"].set_text(_("There was an error in "
|
self.exif_widgets["MessageArea"].set_text(_("There was an error in "
|
||||||
"deleting the original file. You will need to delete it yourself!"))
|
"deleting the original file. You will need to delete it yourself!"))
|
||||||
|
|
||||||
# force an update once completed in converting, deleting, and
|
|
||||||
# updating media object's path...
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def __convert_only(self, full_path =None):
|
def __convert_only(self, full_path =None):
|
||||||
"""
|
"""
|
||||||
This will only convert the file and update the media object path.
|
This will only convert the file and update the media object path.
|
||||||
@ -917,10 +983,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
self.exif_widgets["MessageArea"].set_text(_("There was an error "
|
self.exif_widgets["MessageArea"].set_text(_("There was an error "
|
||||||
"in converting your image file."))
|
"in converting your image file."))
|
||||||
|
|
||||||
# force an update once completed in converting and updating the media
|
|
||||||
# object's path, no deleting of original file...
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def update_media_path(self, newfilepath =None):
|
def update_media_path(self, newfilepath =None):
|
||||||
"""
|
"""
|
||||||
update the media object's media path.
|
update the media object's media path.
|
||||||
@ -1038,14 +1100,14 @@ class EditExifMetadata(Gramplet):
|
|||||||
"Copy" : _("Re -display the data fields that were cleared from the Edit Area."),
|
"Copy" : _("Re -display the data fields that were cleared from the Edit Area."),
|
||||||
|
|
||||||
# Convert 2 Decimal button...
|
# Convert 2 Decimal button...
|
||||||
"Decimal" : _("Convert GPS Latitude/ Longitude Coordinates to Decimal representation."),
|
"Decimal" : _("Convert GPS Latitude/ Longitude coordinates to Decimal representation."),
|
||||||
|
|
||||||
# Convert 2 Degrees, Minutes, Seconds button...
|
# Convert 2 Degrees, Minutes, Seconds button...
|
||||||
"DMS" : _("Convert GPS Latitude/ Longitude Coordinates to "
|
"DMS" : _("Convert GPS Latitude/ Longitude coordinates to "
|
||||||
"(Degrees, Minutes, Seconds) Representation.") }.items() )
|
"(Degrees, Minutes, Seconds) Representation.") }.items() )
|
||||||
|
|
||||||
# True, True -- all data fields and button tooltips will be displayed...
|
# True, True -- all data fields and button tooltips will be displayed...
|
||||||
self._setup_widget_tips([True, True])
|
self._setup_widget_tips(fields =True, buttons = True)
|
||||||
|
|
||||||
# display all data fields and their values...
|
# display all data fields and their values...
|
||||||
self.EditArea(self.plugin_image)
|
self.EditArea(self.plugin_image)
|
||||||
@ -1074,7 +1136,6 @@ class EditExifMetadata(Gramplet):
|
|||||||
new_vbox.show()
|
new_vbox.show()
|
||||||
|
|
||||||
for widget, text in [
|
for widget, text in [
|
||||||
("ExifLabel", _("Exif Label :") ),
|
|
||||||
("Description", _("Description :") ),
|
("Description", _("Description :") ),
|
||||||
("Artist", _("Artist :") ),
|
("Artist", _("Artist :") ),
|
||||||
("Copyright", _("Copyright :") ) ]:
|
("Copyright", _("Copyright :") ) ]:
|
||||||
@ -1142,8 +1203,8 @@ class EditExifMetadata(Gramplet):
|
|||||||
if self.exif_widgets["Modified"].get_text():
|
if self.exif_widgets["Modified"].get_text():
|
||||||
self.exif_widgets["Modified"].set_editable(False)
|
self.exif_widgets["Modified"].set_editable(False)
|
||||||
|
|
||||||
# GPS Coordinates...
|
# GPS coordinates...
|
||||||
latlong_frame = gtk.Frame(_("Latitude/ Longitude/ Altitude GPS Coordinates"))
|
latlong_frame = gtk.Frame(_("Latitude/ Longitude/ Altitude GPS coordinates"))
|
||||||
latlong_frame.set_size_request(550, 125)
|
latlong_frame.set_size_request(550, 125)
|
||||||
main_vbox.pack_start(latlong_frame, expand =False, fill =False, padding =0)
|
main_vbox.pack_start(latlong_frame, expand =False, fill =False, padding =0)
|
||||||
latlong_frame.show()
|
latlong_frame.show()
|
||||||
@ -1284,7 +1345,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
@param: keytag_ -- image metadata key
|
@param: keytag_ -- image metadata key
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if LesserVersion:
|
if OLD_API:
|
||||||
keyvalue_ = self.plugin_image[keytag_]
|
keyvalue_ = self.plugin_image[keytag_]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -1320,7 +1381,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
tagValue = self._get_value(keytag_)
|
tagValue = self._get_value(keytag_)
|
||||||
if tagValue:
|
if tagValue:
|
||||||
|
|
||||||
if widgetname_ in ["ExifLabel", "Description", "Artist", "Copyright"]:
|
if widgetname_ in ["Description", "Artist", "Copyright"]:
|
||||||
self.exif_widgets[widgetname_].set_text(tagValue)
|
self.exif_widgets[widgetname_].set_text(tagValue)
|
||||||
|
|
||||||
# Last Changed/ Modified...
|
# Last Changed/ Modified...
|
||||||
@ -1346,7 +1407,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
# 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):
|
||||||
@ -1357,11 +1418,11 @@ class EditExifMetadata(Gramplet):
|
|||||||
# 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)
|
||||||
|
|
||||||
@ -1397,7 +1458,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
tagclass_ = keytag_[0:4]
|
tagclass_ = keytag_[0:4]
|
||||||
if LesserVersion:
|
if OLD_API:
|
||||||
self.plugin_image[keytag_] = keyvalue_
|
self.plugin_image[keytag_] = keyvalue_
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -1420,10 +1481,10 @@ class EditExifMetadata(Gramplet):
|
|||||||
"""
|
"""
|
||||||
writes the Exif metadata to the image.
|
writes the Exif metadata to the image.
|
||||||
|
|
||||||
LesserVersion -- prior to pyexiv2-0.2.0
|
OLD_API -- prior to pyexiv2-0.2.0
|
||||||
-- pyexiv2-0.2.0 and above...
|
-- pyexiv2-0.2.0 and above...
|
||||||
"""
|
"""
|
||||||
if LesserVersion:
|
if OLD_API:
|
||||||
plugininstance.writeMetadata()
|
plugininstance.writeMetadata()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -1438,7 +1499,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (not latitude and not longitude):
|
if (not latitude and not longitude):
|
||||||
@ -1465,7 +1526,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
def __convert2decimal(self, latitude =False, longitude =False, display =False):
|
def __convert2decimal(self, latitude =False, longitude =False, display =False):
|
||||||
"""
|
"""
|
||||||
will convert a decimal GPS Coordinates into decimal format.
|
will convert a decimal GPS coordinates into decimal format.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (not latitude and not longitude):
|
if (not latitude and not longitude):
|
||||||
@ -1480,9 +1541,9 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
return latitude, longitude
|
return latitude, longitude
|
||||||
|
|
||||||
def __convert2dms(self, latitude =False, longitude =False, display =False):
|
def __convert2dms(self, latitude =False, longitude =False, display =True):
|
||||||
"""
|
"""
|
||||||
will convert a decimal GPS Coordinates into degrees, minutes, seconds
|
will convert a decimal GPS coordinates into degrees, minutes, seconds
|
||||||
for display only
|
for display only
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -1511,7 +1572,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
for widgetname_, widgetvalue_ in datatags_:
|
for widgetname_, widgetvalue_ in datatags_:
|
||||||
|
|
||||||
# Exif Label, Description, Artist, Copyright...
|
# Exif Label, Description, Artist, Copyright...
|
||||||
if widgetname_ in ["ExifLabel", "Description", "Artist", "Copyright"]:
|
if widgetname_ in ["Description", "Artist", "Copyright"]:
|
||||||
self._set_value(_DATAMAP[widgetname_], widgetvalue_)
|
self._set_value(_DATAMAP[widgetname_], widgetvalue_)
|
||||||
|
|
||||||
# Modify Date/ Time...
|
# Modify Date/ Time...
|
||||||
@ -1534,7 +1595,7 @@ class EditExifMetadata(Gramplet):
|
|||||||
# modify the media object date if it is not already set?
|
# modify the media object date if it is not already set?
|
||||||
mediaobj_date = self.orig_image.get_date_object()
|
mediaobj_date = self.orig_image.get_date_object()
|
||||||
if mediaobj_date.is_empty():
|
if mediaobj_date.is_empty():
|
||||||
objdate = Date()
|
objdate = gen.lib.date.Date()
|
||||||
try:
|
try:
|
||||||
objdate.set_yr_mon_day(widgetvalue_.get_year(),
|
objdate.set_yr_mon_day(widgetvalue_.get_year(),
|
||||||
widgetvalue_.get_month(),
|
widgetvalue_.get_month(),
|
||||||
@ -1563,27 +1624,28 @@ class EditExifMetadata(Gramplet):
|
|||||||
if (latitude.count(" ") == longitude.count(" ") == 0):
|
if (latitude.count(" ") == longitude.count(" ") == 0):
|
||||||
latitude, longitude = self.__convert2dms(latitude, longitude)
|
latitude, longitude = self.__convert2dms(latitude, longitude)
|
||||||
|
|
||||||
if (latitude.count(":") == longitude.count(":") >= 1):
|
# remove symbols before saving...
|
||||||
|
latitude, longitude = _removesymbolsb4saving(latitude, longitude)
|
||||||
|
|
||||||
# remove symbols before saving...
|
# split Latitude/ Longitude into its (d, m, s, dir)...
|
||||||
latitude, longitude = _removesymbolsb4saving(
|
latitude = coordinate_splitup(latitude)
|
||||||
self.exif_widgets["Latitude"].get_text(),
|
longitude = coordinate_splitup(longitude)
|
||||||
self.exif_widgets["Longitude"].get_text() )
|
|
||||||
|
|
||||||
|
if "N" in latitude:
|
||||||
latref = "N"
|
latref = "N"
|
||||||
if latitude[0] == "-":
|
elif "S" in latitude:
|
||||||
latitude = latitude.replace("-", '')
|
latref = "S"
|
||||||
latref = "S"
|
latitude.remove(latref)
|
||||||
|
|
||||||
|
if "E" in longitude:
|
||||||
longref = "E"
|
longref = "E"
|
||||||
if longitude[0] == "-":
|
elif "W" in longitude:
|
||||||
longitude = longitude.replace("-", '')
|
longref = "W"
|
||||||
longref = "W"
|
longitude.remove(longref)
|
||||||
|
|
||||||
# convert Latitude/ Longitude into pyexiv2.Rational()...
|
# convert Latitude/ Longitude into pyexiv2.Rational()...
|
||||||
latitude = coords_to_rational(latitude)
|
latitude = coords_to_rational(latitude)
|
||||||
longitude = coords_to_rational(longitude)
|
longitude = coords_to_rational(longitude)
|
||||||
print(latitude, longitude)
|
|
||||||
|
|
||||||
# save LatitudeRef/ Latitude...
|
# save LatitudeRef/ Latitude...
|
||||||
self._set_value(_DATAMAP["LatitudeRef"], latref)
|
self._set_value(_DATAMAP["LatitudeRef"], latref)
|
||||||
@ -1595,18 +1657,18 @@ class EditExifMetadata(Gramplet):
|
|||||||
|
|
||||||
# Altitude, and Altitude Reference...
|
# Altitude, and Altitude Reference...
|
||||||
elif widgetname_ == "Altitude":
|
elif widgetname_ == "Altitude":
|
||||||
altitude = widgetvalue_
|
if widgetvalue_:
|
||||||
if altitude:
|
if "-" in widgetvalue_:
|
||||||
if "-" in altitude:
|
widgetvalue_= widgetvalue_.replace("-", "")
|
||||||
altitude = altitude.replace("-", "")
|
|
||||||
altituderef = "1"
|
altituderef = "1"
|
||||||
else:
|
else:
|
||||||
altituderef = "0"
|
altituderef = "0"
|
||||||
altitude = coords_to_rational(altitude)
|
|
||||||
|
|
||||||
# convert altitude to pyexiv2.Rational for saving...
|
# convert altitude to pyexiv2.Rational for saving...
|
||||||
|
widgetvalue_ = altitude_to_rational(widgetvalue_)
|
||||||
|
|
||||||
self._set_value(_DATAMAP["AltitudeRef"], altituderef)
|
self._set_value(_DATAMAP["AltitudeRef"], altituderef)
|
||||||
self._set_value(_DATAMAP[widgetname_], altitude)
|
self._set_value(_DATAMAP[widgetname_], widgetvalue_)
|
||||||
|
|
||||||
# writes all Exif Metadata to image even if the fields are all empty so as to remove the value...
|
# writes all Exif Metadata to image even if the fields are all empty so as to remove the value...
|
||||||
self.write_metadata(self.plugin_image)
|
self.write_metadata(self.plugin_image)
|
||||||
@ -1669,7 +1731,7 @@ def _get_exif_keypairs(plugin_image):
|
|||||||
if not plugin_image:
|
if not plugin_image:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
mediadatatags_ = [keytag_ for keytag_ in (plugin_image.exifKeys() if LesserVersion
|
mediadatatags_ = [keytag_ for keytag_ in (plugin_image.exifKeys() if OLD_API
|
||||||
else chain( plugin_image.exif_keys,
|
else chain( plugin_image.exif_keys,
|
||||||
plugin_image.xmp_keys,
|
plugin_image.xmp_keys,
|
||||||
plugin_image.iptc_keys) ) ]
|
plugin_image.iptc_keys) ) ]
|
||||||
@ -1712,50 +1774,50 @@ def string_to_rational(coordinate):
|
|||||||
else:
|
else:
|
||||||
return pyexiv2.Rational(int(coordinate), 1)
|
return pyexiv2.Rational(int(coordinate), 1)
|
||||||
|
|
||||||
def coords_to_rational(Coordinates):
|
def coordinate_splitup(coordinates):
|
||||||
"""
|
"""
|
||||||
returns the rational equivalent for Latitude/ Longitude,
|
will split up the coordinates into a list
|
||||||
and Altitude...
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Latitude, Longitude...
|
# Latitude, Longitude...
|
||||||
if " " in Coordinates:
|
if (":" in coordinates and coordinates.find(" ") == -1):
|
||||||
Coordinates = [string_to_rational(coordinate) for coordinate in Coordinates.split(" ")]
|
return [(coordinate) for coordinate in coordinates.split(":")]
|
||||||
|
|
||||||
if ":" in Coordinates:
|
elif (" " in coordinates and coordinates.find(":") == -1):
|
||||||
Coordinates = [string_to_rational(coordinate) for coordinate in Coordinates.split(":")]
|
return [(coordinate) for coordinate in coordinates.split(" ")]
|
||||||
|
|
||||||
# Altitude...
|
return None
|
||||||
else:
|
|
||||||
Coordinates = [string_to_rational(Coordinates)]
|
|
||||||
|
|
||||||
return Coordinates
|
def coords_to_rational(coordinates):
|
||||||
|
"""
|
||||||
|
returns the rational equivalent for (degrees, minutes, seconds)...
|
||||||
|
"""
|
||||||
|
|
||||||
|
return [string_to_rational(coordinate) for coordinate in coordinates]
|
||||||
|
|
||||||
|
def altitude_to_rational(altitude):
|
||||||
|
|
||||||
|
return [string_to_rational(altitude)]
|
||||||
|
|
||||||
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)))
|
||||||
|
|
||||||
def rational_to_dms(coords):
|
def rational_to_dms(coordinates):
|
||||||
"""
|
"""
|
||||||
takes a rational set of coordinates and returns (degrees, minutes, seconds)
|
takes a rational set of coordinates and returns (degrees, minutes, seconds)
|
||||||
|
|
||||||
[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)]
|
||||||
if isinstance(coords, list):
|
return [convert_value(coordinate) for coordinate in coordinates]
|
||||||
if len(coords) == 3:
|
|
||||||
return [convert_value(coordinate) for coordinate in coords]
|
|
||||||
|
|
||||||
elif isinstance(coords, (Fraction, pyexiv2.Rational)):
|
|
||||||
if len(coords) == 1:
|
|
||||||
return convert_value(coords)
|
|
||||||
|
|
||||||
return [False]*3
|
|
||||||
|
|
||||||
def _parse_datetime(value):
|
def _parse_datetime(value):
|
||||||
"""
|
"""
|
||||||
@ -1794,18 +1856,3 @@ def _parse_datetime(value):
|
|||||||
time_part.tm_sec)
|
time_part.tm_sec)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _format_datetime(value):
|
|
||||||
"""
|
|
||||||
Convert a python datetime object into a string for display, using the
|
|
||||||
standard Gramps date format.
|
|
||||||
"""
|
|
||||||
if type(value) != datetime:
|
|
||||||
return ''
|
|
||||||
date_part = gen.lib.Date()
|
|
||||||
date_part.set_yr_mon_day(value.year, value.month, value.day)
|
|
||||||
date_str = _dd.display(date_part)
|
|
||||||
time_str = _('%(hr)02d:%(min)02d:%(sec)02d') % {'hr': value.hour,
|
|
||||||
'min': value.minute,
|
|
||||||
'sec': value.second}
|
|
||||||
return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user