Merge lp:~fabien-morin/unifield-server/fm-us-2339-new into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 4237
Proposed branch: lp:~fabien-morin/unifield-server/fm-us-2339-new
Merge into: lp:unifield-server
Diff against target: 243 lines (+83/-46)
7 files modified
bin/addons/msf_profile/i18n/fr_MF.po (+7/-0)
bin/addons/report_webkit/webkit_report.py (+51/-3)
bin/addons/spreadsheet_xml/spreadsheet_xml.py (+1/-1)
bin/addons/sync_client/backup.py (+2/-2)
bin/tools/misc.py (+1/-1)
setup.py (+13/-13)
setup_py2exe_custom.py (+8/-26)
To merge this branch: bzr merge lp:~fabien-morin/unifield-server/fm-us-2339-new
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+317788@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jeff Allen (jr.allen) :
4206. By Fabien MORIN

US-2339 [FIX] no need to parse two times the same xml document

4207. By Fabien MORIN

US-2339 [MERGE] with latest trunk

4208. By Fabien MORIN

US-2339 [FIX] revert us-2374 as it breaks the AIO generation

4209. By Fabien MORIN

US-2339 [IMP] avoid crashing by ensuring name and sheet_name cannot be None

4210. By Fabien MORIN

US-2339 [ADD] translation for the Sheet name

4211. By Fabien MORIN

US-2339 [FIX] if xml is modified in any of this two check :
- worksheet name
- malformed data
the modified xml should be returned.
If not modified, return the original xml

4212. By Fabien MORIN

US-2339 [FIX] getiterator is depreciated since long time, use iter instead
[FIX] iter (and getiterator now) cannot be restricted by
receiving a QName object but only (from
http://lxml.de/api/lxml.etree._Element-class.html#iter)
"Can be restricted to find only elements with a specific tag: pass
"{ns}localname" as tag. Either or both of ns and localname can be * for a
wildcard; ns can be empty for no namespace. "localname" is equivalent to
"{}localname" (i.e. no namespace) but "*" is "{*}*" (any or no namespace), not
"{}*".

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
2--- bin/addons/msf_profile/i18n/fr_MF.po 2017-02-20 16:10:18 +0000
3+++ bin/addons/msf_profile/i18n/fr_MF.po 2017-02-21 15:07:51 +0000
4@@ -76441,3 +76441,10 @@
5 #, python-format
6 msgid "No journal found to book the reversal FX entry."
7 msgstr "Pas de journal trouvé pour enregistrer l'annulation de l'écriture de différence de change."
8+
9+#. module: report_webkit
10+#: code:addons/report_webkit/webkit_report.py:435
11+#: code:addons/report_webkit/webkit_report.py:466
12+#, python-format
13+msgid "Sheet 1"
14+msgstr "Feuille 1"
15
16=== modified file 'bin/addons/report_webkit/webkit_report.py'
17--- bin/addons/report_webkit/webkit_report.py 2017-02-09 13:41:23 +0000
18+++ bin/addons/report_webkit/webkit_report.py 2017-02-21 15:07:51 +0000
19@@ -423,6 +423,26 @@
20
21 return result
22
23+ def sanitizeWorksheetName(self, name):
24+ '''
25+ according to microsoft documentation :
26+ https://msdn.microsoft.com/en-us/library/office/aa140066(v=office.10).aspx#odc_xmlss_ss:worksheet
27+ The following caracters are not allowed : /, \, ?, *, [, ]
28+ It also seems that microsoft excel do not accept Worksheet name longer
29+ than 31 characters.
30+ '''
31+ if not name:
32+ return _('Sheet 1')
33+ replacement_char = '-'
34+ not_allowed_char_list = ['/', '\\', '?', '*', '[', ']']
35+ new_name = name
36+ if set(new_name).intersection(not_allowed_char_list):
37+ for char in not_allowed_char_list:
38+ if char in new_name:
39+ new_name = new_name.replace(char, replacement_char)
40+
41+ return new_name[:31]
42+
43 def check_malformed_xml_spreadsheet(self, xml_string, report_name):
44 '''Check that the xml spreadsheet doesn't contain
45 node <Date ss:Type="DateTime"> with 'False' in the values
46@@ -431,10 +451,37 @@
47 logger = logging.getLogger('mako_spreadsheet')
48 file_dom = etree.fromstring(xml_string)
49 namespaces = {
50+ 'o': 'urn:schemas-microsoft-com:office:office',
51+ 'x': 'urn:schemas-microsoft-com:office:excel',
52 'ss': 'urn:schemas-microsoft-com:office:spreadsheet',
53- 'spreadsheet': 'urn:schemas-microsoft-com:office:spreadsheet'
54+ 'html': 'http://www.w3.org/TR/REC-html40'
55 }
56- data_time_elements = file_dom.xpath('//spreadsheet:Data[@ss:Type="DateTime"]',
57+
58+ spreadsheet_elements = file_dom.xpath('//ss:Worksheet',
59+ namespaces=namespaces)
60+
61+ xml_modified = False
62+ sheet_name_dict = {}
63+ count = 0
64+ for sheet in spreadsheet_elements:
65+ sheet_name = sheet.get('{%(ss)s}Name' % namespaces, _('Sheet 1'))
66+ new_name = self.sanitizeWorksheetName(sheet_name)
67+ if new_name != sheet_name:
68+ # if the sheet name already exists, modify it to add
69+ # a counter to the name
70+ if new_name in sheet_name_dict:
71+ sheet_name_dict[new_name] += 1
72+ count = sheet_name_dict[new_name]
73+ new_name = '%s_%s' % (new_name[:28], count)
74+ else:
75+ sheet_name_dict[new_name] = 1
76+ sheet.attrib['{urn:schemas-microsoft-com:office:spreadsheet}Name'] = new_name
77+ xml_modified = True
78+ else:
79+ if new_name not in sheet_name_dict:
80+ sheet_name_dict[new_name] = 1
81+
82+ data_time_elements = file_dom.xpath('//ss:Data[@ss:Type="DateTime"]',
83 namespaces=namespaces)
84 element_to_remove = []
85 for element in data_time_elements:
86@@ -446,7 +493,8 @@
87 # if a malformed node exists, replace it with an empty String cell
88 element.attrib['{urn:schemas-microsoft-com:office:spreadsheet}Type'] = 'String'
89 element.text = ''
90- if element_to_remove:
91+ xml_modified = True
92+ if xml_modified:
93 # return modified xml
94 return etree.tostring(file_dom, xml_declaration=True, encoding="utf-8")
95 return xml_string
96
97=== modified file 'bin/addons/spreadsheet_xml/spreadsheet_xml.py'
98--- bin/addons/spreadsheet_xml/spreadsheet_xml.py 2016-08-26 10:10:58 +0000
99+++ bin/addons/spreadsheet_xml/spreadsheet_xml.py 2017-02-21 15:07:51 +0000
100@@ -137,7 +137,7 @@
101
102 def getRows(self,worksheet=1):
103 table = self.xmlobj.xpath('//ss:Worksheet[%d]/ss:Table[1]'%(worksheet, ), **self.xa)
104- return SpreadsheetRow(table[0].getiterator(etree.QName(self.defaultns, 'Row')))
105+ return SpreadsheetRow(table[0].iter('{%s}Row' % self.defaultns))
106
107 def enc(self, s):
108 if isinstance(s, unicode):
109
110=== modified file 'bin/addons/sync_client/backup.py'
111--- bin/addons/sync_client/backup.py 2017-02-16 15:52:37 +0000
112+++ bin/addons/sync_client/backup.py 2017-02-21 15:07:51 +0000
113@@ -76,12 +76,12 @@
114 return 'UNKNOWN_VERSION'
115
116 def _set_pg_psw_env_var(self):
117- if tools.config['db_password'] and not os.environ.get('PGPASSWORD', ''):
118+ if os.name == 'nt' and not os.environ.get('PGPASSWORD', ''):
119 os.environ['PGPASSWORD'] = tools.config['db_password']
120 self._pg_psw_env_var_is_set = True
121
122 def _unset_pg_psw_env_var(self):
123- if self._pg_psw_env_var_is_set:
124+ if os.name == 'nt' and self._pg_psw_env_var_is_set:
125 os.environ['PGPASSWORD'] = ''
126
127 def exp_dump_for_state(self, cr, uid, state, context=None, force=False):
128
129=== modified file 'bin/tools/misc.py'
130--- bin/tools/misc.py 2017-02-17 15:44:19 +0000
131+++ bin/tools/misc.py 2017-02-21 15:07:51 +0000
132@@ -142,7 +142,7 @@
133 return None
134
135 def _set_env_pg(remove=False):
136- if config['db_password']:
137+ if os.name == 'nt':
138 if not remove and not os.environ.get('PGPASSWORD', ''):
139 os.environ['PGPASSWORD'] = config['db_password']
140 if remove and os.environ.get('PGPASSWORD'):
141
142=== modified file 'setup.py'
143--- setup.py 2017-02-16 15:52:37 +0000
144+++ setup.py 2017-02-21 15:07:51 +0000
145@@ -58,7 +58,7 @@
146 "packages": [
147 "lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
148 "lxml.objectify", "decimal", "xml", "xml", "xml.dom",
149- "encodings", "dateutil", "wizard", "PIL", "pyparsing",
150+ "encodings", "dateutil", "wizard", "pychart", "PIL", "pyparsing",
151 "pydot", "asyncore","asynchat", "reportlab", "vobject",
152 "HTMLParser", "select", "mako", "poplib",
153 "imaplib", "smtplib", "email", "yaml", "DAV",
154@@ -240,18 +240,18 @@
155 },
156 package_dir = find_package_dirs(),
157 install_requires = [
158- 'lxml==2.2.4',
159- 'mako==0.2.5',
160- 'python-dateutil==2.5.3',
161- 'psycopg2==2.0.13',
162- 'pydot==1.0.2',
163- 'pytz==2010b0',
164- 'reportlab==2.4',
165- 'pyyaml==3.12',
166- 'egenix-mx-base==3.2.9',
167- 'passlib==1.6.5',
168- 'bcrypt==3.1.1',
169- 'xlwt==1.1.2',
170+ 'lxml',
171+ 'mako',
172+ 'python-dateutil',
173+ 'psycopg2',
174+ 'pychart',
175+ 'pydot',
176+ 'pytz',
177+ 'reportlab',
178+ 'caldav',
179+ 'pyyaml',
180+ 'pywebdav',
181+ 'feedparser',
182 ],
183 extras_require={
184 'SSL' : ['pyopenssl'],
185
186=== modified file 'setup_py2exe_custom.py'
187--- setup_py2exe_custom.py 2017-02-16 15:52:37 +0000
188+++ setup_py2exe_custom.py 2017-02-21 15:07:51 +0000
189@@ -24,25 +24,7 @@
190
191 import os
192 import tempfile
193-import sys
194-
195-if sys.platform == 'nt':
196- from py2exe.build_exe import py2exe as build_exe, fancy_split
197-else:
198- # fake it for non-Windows, so that setup.py can be run for
199- # installing dependencies.
200- class _be(dict):
201- def __init__(self, arg1,arg2,arg3):
202- pass
203- def __dir__(self):
204- return tuple(self)
205- def __getattribute__(self, name):
206- if name == 'user_options':
207- return []
208- else:
209- raise AttributeError(name)
210- build_exe = _be(1, 2, 3)
211- fancy_split = None
212+from py2exe.build_exe import py2exe as build_exe, fancy_split
213
214 def fixup_data_pytz_zoneinfo():
215 r = {}
216@@ -54,8 +36,8 @@
217 return r.items()
218
219 def byte_compile_noop(py_files, optimize=0, force=0,
220- target_dir=None, verbose=1, dry_run=0,
221- direct=None):
222+ target_dir=None, verbose=1, dry_run=0,
223+ direct=None):
224
225 compiled_files = []
226 from distutils.dir_util import mkpath
227@@ -177,11 +159,11 @@
228 # Run fake compilation - just copy raw .py file into their
229 # destination directory
230 self.no_compiled_files = byte_compile_noop(py_files,
231- target_dir=self.collect_dir,
232- optimize=self.optimize,
233- force=0,
234- verbose=self.verbose,
235- dry_run=self.dry_run)
236+ target_dir=self.collect_dir,
237+ optimize=self.optimize,
238+ force=0,
239+ verbose=self.verbose,
240+ dry_run=self.dry_run)
241
242 # Force relocate of specific packages data within collected libs dir
243 def fixup_location(l):

Subscribers

People subscribed via source and target branches