Merge lp:~fabien-morin/unifield-server/fm-us-2339-new into lp:unifield-server
- fm-us-2339-new
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+317788@code.launchpad.net |
Commit message
Description of the change
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
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): |