gtg-user team mailing list archive
-
gtg-user team
-
Mailing list archive
-
Message #00321
[Merge] lp:~gtg-user/gtg/improved_tools_dates.py into lp:gtg
Thibault Fevry has proposed merging lp:~gtg-user/gtg/improved_tools_dates.py into lp:gtg.
Requested reviews:
Gtg developers (gtg): test in different locales perhaps.
This improves tool/dates.py, removing the fixme, adding an elegant way to get weekdays.
This also removes the need for 7 strings translation per language, as this is now handled by the calendar module.
Other nice thing is the pep8 fixing, should be only 4-5 errors left.
This shouldn't break anything, if it does, I'll fix it. (It didn't break anything in mine GTG, but I also didn't tested it in a long time period.)
--
https://code.launchpad.net/~gtg-user/gtg/improved_tools_dates.py/+merge/34697
Your team Gtg users is subscribed to branch lp:~gtg-user/gtg/improved_tools_dates.py.
=== modified file 'GTG/gtk/editor/editor.py'
--- GTG/gtk/editor/editor.py 2010-07-06 04:01:50 +0000
+++ GTG/gtk/editor/editor.py 2010-09-06 18:07:42 +0000
@@ -321,7 +321,7 @@
#If the task is marked as done, we display the delay between the
#due date and the actual closing date. If the task isn't marked
#as done, we display the number of days left.
- if status in [Task.STA_DISMISSED, Task.STA_DONE]:
+ if status in (Task.STA_DISMISSED, Task.STA_DONE):
delay = self.task.get_days_late()
if delay is None:
txt = ""
=== modified file 'GTG/tools/dates.py'
--- GTG/tools/dates.py 2010-04-30 19:23:02 +0000
+++ GTG/tools/dates.py 2010-09-06 18:07:42 +0000
@@ -22,96 +22,109 @@
import calendar
from GTG import _, ngettext
-#setting the locale of gtg to the system locale
+#setting the locale of gtg to the system locale
#locale.setlocale(locale.LC_TIME, '')
+
class Date(object):
+
def __cmp__(self, other):
- if other is None: return 1
+ if other is None:
+ return 1
return cmp(self.to_py_date(), other.to_py_date())
-
+
def __sub__(self, other):
return self.to_py_date() - other.to_py_date()
def __get_locale_string(self):
return locale.nl_langinfo(locale.D_FMT)
-
- def xml_str(self): return str(self)
-
- def day(self): return self.to_py_date().day
- def month(self): return self.to_py_date().month
- def year(self): return self.to_py_date().year
+
+ def xml_str(self):
+ return str(self)
+
+ def day(self):
+ return self.to_py_date().day
+
+ def month(self):
+ return self.to_py_date().month
+
+ def year(self):
+ return self.to_py_date().year
def to_readable_string(self):
if self.to_py_date() == NoDate().to_py_date():
return None
dleft = (self.to_py_date() - date.today()).days
- if dleft == 0:
+ if not dleft:
return _("Today")
elif dleft < 0:
abs_days = abs(dleft)
return ngettext("Yesterday", "%(days)d days ago", abs_days) % \
{"days": abs_days}
- elif dleft > 0 and dleft <= 15:
+ elif 0 < dleft <= 15:
return ngettext("Tomorrow", "In %(days)d days", dleft) % \
{"days": dleft}
else:
locale_format = self.__get_locale_string()
- if calendar.isleap(date.today().year):
- year_len = 366
- else:
- year_len = 365
+ year_len = 365 + int(calendar.isleap(date.today().year))
if float(dleft) / year_len < 1.0:
#if it's in less than a year, don't show the year field
- locale_format = locale_format.replace('/%Y','')
- return self.to_py_date().strftime(locale_format)
+ locale_format = locale_format.replace('/%Y', '')
+ return self.to_py_date().strftime(locale_format)
class FuzzyDate(Date):
+
def __init__(self, offset, name):
super(FuzzyDate, self).__init__()
- self.name=name
- self.offset=offset
-
+ self.name = name
+ self.offset = offset
+
def to_py_date(self):
- return date.today()+timedelta(self.offset)
-
+ return date.today() + timedelta(self.offset)
+
def __str__(self):
return _(self.name)
-
+
def to_readable_string(self):
- return _(self.name)
-
+ return _(self.name)
+
def xml_str(self):
- return self.name
-
+ return self.name
+
def days_left(self):
return None
-
+
+
class FuzzyDateFixed(FuzzyDate):
- def to_py_date(self):
- return self.offset
+
+ def to_py_date(self):
+ return self.offset
NOW = FuzzyDate(0, _('now'))
SOON = FuzzyDate(15, _('soon'))
LATER = FuzzyDateFixed(date.max, _('later'))
+
class RealDate(Date):
+
def __init__(self, dt):
super(RealDate, self).__init__()
assert(dt is not None)
self.proto = dt
-
+
def to_py_date(self):
return self.proto
-
+
def __str__(self):
return str(self.proto)
def days_left(self):
return (self.proto - date.today()).days
-
-DATE_MAX_MINUS_ONE = date.max-timedelta(1) # sooner than 'later'
+
+DATE_MAX_MINUS_ONE = date.max - timedelta(1) # sooner than 'later'
+
+
class NoDate(Date):
def __init__(self):
@@ -119,54 +132,59 @@
def to_py_date(self):
return DATE_MAX_MINUS_ONE
-
+
def __str__(self):
return ''
-
+
def days_left(self):
return None
-
+
def __nonzero__(self):
- return False
+ return False
+
no_date = NoDate()
-#function to convert a string of the form YYYY-MM-DD
-#to a date
-#If the date is not correct, the function returns None
-def strtodate(stri) :
- if stri == _("now") or stri == "now":
+def strtodate(stri):
+ """Funct to convert a string of the form YYYY-MM-DD or "now", "soon" and
+ "later" and localized versions to a date.
+ If the date is not correct, funct returns None."""
+ # Added this line to avoid unecessary calculations and indentation.
+ if not stri:
+ return None
+
+ if stri in (_("now"), "now"):
return NOW
- elif stri == _("soon") or stri == "soon":
+ elif stri in (_("soon"), "soon"):
return SOON
- elif stri == _("later") or stri == "later":
+ elif stri in (_("later"), "later"):
return LATER
-
+
toreturn = None
zedate = []
- if stri :
- if '-' in stri :
- zedate = stri.split('-')
- elif '/' in stri :
- zedate = stri.split('/')
-
- if len(zedate) == 3 :
- y = zedate[0]
- m = zedate[1]
- d = zedate[2]
- if y.isdigit() and m.isdigit() and d.isdigit() :
- yy = int(y)
- mm = int(m)
- dd = int(d)
- # we catch exceptions here
- try :
- toreturn = date(yy,mm,dd)
- except ValueError:
- toreturn = None
-
- if not toreturn: return no_date
- else: return RealDate(toreturn)
-
-
+
+ if '-' in stri:
+ zedate = stri.split('-')
+ elif '/' in stri:
+ zedate = stri.split('/')
+
+ if len(zedate) == 3:
+ y, m, d = zedate[:3]
+ if y.isdigit() and m.isdigit() and d.isdigit():
+ yy = int(y)
+ mm = int(m)
+ dd = int(d)
+ # we catch exceptions here
+ try:
+ toreturn = date(yy, mm, dd)
+ except ValueError:
+ toreturn = None
+
+ if not toreturn:
+ return no_date
+ else:
+ return RealDate(toreturn)
+
+
def date_today():
return RealDate(date.today())
@@ -175,29 +193,22 @@
Transform "arg" in a valid yyyy-mm-dd date or return None.
"arg" can be a yyyy-mm-dd, yyyymmdd, mmdd, today, next week,
next month, next year, or a weekday name.
- Literals are accepted both in english and in the locale language.
- When clashes occur the locale takes precedence.
"""
today = date.today()
- #FIXME: there surely exist a way to get day names from the datetime
- # or time module.
- day_names = ["monday", "tuesday", "wednesday", \
- "thursday", "friday", "saturday", \
- "sunday"]
- day_names_localized = [_("monday"), _("tuesday"), _("wednesday"), \
- _("thursday"), _("friday"), _("saturday"), \
- _("sunday")]
+ # Next line was mostly taken from calendar module, it's the way they
+ # get the full days name (Not localized.)
+ day_names = [date(2001, 1, i + 1).strftime('%A') for i in xrange(7)]
+ # This line gets the localized name, so it avoids having +7 strings in
+ # each language.
+ day_names_localized = [day for day in calendar.day_name]
delta_day_names = {"today": 0, \
"tomorrow": 1, \
"next week": 7, \
"next month": calendar.mdays[today.month], \
"next year": 365 + int(calendar.isleap(today.year))}
- delta_day_names_localized = \
- {_("today"): 0, \
- _("tomorrow"): 1, \
- _("next week"): 7, \
- _("next month"): calendar.mdays[today.month], \
- _("next year"): 365 + int(calendar.isleap(today.year))}
+ # For next line there's a more elegant way to do it but it's 2.7
+ # only. Infact dict comprehensions doesn't exist before that.
+ delta_day_names_localized = dict([(_(delta), i) for delta, i in delta_day_names.iteritems()])
### String sanitization
arg = arg.lower()
### Conversion
@@ -208,23 +219,22 @@
assert(len(arg) == 8)
arg = "%s-%s-%s" % (arg[:4], arg[4:6], arg[6:])
#today, tomorrow, next {week, months, year}
- elif arg in delta_day_names.keys() or \
- arg in delta_day_names_localized.keys():
+ elif arg in delta_day_names.keys() or \
+ arg in delta_day_names_localized.keys():
if arg in delta_day_names:
delta = delta_day_names[arg]
else:
delta = delta_day_names_localized[arg]
- arg = (today + timedelta(days = delta)).isoformat()
+ arg = (today + timedelta(days=delta)).isoformat()
elif arg in day_names or arg in day_names_localized:
if arg in day_names:
arg_day = day_names.index(arg)
else:
arg_day = day_names_localized.index(arg)
today_day = today.weekday()
- next_date = timedelta(days = arg_day - today_day + \
+ next_date = timedelta(days=arg_day - today_day + \
7 * int(arg_day <= today_day)) + today
arg = "%i-%i-%i" % (next_date.year, \
next_date.month, \
next_date.day)
return strtodate(arg)
-
Follow ups