Skip to content

Commit 195c0e7

Browse files
author
Andrey Lebedev
committed
Added users' timezone support
1 parent f05877d commit 195c0e7

File tree

8 files changed

+75
-12
lines changed

8 files changed

+75
-12
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ are given with the most recent entry first.
2323
according to rfc2822 (sf bug 568873)
2424
- fixed cookie path to use TRACKER_WEB (sf bug 667020) (thanks Nathaniel Smith
2525
for helping chase it down and Luke Opperman for confirming fix)
26+
- added ability to display localized dates in web interface. User input is
27+
convered to GMT (see doc/upgrading.txt).
2628

2729

2830
2003-??-?? 0.5.5

doc/upgrading.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,40 @@ Migrating from 0.5 to 0.6
4646
is no tool for converting such data, the only solution is to close
4747
appropriate old issues and create new ones with the same content.
4848

49+
0.6.0 User' timezone support
50+
----------------------------
51+
52+
- From version 0.6.0 roundup supports displaying of Date data in user' local
53+
timezone if he/she has provided timezone information. To make it possible
54+
some modification to tracker's schema and HTML templates are required.
55+
First you should add string property 'timezone' to user class in dbinit.py
56+
like this:
57+
58+
user = Class(db, "user",
59+
username=String(), password=Password(),
60+
address=String(), realname=String(),
61+
phone=String(), organisation=String(),
62+
alternate_addresses=String(),
63+
queries=Multilink('query'), roles=String(),
64+
timezone=String())
65+
66+
And second - html interface. Add following lines to
67+
$TRACKER_HOME/html/user.item template:
68+
69+
<tr>
70+
<th>Timezone</th>
71+
<td tal:content="structure context/timezone/field">timezone</td>
72+
</tr>
73+
74+
After that all users should be able to provide their timezone information.
75+
Timezone should be a positive or negative integer - offset from GMT.
76+
77+
After providing timezone, roundup will show all dates values, found in web
78+
and mail interfaces in local time. It will also accept any Date info in
79+
local time, convert and store it in GMT.
80+
81+
However you are not forced to make these modifications. By default roundup
82+
will assume timezone=0 and will work as previous versions did.
4983

5084
Migrating from 0.4.x to 0.5.0
5185
=============================

roundup/cgi/client.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: client.py,v 1.73 2003-01-24 06:21:17 richard Exp $
1+
# $Id: client.py,v 1.74 2003-01-27 16:32:48 kedder Exp $
22

33
__doc__ = """
44
WWW request handler (also used in the stand-alone server).
@@ -1209,6 +1209,8 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
12091209
props = {}
12101210
keys = form.keys()
12111211
properties = cl.getprops()
1212+
timezone = db.getUserTimezone()
1213+
12121214
for key in keys:
12131215
# see if we're performing a special multilink action
12141216
mlaction = 'set'
@@ -1351,7 +1353,7 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
13511353
# fix the CRLF/CR -> LF stuff
13521354
value = fixNewlines(value)
13531355
elif isinstance(proptype, hyperdb.Date):
1354-
value = date.Date(value)
1356+
value = date.Date(value, offset=timezone)
13551357
elif isinstance(proptype, hyperdb.Interval):
13561358
value = date.Interval(value)
13571359
elif isinstance(proptype, hyperdb.Boolean):

roundup/cgi/templating.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ def history(self, direction='descending', dre=re.compile('\d+')):
515515
comments = {}
516516
history = self._klass.history(self._nodeid)
517517
history.sort()
518+
timezone = self._db.getUserTimezone()
518519
if direction == 'descending':
519520
history.reverse()
520521
for prop_n in self._props.keys():
@@ -530,7 +531,7 @@ def history(self, direction='descending', dre=re.compile('\d+')):
530531
self._klass.get(self._nodeid, prop_n, None), current[prop_n])
531532

532533
for id, evt_date, user, action, args in history:
533-
date_s = str(evt_date).replace("."," ")
534+
date_s = str(evt_date.local(timezone)).replace("."," ")
534535
arg_s = ''
535536
if action == 'link' and type(args) == type(()):
536537
if len(args) == 3:
@@ -632,10 +633,10 @@ def history(self, direction='descending', dre=re.compile('\d+')):
632633
current[k] = old
633634

634635
elif isinstance(prop, hyperdb.Date) and args[k]:
635-
d = date.Date(args[k])
636+
d = date.Date(args[k]).local(timezone)
636637
cell.append('%s: %s'%(k, str(d)))
637638
if current.has_key(k):
638-
cell[-1] += ' -> %s'%current[k]
639+
cell[-1] += ' -> %s' % date.Date(current[k]).local(timezone)
639640
current[k] = str(d)
640641

641642
elif isinstance(prop, hyperdb.Interval) and args[k]:
@@ -918,15 +919,15 @@ def plain(self):
918919
'''
919920
if self._value is None:
920921
return ''
921-
return str(self._value)
922+
return str(self._value.local(self._db.getUserTimezone()))
922923

923924
def field(self, size = 30):
924925
''' Render a form edit field for the property
925926
'''
926927
if self._value is None:
927928
value = ''
928929
else:
929-
value = cgi.escape(str(self._value))
930+
value = cgi.escape(str(self._value.local(self._db.getUserTimezone())))
930931
value = '&quot;'.join(value.split('"'))
931932
return '<input name="%s" value="%s" size="%s">'%(self._name, value, size)
932933

roundup/mailgw.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class node. Any parts of other types are each stored in separate files
7373
an exception, the original message is bounced back to the sender with the
7474
explanatory message given in the exception.
7575
76-
$Id: mailgw.py,v 1.107 2003-01-15 22:17:19 kedder Exp $
76+
$Id: mailgw.py,v 1.108 2003-01-27 16:32:46 kedder Exp $
7777
'''
7878

7979
import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
@@ -869,7 +869,7 @@ def setPropArrayFromString(self, cl, propString, nodeid = None):
869869
props[propname] = password.Password(value.strip())
870870
elif isinstance(proptype, hyperdb.Date):
871871
try:
872-
props[propname] = date.Date(value.strip())
872+
props[propname] = date.Date(value.strip()).local(self.db.getUserTimezone())
873873
except ValueError, message:
874874
errors.append('contains an invalid date for %s.'%propname)
875875
elif isinstance(proptype, hyperdb.Interval):

roundup/roundupdb.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: roundupdb.py,v 1.78 2003-01-15 22:17:19 kedder Exp $
18+
# $Id: roundupdb.py,v 1.79 2003-01-27 16:32:48 kedder Exp $
1919

2020
__doc__ = """
2121
Extending hyperdb with types specific to issue-tracking.
@@ -55,6 +55,20 @@ def getuid(self):
5555
that owns this connection to the hyperdatabase."""
5656
return self.user.lookup(self.journaltag)
5757

58+
def getUserTimezone(self):
59+
"""Return user timezone defined in 'timezone' property of user class.
60+
If no such property exists return 0
61+
"""
62+
userid = self.getuid()
63+
try:
64+
timezone = int(self.user.get(userid, 'timezone'))
65+
except (KeyError, ValueError):
66+
# If there is no class 'user' or current user doesn't have timezone
67+
# property or that property is not numeric assume he/she lives in
68+
# Greenwich :)
69+
timezone = 0
70+
return timezone
71+
5872
class MessageSendError(RuntimeError):
5973
pass
6074

roundup/templates/classic/dbinit.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: dbinit.py,v 1.31 2002-10-10 07:17:39 richard Exp $
18+
# $Id: dbinit.py,v 1.32 2003-01-27 16:32:50 kedder Exp $
1919

2020
import os
2121

@@ -65,7 +65,9 @@ def open(name=None):
6565
address=String(), realname=String(),
6666
phone=String(), organisation=String(),
6767
alternate_addresses=String(),
68-
queries=Multilink('query'), roles=String())
68+
queries=Multilink('query'), roles=String(),
69+
timezone=String())
70+
)
6971
user.setkey("username")
7072

7173
# FileClass automatically gets these properties:

roundup/templates/classic/html/user.item

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ You are not allowed to view this page.
4848
<th>Organisation</th>
4949
<td tal:content="structure context/organisation/field">organisation</td>
5050
</tr>
51+
<tr>
52+
<th>Timezone</th>
53+
<td tal:content="structure context/timezone/field">timezone</td>
54+
</tr>
5155
<tr>
5256
<th>E-mail address</th>
5357
<td tal:content="structure context/address/field">address</td>
@@ -95,6 +99,10 @@ You are not allowed to view this page.
9599
<th>Organisation</th>
96100
<td tal:content="context/organisation">organisation</td>
97101
</tr>
102+
<tr>
103+
<th>Timezone</th>
104+
<td tal:content="context/timezone">timezone</td>
105+
</tr>
98106
<tr>
99107
<th>E-mail address</th>
100108
<td tal:content="context/address/email">address</td>

0 commit comments

Comments
 (0)