GTG

Merge lp:~gtg-user/gtg/improved_tools_dates.py into lp:~gtg/gtg/old-trunk

Proposed by Thibault Févry
Status: Rejected
Rejected by: Izidor Matušov
Proposed branch: lp:~gtg-user/gtg/improved_tools_dates.py
Merge into: lp:~gtg/gtg/old-trunk
Diff against target: 323 lines (+102/-92)
2 files modified
GTG/gtk/editor/editor.py (+1/-1)
GTG/tools/dates.py (+101/-91)
To merge this branch: bzr merge lp:~gtg-user/gtg/improved_tools_dates.py
Reviewer Review Type Date Requested Status
Izidor Matušov Needs Resubmitting
Gtg developers test in different locales perhaps. Pending
Review via email: mp+34697@code.launchpad.net

Commit message

Optimizations and improvements in tools-dates.py (This shouldn't change anything for developpers or users.

Description of the change

 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.)

To post a comment you must log in.
Revision history for this message
Luca Invernizzi (invernizzi) wrote :

Great! thanks for this. You just gained the pep8-defender badge :P

Revision history for this message
Paul Natsuo Kishimoto (khaeru) wrote :

Using the calendar module's localized day names was one of the changes already made in https://code.edge.launchpad.net/~gtg-contributors/gtg/new-date-class/+merge/28009

Nobody has touched that one for a while, but it *is* still available to commit, without conflicts. Which of these two should be merged?

Thibault, if you like I can update my branch to incorporate your changes. That will probably be easier than vice-versa.

Revision history for this message
Luca Invernizzi (invernizzi) wrote :

Un-committing since it has problems with due dates not set (i.e., set to None). I'm trying to get a stable trunk, so I prefer that new bugs are fixed before merging. We have already enough :)

Traceback:

None
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/luca/Projects/gtg/TRUNK/GTG/core/datastore.py", line 401, in __start_get_tasks
    self.backend.start_get_tasks()
  File "/home/luca/Projects/gtg/TRUNK/GTG/backends/backend_localfile.py", line 129, in start_get_tasks
    task = taskxml.task_from_xml(task, node)
  File "/home/luca/Projects/gtg/TRUNK/GTG/tools/taskxml.py", line 58, in task_from_xml
    cur_task.set_due_date(dates.strtodate(cleanxml.readTextNode(xmlnode,"duedate")))
  File "/home/luca/Projects/gtg/TRUNK/GTG/core/task.py", line 193, in set_due_date
    assert(isinstance(fulldate, Date))
AssertionError

(fulldate is None).

About Paul branch, since you both have worked on this matter you can figure out how to merge the two the best. I'm still not convinced about the elimination of FuzzyDate, since it was useful to get the type of the date for syncing with the backends. There is the is_special() method, but that matches also NoDate.

Revision history for this message
Thibault Févry (thibaultfevry) wrote :

As I really don't know what in the changed code does the bug, (I'm not even sure this is a bug, this just prints an exception (That we raise), but does this change anything in the way GTG handle the task with no date attribute ?), I'll do other things for now and get back later to this.

Revision history for this message
Izidor Matušov (izidor) wrote :

Marking as rejected because nothing happend for quite long time and similar changes was already merged.

review: Needs Resubmitting

Unmerged revisions

873. By Thibault Févry

Further optimizations, commit with trunk.

872. By Thibault Févry

Fix evil...

871. By Thibault Févry

Commit

870. By Thibault Févry

l

869. By Thibault Févry

Nothing, just updated to trunk.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'GTG/gtk/editor/editor.py'
2--- GTG/gtk/editor/editor.py 2010-07-06 04:01:50 +0000
3+++ GTG/gtk/editor/editor.py 2010-09-06 18:07:42 +0000
4@@ -321,7 +321,7 @@
5 #If the task is marked as done, we display the delay between the
6 #due date and the actual closing date. If the task isn't marked
7 #as done, we display the number of days left.
8- if status in [Task.STA_DISMISSED, Task.STA_DONE]:
9+ if status in (Task.STA_DISMISSED, Task.STA_DONE):
10 delay = self.task.get_days_late()
11 if delay is None:
12 txt = ""
13
14=== modified file 'GTG/tools/dates.py'
15--- GTG/tools/dates.py 2010-04-30 19:23:02 +0000
16+++ GTG/tools/dates.py 2010-09-06 18:07:42 +0000
17@@ -22,96 +22,109 @@
18 import calendar
19 from GTG import _, ngettext
20
21-#setting the locale of gtg to the system locale
22+#setting the locale of gtg to the system locale
23 #locale.setlocale(locale.LC_TIME, '')
24
25+
26 class Date(object):
27+
28 def __cmp__(self, other):
29- if other is None: return 1
30+ if other is None:
31+ return 1
32 return cmp(self.to_py_date(), other.to_py_date())
33-
34+
35 def __sub__(self, other):
36 return self.to_py_date() - other.to_py_date()
37
38 def __get_locale_string(self):
39 return locale.nl_langinfo(locale.D_FMT)
40-
41- def xml_str(self): return str(self)
42-
43- def day(self): return self.to_py_date().day
44- def month(self): return self.to_py_date().month
45- def year(self): return self.to_py_date().year
46+
47+ def xml_str(self):
48+ return str(self)
49+
50+ def day(self):
51+ return self.to_py_date().day
52+
53+ def month(self):
54+ return self.to_py_date().month
55+
56+ def year(self):
57+ return self.to_py_date().year
58
59 def to_readable_string(self):
60 if self.to_py_date() == NoDate().to_py_date():
61 return None
62 dleft = (self.to_py_date() - date.today()).days
63- if dleft == 0:
64+ if not dleft:
65 return _("Today")
66 elif dleft < 0:
67 abs_days = abs(dleft)
68 return ngettext("Yesterday", "%(days)d days ago", abs_days) % \
69 {"days": abs_days}
70- elif dleft > 0 and dleft <= 15:
71+ elif 0 < dleft <= 15:
72 return ngettext("Tomorrow", "In %(days)d days", dleft) % \
73 {"days": dleft}
74 else:
75 locale_format = self.__get_locale_string()
76- if calendar.isleap(date.today().year):
77- year_len = 366
78- else:
79- year_len = 365
80+ year_len = 365 + int(calendar.isleap(date.today().year))
81 if float(dleft) / year_len < 1.0:
82 #if it's in less than a year, don't show the year field
83- locale_format = locale_format.replace('/%Y','')
84- return self.to_py_date().strftime(locale_format)
85+ locale_format = locale_format.replace('/%Y', '')
86+ return self.to_py_date().strftime(locale_format)
87
88
89 class FuzzyDate(Date):
90+
91 def __init__(self, offset, name):
92 super(FuzzyDate, self).__init__()
93- self.name=name
94- self.offset=offset
95-
96+ self.name = name
97+ self.offset = offset
98+
99 def to_py_date(self):
100- return date.today()+timedelta(self.offset)
101-
102+ return date.today() + timedelta(self.offset)
103+
104 def __str__(self):
105 return _(self.name)
106-
107+
108 def to_readable_string(self):
109- return _(self.name)
110-
111+ return _(self.name)
112+
113 def xml_str(self):
114- return self.name
115-
116+ return self.name
117+
118 def days_left(self):
119 return None
120-
121+
122+
123 class FuzzyDateFixed(FuzzyDate):
124- def to_py_date(self):
125- return self.offset
126+
127+ def to_py_date(self):
128+ return self.offset
129
130 NOW = FuzzyDate(0, _('now'))
131 SOON = FuzzyDate(15, _('soon'))
132 LATER = FuzzyDateFixed(date.max, _('later'))
133
134+
135 class RealDate(Date):
136+
137 def __init__(self, dt):
138 super(RealDate, self).__init__()
139 assert(dt is not None)
140 self.proto = dt
141-
142+
143 def to_py_date(self):
144 return self.proto
145-
146+
147 def __str__(self):
148 return str(self.proto)
149
150 def days_left(self):
151 return (self.proto - date.today()).days
152-
153-DATE_MAX_MINUS_ONE = date.max-timedelta(1) # sooner than 'later'
154+
155+DATE_MAX_MINUS_ONE = date.max - timedelta(1) # sooner than 'later'
156+
157+
158 class NoDate(Date):
159
160 def __init__(self):
161@@ -119,54 +132,59 @@
162
163 def to_py_date(self):
164 return DATE_MAX_MINUS_ONE
165-
166+
167 def __str__(self):
168 return ''
169-
170+
171 def days_left(self):
172 return None
173-
174+
175 def __nonzero__(self):
176- return False
177+ return False
178+
179 no_date = NoDate()
180
181-#function to convert a string of the form YYYY-MM-DD
182-#to a date
183-#If the date is not correct, the function returns None
184-def strtodate(stri) :
185- if stri == _("now") or stri == "now":
186+def strtodate(stri):
187+ """Funct to convert a string of the form YYYY-MM-DD or "now", "soon" and
188+ "later" and localized versions to a date.
189+ If the date is not correct, funct returns None."""
190+ # Added this line to avoid unecessary calculations and indentation.
191+ if not stri:
192+ return None
193+
194+ if stri in (_("now"), "now"):
195 return NOW
196- elif stri == _("soon") or stri == "soon":
197+ elif stri in (_("soon"), "soon"):
198 return SOON
199- elif stri == _("later") or stri == "later":
200+ elif stri in (_("later"), "later"):
201 return LATER
202-
203+
204 toreturn = None
205 zedate = []
206- if stri :
207- if '-' in stri :
208- zedate = stri.split('-')
209- elif '/' in stri :
210- zedate = stri.split('/')
211-
212- if len(zedate) == 3 :
213- y = zedate[0]
214- m = zedate[1]
215- d = zedate[2]
216- if y.isdigit() and m.isdigit() and d.isdigit() :
217- yy = int(y)
218- mm = int(m)
219- dd = int(d)
220- # we catch exceptions here
221- try :
222- toreturn = date(yy,mm,dd)
223- except ValueError:
224- toreturn = None
225-
226- if not toreturn: return no_date
227- else: return RealDate(toreturn)
228-
229-
230+
231+ if '-' in stri:
232+ zedate = stri.split('-')
233+ elif '/' in stri:
234+ zedate = stri.split('/')
235+
236+ if len(zedate) == 3:
237+ y, m, d = zedate[:3]
238+ if y.isdigit() and m.isdigit() and d.isdigit():
239+ yy = int(y)
240+ mm = int(m)
241+ dd = int(d)
242+ # we catch exceptions here
243+ try:
244+ toreturn = date(yy, mm, dd)
245+ except ValueError:
246+ toreturn = None
247+
248+ if not toreturn:
249+ return no_date
250+ else:
251+ return RealDate(toreturn)
252+
253+
254 def date_today():
255 return RealDate(date.today())
256
257@@ -175,29 +193,22 @@
258 Transform "arg" in a valid yyyy-mm-dd date or return None.
259 "arg" can be a yyyy-mm-dd, yyyymmdd, mmdd, today, next week,
260 next month, next year, or a weekday name.
261- Literals are accepted both in english and in the locale language.
262- When clashes occur the locale takes precedence.
263 """
264 today = date.today()
265- #FIXME: there surely exist a way to get day names from the datetime
266- # or time module.
267- day_names = ["monday", "tuesday", "wednesday", \
268- "thursday", "friday", "saturday", \
269- "sunday"]
270- day_names_localized = [_("monday"), _("tuesday"), _("wednesday"), \
271- _("thursday"), _("friday"), _("saturday"), \
272- _("sunday")]
273+ # Next line was mostly taken from calendar module, it's the way they
274+ # get the full days name (Not localized.)
275+ day_names = [date(2001, 1, i + 1).strftime('%A') for i in xrange(7)]
276+ # This line gets the localized name, so it avoids having +7 strings in
277+ # each language.
278+ day_names_localized = [day for day in calendar.day_name]
279 delta_day_names = {"today": 0, \
280 "tomorrow": 1, \
281 "next week": 7, \
282 "next month": calendar.mdays[today.month], \
283 "next year": 365 + int(calendar.isleap(today.year))}
284- delta_day_names_localized = \
285- {_("today"): 0, \
286- _("tomorrow"): 1, \
287- _("next week"): 7, \
288- _("next month"): calendar.mdays[today.month], \
289- _("next year"): 365 + int(calendar.isleap(today.year))}
290+ # For next line there's a more elegant way to do it but it's 2.7
291+ # only. Infact dict comprehensions doesn't exist before that.
292+ delta_day_names_localized = dict([(_(delta), i) for delta, i in delta_day_names.iteritems()])
293 ### String sanitization
294 arg = arg.lower()
295 ### Conversion
296@@ -208,23 +219,22 @@
297 assert(len(arg) == 8)
298 arg = "%s-%s-%s" % (arg[:4], arg[4:6], arg[6:])
299 #today, tomorrow, next {week, months, year}
300- elif arg in delta_day_names.keys() or \
301- arg in delta_day_names_localized.keys():
302+ elif arg in delta_day_names.keys() or \
303+ arg in delta_day_names_localized.keys():
304 if arg in delta_day_names:
305 delta = delta_day_names[arg]
306 else:
307 delta = delta_day_names_localized[arg]
308- arg = (today + timedelta(days = delta)).isoformat()
309+ arg = (today + timedelta(days=delta)).isoformat()
310 elif arg in day_names or arg in day_names_localized:
311 if arg in day_names:
312 arg_day = day_names.index(arg)
313 else:
314 arg_day = day_names_localized.index(arg)
315 today_day = today.weekday()
316- next_date = timedelta(days = arg_day - today_day + \
317+ next_date = timedelta(days=arg_day - today_day + \
318 7 * int(arg_day <= today_day)) + today
319 arg = "%i-%i-%i" % (next_date.year, \
320 next_date.month, \
321 next_date.day)
322 return strtodate(arg)
323-

Subscribers

People subscribed via source and target branches

to status/vote changes: