Fixed multiple date/ time issues. Thank you, Nick Hall.
svn: r17387
This commit is contained in:
parent
cba4511cbe
commit
aa4d51f1e1
@ -1,4 +1,3 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
@ -28,7 +27,8 @@
|
||||
# *****************************************************************************
|
||||
import os, sys
|
||||
from datetime import datetime, date
|
||||
import time, calendar
|
||||
import calendar, time
|
||||
|
||||
|
||||
# abilty to escape certain characters from output...
|
||||
from xml.sax.saxutils import escape as _html_escape
|
||||
@ -165,7 +165,7 @@ _TOOLTIPS = {
|
||||
# set up Exif keys for Image.exif_keys
|
||||
_DATAMAP = {
|
||||
"Exif.Image.ImageDescription" : "Description",
|
||||
"Exif.Image.DateTime" : "ModDateTime",
|
||||
"Exif.Image.DateTime" : "Modified",
|
||||
"Exif.Image.Artist" : "Artist",
|
||||
"Exif.Image.Copyright" : "Copyright",
|
||||
"Exif.Photo.DateTimeOriginal" : "DateTime",
|
||||
@ -234,29 +234,6 @@ def _return_month(month):
|
||||
break
|
||||
return month
|
||||
|
||||
def _split_values(text):
|
||||
"""
|
||||
splits a variable into its pieces
|
||||
"""
|
||||
|
||||
# a hypen
|
||||
if "-" in text:
|
||||
separator = "-"
|
||||
|
||||
# a period
|
||||
elif "." in text:
|
||||
separator = "."
|
||||
|
||||
# a colon
|
||||
elif ":" in text:
|
||||
separator = ":"
|
||||
|
||||
# a space
|
||||
else:
|
||||
separator = " "
|
||||
|
||||
return [value for value in text.split(separator)]
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Gramplet class
|
||||
# ------------------------------------------------------------------------
|
||||
@ -276,6 +253,16 @@ class EditExifMetadata(Gramplet):
|
||||
self.MediaDataTags = False
|
||||
|
||||
self.connect_signal("Media", self.update)
|
||||
vbox = self.build_gui()
|
||||
|
||||
self.gui.get_container_widget().remove(self.gui.textview)
|
||||
self.gui.get_container_widget().add_with_viewport(vbox)
|
||||
vbox.show_all()
|
||||
|
||||
# provide tooltips for all fields and buttons...
|
||||
_setup_widget_tooltips(self.exif_widgets)
|
||||
|
||||
def build_gui(self):
|
||||
|
||||
vbox = gtk.VBox()
|
||||
|
||||
@ -330,6 +317,9 @@ class EditExifMetadata(Gramplet):
|
||||
# Image Description
|
||||
("Description", _("Description"), None, False, [], True, 0),
|
||||
|
||||
# Last Modified Date/ Time
|
||||
("Modified", _("Last Changed"), None, True, [], True, 0),
|
||||
|
||||
# Artist field
|
||||
("Artist", _("Artist"), None, False, [], True, 0),
|
||||
|
||||
@ -372,18 +362,13 @@ class EditExifMetadata(Gramplet):
|
||||
|
||||
if _MAGICK_FOUND:
|
||||
# Delete All Metadata button...
|
||||
hsd_box.add( self.__create_button(
|
||||
"Delete", False, self.__delete_dialog, gtk.STOCK_DELETE, False) )
|
||||
hsd_box.add(self.__create_button(
|
||||
"Delete", False, self.__delete_dialog, gtk.STOCK_DELETE, False))
|
||||
|
||||
# adds Exif Metadata Viewing Area
|
||||
vbox.pack_start(view, padding =10)
|
||||
|
||||
self.gui.get_container_widget().remove(self.gui.textview)
|
||||
self.gui.get_container_widget().add_with_viewport(vbox)
|
||||
vbox.show_all()
|
||||
|
||||
# provide tooltips for all fields and buttons...
|
||||
_setup_widget_tooltips(self.exif_widgets)
|
||||
return vbox
|
||||
|
||||
def update_has_data(self):
|
||||
active_handle = self.get_active('Media')
|
||||
@ -423,6 +408,21 @@ class EditExifMetadata(Gramplet):
|
||||
|
||||
return False
|
||||
|
||||
def activate_buttons(self, ButtonList):
|
||||
"""
|
||||
Enable/ activate the buttons that are in ButtonList
|
||||
"""
|
||||
|
||||
for ButtonName in ButtonList:
|
||||
self.exif_widgets[ButtonName].set_sensitive(True)
|
||||
|
||||
def deactivate_buttons(self, ButtonList):
|
||||
"""
|
||||
disable/ de-activate buttons in ButtonList
|
||||
"""
|
||||
for ButtonName in ButtonList:
|
||||
self.exif_widgets[ButtonName].set_sensitive(False)
|
||||
|
||||
def main(self): # return false finishes
|
||||
"""
|
||||
get the active media, mime type, and reads the image metadata
|
||||
@ -682,7 +682,7 @@ class EditExifMetadata(Gramplet):
|
||||
def _mark_dirty(self, obj):
|
||||
pass
|
||||
|
||||
def _get_exif_KeyTag(self, KeyTag):
|
||||
def _get_value(self, KeyTag):
|
||||
"""
|
||||
gets the value from the Exif Key, and returns it...
|
||||
|
||||
@ -708,23 +708,26 @@ class EditExifMetadata(Gramplet):
|
||||
"""
|
||||
|
||||
# set has data flag...
|
||||
self.set_has_data( len(self.MediaDataTags) > 0)
|
||||
self.set_has_data(len(self.MediaDataTags) > 0)
|
||||
|
||||
# Activate Clear and Save buttons...
|
||||
self.activate_buttons(["Clear", "Save"])
|
||||
|
||||
# check to see if we got metadata from the media object?
|
||||
if self.MediaDataTags:
|
||||
|
||||
# clears all Message Area labels...
|
||||
self.exif_widgets["Message:Area"].set_text("")
|
||||
|
||||
# activate CopyTo button...
|
||||
self.activate_buttons(["CopyTo"])
|
||||
|
||||
# set Message Area to Display...
|
||||
self.exif_widgets["Message:Area"].set_text(_("Displaying image Exif metadata..."))
|
||||
|
||||
for KeyTag in self.MediaDataTags:
|
||||
tagValue = self._get_exif_KeyTag(KeyTag)
|
||||
if tagValue:
|
||||
|
||||
if LesserVersion:
|
||||
label = self.plugin_image.tagDetails(KeyTag)[0]
|
||||
human_value = self.plugin_image.interpretedExifValue(KeyTag)
|
||||
|
||||
else:
|
||||
try:
|
||||
tag = self.plugin_image[KeyTag]
|
||||
@ -733,36 +736,13 @@ class EditExifMetadata(Gramplet):
|
||||
except AttributeError:
|
||||
human_value = False
|
||||
|
||||
if human_value is not False:
|
||||
if KeyTag in ("Exif.Image.DateTime", "Exif.Photo.DateTimeOriginal",
|
||||
if KeyTag in ("Exif.Image.DateTime",
|
||||
"Exif.Photo.DateTimeOriginal",
|
||||
"Exif.Photo.DateTimeDigitized"):
|
||||
human_value = _process_date( self._get_exif_KeyTag(KeyTag) )
|
||||
human_value = _process_datetime(self._get_value(KeyTag))
|
||||
|
||||
self.model.append( (self.plugin_image, label, human_value) )
|
||||
else:
|
||||
# display "No Exif metadata" message...
|
||||
self.exif_widgets["Message:Area"].set_text(_("No Exif metadata for this image..."))
|
||||
|
||||
# set has_data flag...
|
||||
self.set_has_data(False)
|
||||
|
||||
# Activate Clear and Save buttons..
|
||||
self.activate_buttons(["Clear", "Save"])
|
||||
|
||||
def activate_buttons(self, ButtonList):
|
||||
"""
|
||||
Enable/ activate the buttons that are in ButtonList
|
||||
"""
|
||||
|
||||
for ButtonName in ButtonList:
|
||||
self.exif_widgets[ButtonName].set_sensitive(True)
|
||||
|
||||
def deactivate_buttons(self, ButtonList):
|
||||
"""
|
||||
disable/ de-activate buttons in ButtonList
|
||||
"""
|
||||
for ButtonName in ButtonList:
|
||||
self.exif_widgets[ButtonName].set_sensitive(False)
|
||||
if human_value is not False:
|
||||
self.model.append((self.plugin_image, label, human_value))
|
||||
|
||||
def CopyTo(self, obj):
|
||||
"""
|
||||
@ -783,7 +763,7 @@ class EditExifMetadata(Gramplet):
|
||||
# name for matching to exif_widgets
|
||||
widgetsName = _DATAMAP[KeyTag]
|
||||
|
||||
tagValue = self._get_exif_KeyTag(KeyTag)
|
||||
tagValue = self._get_value(KeyTag)
|
||||
if tagValue:
|
||||
|
||||
if widgetsName in ["Description", "Artist", "Copyright"]:
|
||||
@ -791,16 +771,16 @@ class EditExifMetadata(Gramplet):
|
||||
|
||||
# Original Date of the image...
|
||||
elif widgetsName == "DateTime":
|
||||
use_date = self._get_exif_KeyTag(KeyTag)
|
||||
use_date = _process_date(use_date) if use_date else False
|
||||
use_date = self._get_value(KeyTag)
|
||||
use_date = _process_datetime(use_date) if use_date else False
|
||||
if use_date is not False:
|
||||
self.exif_widgets[widgetsName].set_text(use_date)
|
||||
|
||||
# LatitudeRef, Latitude, LongitudeRef, Longitude...
|
||||
elif widgetsName == "Latitude":
|
||||
|
||||
latitude = self._get_exif_KeyTag(KeyTag)
|
||||
longitude = self._get_exif_KeyTag(_DATAMAP["Longitude"] )
|
||||
latitude = self._get_value(KeyTag)
|
||||
longitude = self._get_value(_DATAMAP["Longitude"] )
|
||||
|
||||
# if latitude and longitude exist, display them?
|
||||
if (latitude and longitude):
|
||||
@ -817,10 +797,10 @@ class EditExifMetadata(Gramplet):
|
||||
if (not latfail and not longfail):
|
||||
|
||||
# Latitude Direction Reference
|
||||
LatitudeRef = self._get_exif_KeyTag(_DATAMAP["LatitudeRef"] )
|
||||
LatitudeRef = self._get_value(_DATAMAP["LatitudeRef"] )
|
||||
|
||||
# Longitude Direction Reference
|
||||
LongitudeRef = self._get_exif_KeyTag(_DATAMAP["LongitudeRef"] )
|
||||
LongitudeRef = self._get_value(_DATAMAP["LongitudeRef"] )
|
||||
|
||||
# set display for Latitude GPS Coordinates
|
||||
self.exif_widgets["Latitude"].set_text(
|
||||
@ -1062,8 +1042,10 @@ class EditExifMetadata(Gramplet):
|
||||
self._set_exif_KeyTag(_DATAMAP["Description"], self.exif_widgets["Description"].get_text() )
|
||||
|
||||
# Modify Date/ Time... not a data field, but saved anyway...
|
||||
ModDateTime = _format_datetime(datetime.now() )
|
||||
self._set_exif_KeyTag(_DATAMAP["ModDateTime"], _write_date(ModDateTime) )
|
||||
self._set_exif_KeyTag(_DATAMAP["Modified"], datetime.now() )
|
||||
|
||||
# display modified Date/ Time
|
||||
self.exif_widgets["Modified"].set_text(_format_datetime(datetime.now() ) )
|
||||
|
||||
# Artist/ Author data field
|
||||
self._set_exif_KeyTag(_DATAMAP["Artist"], self.exif_widgets["Artist"].get_text() )
|
||||
@ -1074,12 +1056,9 @@ class EditExifMetadata(Gramplet):
|
||||
# Original Date/ Time data field
|
||||
DateTime = self.exif_widgets["DateTime"].get_text()
|
||||
if DateTime:
|
||||
if type(DateTime) is not datetime:
|
||||
DateTime = _process_date(DateTime)
|
||||
|
||||
if type(DateTime) == datetime:
|
||||
self.exif_widgets["DateTime"].set_text(_format_datetime(DateTime) )
|
||||
self._set_exif_KeyTag(_DATAMAP["DateTime"], _write_date(DateTime) )
|
||||
DateTime = _process_datetime(DateTime, False)
|
||||
if DateTime is not False:
|
||||
self._set_exif_KeyTag(_DATAMAP["DateTime"], DateTime)
|
||||
|
||||
# Latitude/ Longitude data fields
|
||||
latitude = self.exif_widgets["Latitude"].get_text()
|
||||
@ -1297,18 +1276,19 @@ def rational_to_dms(coords):
|
||||
|
||||
return deg, min, sec
|
||||
|
||||
def _format_datetime(exif_dt):
|
||||
def _format_datetime(exif_date):
|
||||
"""
|
||||
Convert a python datetime object into a string for display, using the
|
||||
standard Gramps date format.
|
||||
"""
|
||||
if type(exif_dt) is not datetime:
|
||||
return ''
|
||||
|
||||
if not isinstance(exif_date, datetime):
|
||||
return ""
|
||||
|
||||
date_part = gen.lib.Date()
|
||||
date_part.set_yr_mon_day(exif_dt.year, exif_dt.month, exif_dt.day)
|
||||
date_part.set_yr_mon_day(exif_date.year, exif_date.month, exif_date.day)
|
||||
date_str = _dd.display(date_part)
|
||||
time_str = exif_dt.strftime('%H:%M:%S')
|
||||
time_str = exif_date.strftime('%H:%M:%S')
|
||||
|
||||
return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str}
|
||||
|
||||
@ -1318,6 +1298,7 @@ def _get_date_format(datestr):
|
||||
"""
|
||||
|
||||
# attempt to determine the dateformat of the variable passed to it...
|
||||
tmpDate = False
|
||||
for dateformat in ["%Y-%m-%d %H:%M:%S", "%Y %m %d %H:%M:%S",
|
||||
"%Y-%b-%d %H:%M:%S", "%Y %b %d %H:%M:%S",
|
||||
"%Y-%B-%d %H:%M:%S", "%Y %B %d %H:%M:%S",
|
||||
@ -1335,80 +1316,97 @@ def _get_date_format(datestr):
|
||||
|
||||
# datestring format not found...
|
||||
except ValueError:
|
||||
tmpDate = False
|
||||
pass
|
||||
|
||||
return tmpDate
|
||||
|
||||
def _write_date(wdatetime):
|
||||
"""
|
||||
handle thes Original Date/ Time field for saving
|
||||
def _create_datetime(pyear, pmonth, day, hour, minutes, seconds):
|
||||
"""
|
||||
will create and retrun a str or datetime from (
|
||||
year, month, day, hour, minutes, and seconds) ...
|
||||
|
||||
datestr = _get_date_format(wdatetime)
|
||||
if datestr is not False:
|
||||
wyear, wmonth, day, hour, minutes, seconds = datestr[0:6]
|
||||
if the year is less than 1900, then it will return a string representation...
|
||||
"""
|
||||
|
||||
# do some error trapping...
|
||||
if wmonth > 12: wmonth = 12
|
||||
if day == 0: day = 1
|
||||
if hour >= 24: hour = 0
|
||||
if minutes > 59: minutes = 59
|
||||
if seconds > 59: seconds = 59
|
||||
if pmonth > 12:
|
||||
pmonth = 12
|
||||
elif pmonth <= 0:
|
||||
pmonth = 1
|
||||
|
||||
if hour >= 24:
|
||||
hour = 23
|
||||
elif hour < 0:
|
||||
hour = 0
|
||||
|
||||
if minutes > 59:
|
||||
minutes = 59
|
||||
elif minutes < 0:
|
||||
minutes = 0
|
||||
|
||||
if seconds > 59:
|
||||
seconds = 59
|
||||
elif seconds < 0:
|
||||
seconds = 0
|
||||
|
||||
# get the number of days in year for all months
|
||||
numdays = [0] + [calendar.monthrange(year, month)[1] for year
|
||||
in [wyear] for month in range(1, 13) ]
|
||||
numdays = [0] + [calendar.monthrange(year, month)[1] for year in [pyear] for month in range(1, 13) ]
|
||||
if day > numdays[pmonth]:
|
||||
day = numdays[pmonth]
|
||||
elif day <= 0:
|
||||
day = 1
|
||||
|
||||
# Make sure that day number is not greater than number of days in that month...
|
||||
if day > numdays[wmonth]: day = numdays[wmonth]
|
||||
|
||||
if wyear < 1900:
|
||||
if pyear < 1900:
|
||||
try:
|
||||
tmpDate = "%04d-%s-%02d %02d:%02d:%02d" % (wyear, _dd.long_months[wmonth], day,
|
||||
tmpDate = "%04d-%s-%02d %02d:%02d:%02d" % (pyear, _dd.long_months[pmonth], day,
|
||||
hour, minutes, seconds)
|
||||
except ValueError:
|
||||
tmpDate = ""
|
||||
tmpDate = False
|
||||
|
||||
else:
|
||||
try:
|
||||
tmpDate = datetime(wyear, wmonth, day, hour, minutes, seconds)
|
||||
tmpDate = datetime(pyear, pmonth, day, hour, minutes, seconds)
|
||||
|
||||
except ValueError:
|
||||
tmpDate = False
|
||||
|
||||
if tmpDate is False:
|
||||
tmpDate = ""
|
||||
|
||||
return tmpDate
|
||||
else:
|
||||
return ""
|
||||
|
||||
def _process_date(tmpDate):
|
||||
def _process_datetime(tmpDate, exif_type =True):
|
||||
"""
|
||||
will attempt to parse the date/ time Exif metadata entry into its pieces...
|
||||
(year, month, day, hour, minutes, seconds)
|
||||
"""
|
||||
|
||||
if not tmpDate:
|
||||
return ""
|
||||
return False
|
||||
|
||||
datetype = type(tmpDate)
|
||||
|
||||
# if variable is already in datetime.datetime() format, return it?
|
||||
if datetype == datetime:
|
||||
return _format_datetime(tmpDate)
|
||||
pyear, pmonth, day = tmpDate.year, tmpDate.month, tmpDate.day
|
||||
hour, minutes, seconds = tmpDate.hour, tmpDate.minute, tmpDate.second
|
||||
|
||||
elif datetype in [date, gen.lib.date.Date, list]:
|
||||
elif any(datetype == value for value in [date, gen.lib.date.Date, list] ):
|
||||
hour, minutes, seconds = time.localtime()[3:6]
|
||||
|
||||
# ImageDateTime is in datetime.date format
|
||||
if datetype == date:
|
||||
# datetime.date format
|
||||
if isinstance(tmpDate, date):
|
||||
pyear, pmonth, day = tmpDate.year, tmpDate.month, tmpDate.day
|
||||
|
||||
# ImageDateTime is in gen.lib.date.Date format
|
||||
elif datetype == gen.lib.date.Date:
|
||||
# gen.lib.date.Date format
|
||||
elif isinstance(tmpDate, gen.lib.date.Date):
|
||||
pyear, pmonth, day = tmpDate.get_year(), tmpDate.get_month(), tmpDate.get_day()
|
||||
|
||||
# ImageDateTime is in list format
|
||||
# list format
|
||||
else:
|
||||
pyear, pmonth, day = tmpDate[0].year, tmpDate[0].month, tmpDate[0].day
|
||||
|
||||
# datetime is in string format...
|
||||
# string format...
|
||||
elif datetype == str:
|
||||
|
||||
datestr = _get_date_format(tmpDate)
|
||||
@ -1418,44 +1416,24 @@ def _process_date(tmpDate):
|
||||
else:
|
||||
pyear, pmonth, day, hour, minutes, seconds = [False]*6
|
||||
|
||||
# do some error trapping...
|
||||
if pmonth > 12: pmonth = 12
|
||||
if day == 0: day = 1
|
||||
if hour >= 24: hour = 0
|
||||
if minutes > 59: minutes = 59
|
||||
if seconds > 59: seconds = 59
|
||||
|
||||
# get the number of days in year for all months
|
||||
numdays = [0] + [calendar.monthrange(year, month)[1] for year
|
||||
in [pyear] for month in range(1, 13) ]
|
||||
|
||||
if day > numdays[pmonth]:
|
||||
day = numdays[pmonth]
|
||||
|
||||
if pyear < 1900:
|
||||
try:
|
||||
tmpDate = "%04d-%s-%02d %02d:%02d:%02d" % (pyear, _dd.long_months[pmonth], day,
|
||||
hour, minutes, seconds)
|
||||
except ValueError:
|
||||
tmpDate = ""
|
||||
else:
|
||||
try:
|
||||
tmpDate = datetime(pyear, pmonth, day, hour, minutes, seconds)
|
||||
|
||||
except ValueError:
|
||||
if (not pyear and not pmonth):
|
||||
tmpDate = False
|
||||
|
||||
else:
|
||||
|
||||
# create datetime...
|
||||
tmpDate = _create_datetime(pyear, pmonth, day, hour, minutes, seconds)
|
||||
|
||||
if tmpDate is not False:
|
||||
if type(tmpDate) == datetime:
|
||||
return _format_datetime(tmpDate)
|
||||
else:
|
||||
try:
|
||||
return "%04d-%s-%02d %02d:%02d:%02d" % (pyear, _dd.long_months[pmonth], day,
|
||||
hour, minutes, seconds)
|
||||
except ValueError:
|
||||
return ""
|
||||
else:
|
||||
return ""
|
||||
|
||||
if isinstance(tmpDate, datetime):
|
||||
|
||||
# for display only...
|
||||
# make datetime displayed as user has set in preferences...
|
||||
if exif_type:
|
||||
tmpDate = _format_datetime(tmpDate)
|
||||
|
||||
return tmpDate
|
||||
|
||||
def _setup_widget_tooltips(Exif_widgets):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user