Merge lp:~openerp-dev/openobject-server/trunk-bug-729690-nch into lp:openobject-server

Proposed by Naresh(OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openobject-server/trunk-bug-729690-nch
Merge into: lp:openobject-server
Diff against target: 214 lines (+64/-31)
4 files modified
openerp/osv/orm.py (+2/-2)
openerp/report/printscreen/ps_list.py (+3/-9)
openerp/report/report_sxw.py (+17/-17)
openerp/tools/misc.py (+42/-3)
To merge this branch: bzr merge lp:~openerp-dev/openobject-server/trunk-bug-729690-nch
Reviewer Review Type Date Requested Status
Vo Minh Thu Pending
Olivier Dony (Odoo) Pending
Review via email: mp+78833@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

3747. By Naresh(OpenERP)

[IMP]:improvements

3746. By Naresh(OpenERP)

[IMP]:added test for timezone and made a separate function in misc for babel strftime

3745. By Naresh(OpenERP)

[FIX/IMP]:Date format should not rely on the locale of the OpenERP server (e.g for month names)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/osv/orm.py'
2--- openerp/osv/orm.py 2011-10-07 14:49:44 +0000
3+++ openerp/osv/orm.py 2011-10-10 13:01:29 +0000
4@@ -397,17 +397,17 @@
5 # TODO: improve this, very slow for reports
6 if self._fields_process:
7 lang = self._context.get('lang', 'en_US') or 'en_US'
8+ timezone = self._context.get('tz', 'UTC') or 'UTC'
9 lang_obj_ids = self.pool.get('res.lang').search(self._cr, self._uid, [('code', '=', lang)])
10 if not lang_obj_ids:
11 raise Exception(_('Language with code "%s" is not defined in your system !\nDefine it through the Administration menu.') % (lang,))
12 lang_obj = self.pool.get('res.lang').browse(self._cr, self._uid, lang_obj_ids[0])
13-
14 for field_name, field_column in fields_to_fetch:
15 if field_column._type in self._fields_process:
16 for result_line in field_values:
17 result_line[field_name] = self._fields_process[field_column._type](result_line[field_name])
18 if result_line[field_name]:
19- result_line[field_name].set_value(self._cr, self._uid, result_line[field_name], self, field_column, lang_obj)
20+ result_line[field_name].set_value(self._cr, self._uid, result_line[field_name], self, field_column, lang_obj, timezone)
21
22 if not field_values:
23 # Where did those ids come from? Perhaps old entries in ir_model_dat?
24
25=== modified file 'openerp/report/printscreen/ps_list.py'
26--- openerp/report/printscreen/ps_list.py 2011-06-23 09:04:57 +0000
27+++ openerp/report/printscreen/ps_list.py 2011-10-10 13:01:29 +0000
28@@ -26,7 +26,6 @@
29 from lxml import etree
30 from openerp.report import render, report_sxw
31 import locale
32-
33 import time, os
34 from operator import itemgetter
35 from datetime import datetime
36@@ -137,7 +136,7 @@
37
38 _append_node('company', pooler.get_pool(self.cr.dbname).get('res.users').browse(self.cr,uid,uid).company_id.name)
39 rpt_obj = pooler.get_pool(self.cr.dbname).get('res.users')
40- rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name,context)
41+ rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name, context=context)
42 _append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")))
43 l = []
44 t = 0
45@@ -198,9 +197,7 @@
46 if fields[f]['type'] == 'date' and line[f]:
47 new_d1 = line[f]
48 if not line.get('__group'):
49- format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))
50- d1 = datetime.strptime(line[f],'%Y-%m-%d')
51- new_d1 = d1.strftime(format)
52+ new_d1 = rml_obj.formatLang(value = line[f], date=True)
53 line[f] = new_d1
54
55 if fields[f]['type'] == 'time' and line[f]:
56@@ -214,12 +211,9 @@
57 if fields[f]['type'] == 'datetime' and line[f]:
58 new_d1 = line[f]
59 if not line.get('__group'):
60- format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))+' '+str(locale.nl_langinfo(locale.T_FMT))
61- d1 = datetime.strptime(line[f], '%Y-%m-%d %H:%M:%S')
62- new_d1 = d1.strftime(format)
63+ new_d1 = rml_obj.formatLang(value =line[f], date_time=True)
64 line[f] = new_d1
65
66-
67 if line.get('__group'):
68 col = etree.SubElement(node_line, 'col', para='group', tree='no')
69 else:
70
71=== modified file 'openerp/report/report_sxw.py'
72--- openerp/report/report_sxw.py 2011-09-21 23:21:50 +0000
73+++ openerp/report/report_sxw.py 2011-10-10 13:01:29 +0000
74@@ -72,12 +72,16 @@
75 return len((datetime.now()).strftime(date_format))
76
77 class _format(object):
78- def set_value(self, cr, uid, name, object, field, lang_obj):
79+ def set_value(self, cr, uid, name, object, field, lang_obj, tz='UTC'):
80 self.object = object
81 self._field = field
82 self.name = name
83 self.lang_obj = lang_obj
84-
85+ self.date_fmt = re.sub(tools.babel_fmt_pattern, tools.fmt_sub, self.lang_obj.date_format)
86+ self.time_fmt = re.sub(tools.babel_fmt_pattern, tools.fmt_sub, self.lang_obj.time_format)
87+ self.datetime_fmt = self.date_fmt + " " + self.time_fmt
88+ self.locale_tz = tz
89+
90 class _float_format(float, _format):
91 def __init__(self,value):
92 super(_float_format, self).__init__()
93@@ -110,7 +114,7 @@
94 if self.val:
95 if getattr(self,'name', None):
96 date = datetime.strptime(self.name[:get_date_length()], DT_FORMAT)
97- return date.strftime(str(self.lang_obj.date_format))
98+ return tools.format_datetime(date, self.date_fmt, self.lang_obj.code, self.locale_tz)
99 return self.val
100
101 class _dttime_format(str, _format):
102@@ -120,9 +124,8 @@
103
104 def __str__(self):
105 if self.val and getattr(self,'name', None):
106- return datetime.strptime(self.name, DHM_FORMAT)\
107- .strftime("%s %s"%(str(self.lang_obj.date_format),
108- str(self.lang_obj.time_format)))
109+ date = datetime.strptime(self.name, DHM_FORMAT)
110+ return tools.format_datetime(date, self.datetime_fmt, self.lang_obj.code, self.locale_tz)
111 return self.val
112
113
114@@ -289,22 +292,19 @@
115 self.lang_dict_called = True
116
117 if date or date_time:
118- if not str(value):
119- return ''
120-
121- date_format = self.lang_dict['date_format']
122+ date_format = re.sub(tools.babel_fmt_pattern, tools.fmt_sub, self.lang_dict['date_format'])
123+ datetime_format = re.sub(tools.babel_fmt_pattern, tools.fmt_sub, self.lang_dict['time_format'])
124 parse_format = DT_FORMAT
125+ locale_lang = self.localcontext.get('lang', 'en_US') or 'en_US'
126+ locale_tz = self.localcontext.get('tz', 'UTC') or 'UTC'
127 if date_time:
128 value=value.split('.')[0]
129- date_format = date_format + " " + self.lang_dict['time_format']
130+ date_format = date_format + " " + datetime_format
131 parse_format = DHM_FORMAT
132 if not isinstance(value, time.struct_time):
133- return time.strftime(date_format, time.strptime(value[:get_date_length(parse_format)], parse_format))
134-
135- else:
136- date = datetime(*value.timetuple()[:6])
137- return date.strftime(date_format)
138-
139+ return tools.format_datetime(datetime.strptime(value[:get_date_length(parse_format)], parse_format)
140+ ,date_format, locale_lang, locale_tz)
141+ return tools.format_datetime(datetime(*value.timetuple()[:6]), date_format, locale_lang, locale_tz)
142 res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
143 if currency_obj:
144 if currency_obj.position == 'after':
145
146=== modified file 'openerp/tools/misc.py'
147--- openerp/tools/misc.py 2011-09-22 09:54:43 +0000
148+++ openerp/tools/misc.py 2011-10-10 13:01:29 +0000
149@@ -38,6 +38,11 @@
150 import time
151 import warnings
152 import zipfile
153+import babel.dates
154+try:
155+ import pytz
156+except Exception:
157+ pytz = None
158 from collections import defaultdict
159 from datetime import datetime
160 from email.MIMEText import MIMEText
161@@ -935,9 +940,7 @@
162 Defaults to UTC if no working timezone can be found.
163 @return the timezone identifier as expected by pytz.timezone.
164 """
165- try:
166- import pytz
167- except Exception:
168+ if pytz is None:
169 loglevels.Logger().notifyChannel("detect_server_timezone", loglevels.LOG_WARNING,
170 "Python pytz module is not available. Timezone will be set to UTC by default.")
171 return 'UTC'
172@@ -993,6 +996,42 @@
173 DEFAULT_SERVER_DATE_FORMAT,
174 DEFAULT_SERVER_TIME_FORMAT)
175
176+##TODO:remove this monkey patch when the bug is fixed in the babel
177+## There is a bug when the format contains 'w', D','Y' in babel.dates.DateTimeFormat.get_day_of_year
178+def get_day_of_year(self, date=None):
179+ if date is None:
180+ date = self.value
181+ return (date - date.replace(day=1,month=1)).days + 1
182+try:
183+ babel.dates.format_datetime(datetime.utcnow(),'D')
184+except TypeError:
185+ babel.dates.DateTimeFormat.get_day_of_year = get_day_of_year
186+
187+##Format Conversion function used to convert from normal to babel format
188+strftime_to_unicode = {'a':'E','A':'EEEE','b': 'MMM','B':'MMMM','c': 'E MMM d hh:mm:ss yyyy','d':'d','H': 'HH',
189+ 'I': 'hh','j': 'D','m': 'MM','M': 'mm','p': 'a','S': 'ss','w': 'e','x': 'M/d/yy','X': 'hh:mm:ss',
190+ 'y': 'yy','Y': 'yyyy','U': 'w','W': 'w'
191+ }
192+babel_fmt_pattern = r"(%%|%\w|[^%]+)"
193+
194+def fmt_sub(match):
195+ if match.group(0) == '%%':
196+ return '%'
197+ if match.group(0).startswith('%'):
198+ # do sub by looking up into dict
199+ # + need to handle %x/%X separately as 'short' currently its replaced statically
200+ return (strftime_to_unicode[match.group(0)[1]]).replace("'","")
201+ return "'%s'" % match.group(0).replace("'","''")
202+
203+def format_datetime(value, format, locale='en_us', tz='UTC'):
204+ if pytz is None:
205+ return babel.dates.format_datetime(value, format, locale=locale)
206+ try:
207+ tz = pytz.timezone(tz)
208+ except pytz.UnknownTimeZoneError:
209+ tz = None
210+ return babel.dates.format_datetime(value, format, locale=locale, tzinfo=tz)
211+
212 # Python's strftime supports only the format directives
213 # that are available on the platform's libc, so in order to
214 # be cross-platform we map to the directives required by