Tidy up date/time functionality
svn: r17735
This commit is contained in:
		| @@ -24,8 +24,8 @@ | |||||||
| # ***************************************************************************** | # ***************************************************************************** | ||||||
| # Python Modules | # Python Modules | ||||||
| # ***************************************************************************** | # ***************************************************************************** | ||||||
| import os, sys | import os | ||||||
| from datetime import datetime, date | from datetime import datetime | ||||||
| import calendar | import calendar | ||||||
| import time | import time | ||||||
|  |  | ||||||
| @@ -34,7 +34,7 @@ from xml.sax.saxutils import escape as _html_escape | |||||||
|  |  | ||||||
| from itertools import chain | from itertools import chain | ||||||
|  |  | ||||||
| from decimal import * | from decimal import Decimal, getcontext | ||||||
| getcontext().prec = 4 | getcontext().prec = 4 | ||||||
| from fractions import Fraction | from fractions import Fraction | ||||||
|  |  | ||||||
| @@ -56,7 +56,7 @@ from gen.ggettext import gettext as _ | |||||||
| from gen.plug import Gramplet | from gen.plug import Gramplet | ||||||
| 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, NextYear | from gen.lib.date import Date | ||||||
| from gui.widgets import ValidatableMaskedEntry | from gui.widgets import ValidatableMaskedEntry | ||||||
| from Errors import ValidationError | from Errors import ValidationError | ||||||
|  |  | ||||||
| @@ -64,7 +64,7 @@ import gen.lib | |||||||
| import gen.mime | import gen.mime | ||||||
| import Utils | import Utils | ||||||
| from PlaceUtils import conv_lat_lon | from PlaceUtils import conv_lat_lon | ||||||
| from ListModel import ListModel, NOSORT | from ListModel import ListModel | ||||||
|  |  | ||||||
| ##################################################################### | ##################################################################### | ||||||
| #               Check for pyexiv2 library... | #               Check for pyexiv2 library... | ||||||
| @@ -1108,26 +1108,11 @@ class EditExifMetadata(Gramplet): | |||||||
|         """ |         """ | ||||||
|         Parse date and time from text entry |         Parse date and time from text entry | ||||||
|         """ |         """ | ||||||
|  |         value = _parse_datetime(unicode(widget.get_text())) | ||||||
|         if not widget.get_text(): |         if value is not None: | ||||||
|             return |  | ||||||
|  |  | ||||||
|         dt_text = unicode(widget.get_text().rstrip()) |  | ||||||
|         date_text, time_text = dt_text.rsplit(u' ', 1) |  | ||||||
|         date_part = _dp.parse(date_text) |  | ||||||
|         try: |  | ||||||
|             time_part = time.strptime(time_text, "%H:%M:%S") |  | ||||||
|  |  | ||||||
|         except ValueError: |  | ||||||
|             time_part = None |  | ||||||
|         if date_part.get_modifier() == Date.MOD_NONE and time_part is not None: |  | ||||||
|             self.dates[field] = "%04d:%02d:%02d %02d:%02d:%02d" % ( |             self.dates[field] = "%04d:%02d:%02d %02d:%02d:%02d" % ( | ||||||
|                                     date_part.get_year(), |                                     value.year, value.month, value.day, | ||||||
|                                     date_part.get_month(), |                                     value.hour, value.minute, value.second) | ||||||
|                                     date_part.get_day(), |  | ||||||
|                                     time_part.tm_hour, |  | ||||||
|                                     time_part.tm_min, |  | ||||||
|                                     time_part.tm_sec) |  | ||||||
|         else: |         else: | ||||||
|             self.dates[field] = None |             self.dates[field] = None | ||||||
|  |  | ||||||
| @@ -1194,32 +1179,11 @@ class EditExifMetadata(Gramplet): | |||||||
|                         self.exif_widgets[widgetName].set_text(tagValue) |                         self.exif_widgets[widgetName].set_text(tagValue) | ||||||
|  |  | ||||||
|                     # Last Changed/ Modified... |                     # Last Changed/ Modified... | ||||||
|                     elif widgetName == "Modified": |                     elif widgetName in ["Modified", "Original"]: | ||||||
|                         use_date = _format_datetime(tagValue) |                         use_date = _format_datetime(tagValue) | ||||||
|                         if use_date: |                         if use_date: | ||||||
|                             self.exif_widgets[widgetName].set_text(use_date) |                             self.exif_widgets[widgetName].set_text(use_date) | ||||||
|  |  | ||||||
|                     # Original Date/ Time... |  | ||||||
|                     elif widgetName == "Original": |  | ||||||
|                         date1 = tagValue |  | ||||||
|                         date2 = self._get_value(_DATAMAP["Digitized"]) |  | ||||||
|                         date3 = self.orig_image.get_date_object() |  | ||||||
|                         use_date = date1 or date2 or date3 or False |  | ||||||
|                         if use_date: |  | ||||||
|                             if isinstance(use_date, (str, unicode)): |  | ||||||
|                                 use_date = _get_date_format(use_date) |  | ||||||
|                                 if use_date: |  | ||||||
|                                     pyear, pmonth, day, hour, minutes, seconds = use_date[0:6] |  | ||||||
|                             elif isinstance(use_date, datetime): |  | ||||||
|                                 pyear, pmonth, day = use_date.year, use_date.month, use_date.day |  | ||||||
|                                 hour, minutes, seconds = use_date.hour, use_date.minute, use_date.second |  | ||||||
|                             else: |  | ||||||
|                                 pyear = False |  | ||||||
|                             if pyear: |  | ||||||
|                                 use_date = _create_datetime(pyear, pmonth, day, hour, minutes, seconds) |  | ||||||
|                                 if use_date: |  | ||||||
|                                     self.exif_widgets[widgetName].set_text(_format_datetime(use_date)) |  | ||||||
|  |  | ||||||
|                     # LatitudeRef, Latitude, LongitudeRef, Longitude... |                     # LatitudeRef, Latitude, LongitudeRef, Longitude... | ||||||
|                     elif widgetName == "Latitude": |                     elif widgetName == "Latitude": | ||||||
|  |  | ||||||
| @@ -1722,161 +1686,52 @@ def rational_to_dms(coords): | |||||||
|  |  | ||||||
|     return [False]*3 |     return [False]*3 | ||||||
|  |  | ||||||
| def _format_datetime(exif_dt): | def _parse_datetime(value): | ||||||
|  |     """ | ||||||
|  |     Parse date and time and return a datetime object. | ||||||
|  |     """ | ||||||
|  |     value = value.rstrip() | ||||||
|  |     if value.find(u':') >= 0: | ||||||
|  |         # Time part present | ||||||
|  |         if value.find(u' ') >= 0: | ||||||
|  |             # Both date and time part | ||||||
|  |             date_text, time_text = value.rsplit(u' ', 1) | ||||||
|  |         else: | ||||||
|  |             # Time only | ||||||
|  |             date_text = u'' | ||||||
|  |             time_text = value | ||||||
|  |     else: | ||||||
|  |         # Date only | ||||||
|  |         date_text = value | ||||||
|  |         time_text = u'00:00:00' | ||||||
|  |  | ||||||
|  |     date_part = _dp.parse(date_text) | ||||||
|  |     try: | ||||||
|  |         time_part = time.strptime(time_text, "%H:%M:%S") | ||||||
|  |     except ValueError: | ||||||
|  |         time_part = None | ||||||
|  |  | ||||||
|  |     if date_part.get_modifier() == Date.MOD_NONE and time_part is not None: | ||||||
|  |         return datetime(date_part.get_year(),  | ||||||
|  |                         date_part.get_month(), | ||||||
|  |                         date_part.get_day(), | ||||||
|  |                         time_part.tm_hour, | ||||||
|  |                         time_part.tm_min, | ||||||
|  |                         time_part.tm_sec) | ||||||
|  |     else: | ||||||
|  |         return None | ||||||
|  |  | ||||||
|  | def _format_datetime(value): | ||||||
|     """ |     """ | ||||||
|     Convert a python datetime object into a string for display, using the |     Convert a python datetime object into a string for display, using the | ||||||
|     standard Gramps date format. |     standard Gramps date format. | ||||||
|     """ |     """ | ||||||
|  |     if type(value) != datetime: | ||||||
|  |         return '' | ||||||
|     date_part = gen.lib.Date() |     date_part = gen.lib.Date() | ||||||
|     if isinstance(exif_dt, datetime): |     date_part.set_yr_mon_day(value.year, value.month, value.day) | ||||||
|         fyear, fmonth, day = exif_dt.year, exif_dt.month, exif_dt.day |  | ||||||
|         hour, minutes, seconds = exif_dt.hour, exif_dt.minute, exif_dt.second |  | ||||||
|  |  | ||||||
|     elif isinstance(exif_dt, str): |  | ||||||
|         exif_dt = _get_date_format(exif_dt) |  | ||||||
|         if not exif_dt: |  | ||||||
|             return False |  | ||||||
|         fyear, fmonth, day, hour, minutes, seconds =exif_dt[0:6] |  | ||||||
|  |  | ||||||
|     date_part.set_yr_mon_day(fyear, fmonth, day) |  | ||||||
|     date_str = _dd.display(date_part) |     date_str = _dd.display(date_part) | ||||||
|     time_str = _('%(hr)02d:%(min)02d:%(sec)02d') % {'hr' : hour, |     time_str = _('%(hr)02d:%(min)02d:%(sec)02d') % {'hr': value.hour, | ||||||
|                                                     'min': minutes, |                                                     'min': value.minute, | ||||||
|                                                     'sec': seconds} |                                                     'sec': value.second} | ||||||
|     return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str} |     return _('%(date)s %(time)s') % {'date': date_str, 'time': time_str} | ||||||
|  |  | ||||||
| def _get_date_format(datestr): |  | ||||||
|     """ |  | ||||||
|     attempt to retrieve date format from date string |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     # attempt to determine the dateformat of the date string... |  | ||||||
|     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", |  | ||||||
|                        "%d-%m-%Y %H:%M:%S", "%d %m %Y %H:%M:%S", |  | ||||||
|                        "%d-%b-%Y %H:%M:%S", "%d %b %Y %H:%M:%S", |  | ||||||
|                        "%d-%B-%Y %H:%M:%S", "%d %B %Y %H:%M:%S", |  | ||||||
|                        "%m-%d-%Y %H:%M:%S", "%m %d %Y %H:%M:%S", |  | ||||||
|                        "%b-%d-%Y %H:%M:%S", "%b %d %Y %H:%M:%S", |  | ||||||
|                        "%B-%d-%Y %H:%M:%S", "%B %d %Y %H:%M:%S"]: |  | ||||||
|  |  | ||||||
|         # find date string format |  | ||||||
|         try: |  | ||||||
|             tmpDate = time.strptime(datestr, dateformat) |  | ||||||
|             break |  | ||||||
|  |  | ||||||
|         # date string format  not found... |  | ||||||
|         except ValueError: |  | ||||||
|             pass |  | ||||||
|  |  | ||||||
|     return tmpDate |  | ||||||
|  |  | ||||||
| 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) ... |  | ||||||
|  |  | ||||||
|     if the year is less than 1900, then it will return a string representation... |  | ||||||
|     """ |  | ||||||
|  |  | ||||||
|     # do some error trapping... |  | ||||||
|     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 [pyear] for month in range(1, 13) ] |  | ||||||
|     if day > numdays[pmonth]: |  | ||||||
|         day = numdays[pmonth] |  | ||||||
|     elif day <= 0: |  | ||||||
|         day = 1 |  | ||||||
|  |  | ||||||
|     if pyear < 1900: |  | ||||||
|         tmpDate = "%04d-%02d-%02d %02d:%02d:%02d" % (pyear, pmonth, day, hour, minutes, seconds) |  | ||||||
|     else: |  | ||||||
|         try: |  | ||||||
|             tmpDate = datetime(pyear, pmonth, day, hour, minutes, seconds) |  | ||||||
|  |  | ||||||
|         except ValueError: |  | ||||||
|             tmpDate = False |  | ||||||
|  |  | ||||||
|     return 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 False |  | ||||||
|  |  | ||||||
|     datetype = type(tmpDate) |  | ||||||
|  |  | ||||||
|     # if variable is already in datetime.datetime() format, return it? |  | ||||||
|     if datetype == datetime: |  | ||||||
|         pyear, pmonth, day = tmpDate.year, tmpDate.month, tmpDate.day |  | ||||||
|         hour, minutes, seconds = tmpDate.hour, tmpDate.minute, tmpDate.second         |  | ||||||
|  |  | ||||||
|     elif any(datetype == value for value in [date, gen.lib.date.Date, list] ): |  | ||||||
|         hour, minutes, seconds = time.localtime()[3:6] |  | ||||||
|  |  | ||||||
|         # datetime.date format |  | ||||||
|         if isinstance(tmpDate, date): |  | ||||||
|             pyear, pmonth, day = tmpDate.year, tmpDate.month, tmpDate.day |  | ||||||
|  |  | ||||||
|         # gen.lib.date.Date format |  | ||||||
|         elif isinstance(tmpDate, gen.lib.date.Date): |  | ||||||
|             pyear, pmonth, day = tmpDate.get_year(), tmpDate.get_month(), tmpDate.get_day() |  | ||||||
|  |  | ||||||
|         # list format |  | ||||||
|         else: |  | ||||||
|             pyear, pmonth, day = tmpDate[0].year, tmpDate[0].month, tmpDate[0].day |  | ||||||
|  |  | ||||||
|     #  string format... |  | ||||||
|     elif datetype == str: |  | ||||||
|  |  | ||||||
|         datestr = _get_date_format(tmpDate) |  | ||||||
|         if datestr is not False: |  | ||||||
|             pyear, pmonth, day, hour, minutes, seconds = datestr[0:6] |  | ||||||
|  |  | ||||||
|         else: |  | ||||||
|             pyear, pmonth, day, hour, minutes, seconds = [False]*6 |  | ||||||
|  |  | ||||||
|     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 isinstance(tmpDate, datetime): |  | ||||||
|  |  | ||||||
|             # for display only... |  | ||||||
|             # make datetime displayed as user has set in preferences... |  | ||||||
|             if exif_type: |  | ||||||
|                 tmpDate = _format_datetime(tmpDate) |  | ||||||
|  |  | ||||||
|     return tmpDate |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user