Merge lp:~camptocamp/account-financial-report/7.0-sync-afr_webkit-with-report_webkit into lp:~account-report-core-editor/account-financial-report/7.0
- 7.0-sync-afr_webkit-with-report_webkit
- Merge into 7.0
Status: | Merged |
---|---|
Merged at revision: | 92 |
Proposed branch: | lp:~camptocamp/account-financial-report/7.0-sync-afr_webkit-with-report_webkit |
Merge into: | lp:~account-report-core-editor/account-financial-report/7.0 |
Diff against target: |
226 lines (+52/-44) 1 file modified
account_financial_report_webkit/report/webkit_parser_header_fix.py (+52/-44) |
To merge this branch: | bzr merge lp:~camptocamp/account-financial-report/7.0-sync-afr_webkit-with-report_webkit |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stéphane Bidoul (Acsone) (community) | Approve | ||
Guewen Baconnier @ Camptocamp | tested | Approve | |
Pedro Manuel Baeza | code review | Approve | |
Nicolas Bessi - Camptocamp (community) | Approve | ||
Review via email: mp+223058@code.launchpad.net |
Commit message
Description of the change
Adapt account_
https:/
https:/
Plus few improvement following pep8 to remove useless variable and import
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote : | # |
Pedro Manuel Baeza (pedro.baeza) wrote : | # |
LGTM.
Regards.
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Thanks
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
Hi,
Is it just me or this MP broke afr with ocb 7.0?
Traceback (most recent call last):
File "/home/
**parser_
File "/home/
return runtime.
File "/home/
**_kwargs_
File "/home/
_exec_template(
File "/home/
callable_(context, *args, **kwargs)
File "memory:0x5184dd0", line 22, in render_body
<%
TypeError: translate_call() takes exactly 2 arguments (3 given)
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
reverting to rev 91 works
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
I'm using rev 5343 of ocb-server/7.0, which the latest on launchpad
Not sure what's going on. Unfortunately I can't dig deeper right now.
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
On 06/17/2014 09:29 PM, Stéphane Bidoul (Acsone) wrote:
> Review: Needs Fixing test
>
> Hi,
>
> Is it just me or this MP broke afr with ocb 7.0?
>
> Traceback (most recent call last):
> File "/home/
> **parser_
> File "/home/
> return runtime.
> File "/home/
> **_kwargs_
> File "/home/
> _exec_template(
> File "/home/
> callable_(context, *args, **kwargs)
> File "memory:0x5184dd0", line 22, in render_body
> <%
> TypeError: translate_call() takes exactly 2 arguments (3 given)
>
>
It is necessary to be compatible with this change:
https:/
That has been merged in official branches.
I didn't noticed that it was not working in ocb because in my local OCB
branch (which is a bit out of date), the patch was there:
revno: 10194 [merge]
author: <email address hidden>
committer: Leonardo Pistone <email address hidden>
branch nick: 7.0-ocb
timestamp: Wed 2014-05-21 10:58:28 +0200
message:
Transmit parser_instance using partial function for mako translation
callback.
This to remove parser_instance from attribute as it can cause race
condition
on cursors.
But it is no longer there when I look in the current ocb-addons tree.
I guess we should propose the MP again on OCB
--
Guewen Baconnier
Business Solutions Software Developer
Camptocamp SA
PSE A, CH-1015 Lausanne
Phone: +41 21 619 10 39
Office: +41 21 619 10 10
http://
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
This has been fixed by Pedro, some revision were overwritten last week and are now back in OCB.
Thanks for noticing it Stéphane
Stéphane Bidoul (Acsone) (sbi) wrote : | # |
Tested again with ocb-addons/7.0 HEAD.
Situation is recovered. Thanks!
Preview Diff
1 | === modified file 'account_financial_report_webkit/report/webkit_parser_header_fix.py' | |||
2 | --- account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-03-18 14:55:32 +0000 | |||
3 | +++ account_financial_report_webkit/report/webkit_parser_header_fix.py 2014-06-13 12:07:01 +0000 | |||
4 | @@ -30,8 +30,8 @@ | |||
5 | 30 | import os | 30 | import os |
6 | 31 | import subprocess | 31 | import subprocess |
7 | 32 | import tempfile | 32 | import tempfile |
8 | 33 | import time | ||
9 | 34 | import logging | 33 | import logging |
10 | 34 | from functools import partial | ||
11 | 35 | 35 | ||
12 | 36 | 36 | ||
13 | 37 | from mako import exceptions | 37 | from mako import exceptions |
14 | @@ -48,11 +48,12 @@ | |||
15 | 48 | # Class used only as a workaround to bug: | 48 | # Class used only as a workaround to bug: |
16 | 49 | # http://code.google.com/p/wkhtmltopdf/issues/detail?id=656 | 49 | # http://code.google.com/p/wkhtmltopdf/issues/detail?id=656 |
17 | 50 | 50 | ||
20 | 51 | # html headers and footers do not work on big files (hundreds of pages) so we replace them by | 51 | # html headers and footers do not work on big files (hundreds of pages) so we |
21 | 52 | # text headers and footers passed as arguments to wkhtmltopdf | 52 | # replace them by text headers and footers passed as arguments to wkhtmltopdf |
22 | 53 | # this class has to be removed once the bug is fixed | 53 | # this class has to be removed once the bug is fixed |
23 | 54 | 54 | ||
25 | 55 | # in your report class, to print headers and footers as text, you have to add them in the localcontext with a key 'additional_args' | 55 | # in your report class, to print headers and footers as text, you have to add |
26 | 56 | # them in the localcontext with a key 'additional_args' | ||
27 | 56 | # for instance: | 57 | # for instance: |
28 | 57 | # header_report_name = _('PARTNER LEDGER') | 58 | # header_report_name = _('PARTNER LEDGER') |
29 | 58 | # footer_date_time = self.formatLang(str(datetime.today()), date_time=True) | 59 | # footer_date_time = self.formatLang(str(datetime.today()), date_time=True) |
30 | @@ -75,23 +76,25 @@ | |||
31 | 75 | from mako.template import Template | 76 | from mako.template import Template |
32 | 76 | from mako.lookup import TemplateLookup | 77 | from mako.lookup import TemplateLookup |
33 | 77 | 78 | ||
34 | 79 | |||
35 | 78 | def mako_template(text): | 80 | def mako_template(text): |
36 | 79 | """Build a Mako template. | 81 | """Build a Mako template. |
37 | 80 | 82 | ||
38 | 81 | This template uses UTF-8 encoding | 83 | This template uses UTF-8 encoding |
39 | 82 | """ | 84 | """ |
41 | 83 | tmp_lookup = TemplateLookup() #we need it in order to allow inclusion and inheritance | 85 | tmp_lookup = TemplateLookup() # we need it in order to allow inclusion and inheritance |
42 | 84 | return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup) | 86 | return Template(text, input_encoding='utf-8', output_encoding='utf-8', lookup=tmp_lookup) |
43 | 85 | 87 | ||
44 | 86 | 88 | ||
45 | 87 | class HeaderFooterTextWebKitParser(webkit_report.WebKitParser): | 89 | class HeaderFooterTextWebKitParser(webkit_report.WebKitParser): |
46 | 88 | 90 | ||
48 | 89 | def generate_pdf(self, comm_path, report_xml, header, footer, html_list, webkit_header=False): | 91 | def generate_pdf(self, comm_path, report_xml, header, footer, html_list, |
49 | 92 | webkit_header=False, parser_instance=False): | ||
50 | 90 | """Call webkit in order to generate pdf""" | 93 | """Call webkit in order to generate pdf""" |
51 | 91 | if not webkit_header: | 94 | if not webkit_header: |
52 | 92 | webkit_header = report_xml.webkit_header | 95 | webkit_header = report_xml.webkit_header |
55 | 93 | tmp_dir = tempfile.gettempdir() | 96 | fd, out_filename = tempfile.mkstemp(suffix=".pdf", |
56 | 94 | out_filename = tempfile.mktemp(suffix=".pdf", prefix="webkit.tmp.") | 97 | prefix="webkit.tmp.") |
57 | 95 | file_to_del = [out_filename] | 98 | file_to_del = [out_filename] |
58 | 96 | if comm_path: | 99 | if comm_path: |
59 | 97 | command = [comm_path] | 100 | command = [comm_path] |
60 | @@ -115,16 +118,16 @@ | |||
61 | 115 | if webkit_header.format: | 118 | if webkit_header.format: |
62 | 116 | command.extend(['--page-size', str(webkit_header.format).replace(',', '.')]) | 119 | command.extend(['--page-size', str(webkit_header.format).replace(',', '.')]) |
63 | 117 | 120 | ||
66 | 118 | if self.parser_instance.localcontext.get('additional_args', False): | 121 | if parser_instance.localcontext.get('additional_args', False): |
67 | 119 | for arg in self.parser_instance.localcontext['additional_args']: | 122 | for arg in parser_instance.localcontext['additional_args']: |
68 | 120 | command.extend(arg) | 123 | command.extend(arg) |
69 | 121 | 124 | ||
70 | 122 | count = 0 | 125 | count = 0 |
71 | 123 | for html in html_list: | 126 | for html in html_list: |
76 | 124 | html_file = file(os.path.join(tmp_dir, str(time.time()) + str(count) +'.body.html'), 'w') | 127 | with tempfile.NamedTemporaryFile(suffix="%d.body.html" % count, |
77 | 125 | count += 1 | 128 | delete=False) as html_file: |
78 | 126 | html_file.write(html) | 129 | count += 1 |
79 | 127 | html_file.close() | 130 | html_file.write(self._sanitize_html(html)) |
80 | 128 | file_to_del.append(html_file.name) | 131 | file_to_del.append(html_file.name) |
81 | 129 | command.append(html_file.name) | 132 | command.append(html_file.name) |
82 | 130 | command.append(out_filename) | 133 | command.append(out_filename) |
83 | @@ -132,8 +135,8 @@ | |||
84 | 132 | file_to_del.append(stderr_path) | 135 | file_to_del.append(stderr_path) |
85 | 133 | try: | 136 | try: |
86 | 134 | status = subprocess.call(command, stderr=stderr_fd) | 137 | status = subprocess.call(command, stderr=stderr_fd) |
89 | 135 | os.close(stderr_fd) # ensure flush before reading | 138 | os.close(stderr_fd) # ensure flush before reading |
90 | 136 | stderr_fd = None # avoid closing again in finally block | 139 | stderr_fd = None # avoid closing again in finally block |
91 | 137 | fobj = open(stderr_path, 'r') | 140 | fobj = open(stderr_path, 'r') |
92 | 138 | error_message = fobj.read() | 141 | error_message = fobj.read() |
93 | 139 | fobj.close() | 142 | fobj.close() |
94 | @@ -142,11 +145,11 @@ | |||
95 | 142 | else: | 145 | else: |
96 | 143 | error_message = _('The following diagnosis message was provided:\n') + error_message | 146 | error_message = _('The following diagnosis message was provided:\n') + error_message |
97 | 144 | if status: | 147 | if status: |
99 | 145 | raise except_osv(_('Webkit error' ), | 148 | raise except_osv(_('Webkit error'), |
100 | 146 | _("The command 'wkhtmltopdf' failed with error code = %s. Message: %s") % (status, error_message)) | 149 | _("The command 'wkhtmltopdf' failed with error code = %s. Message: %s") % (status, error_message)) |
104 | 147 | pdf_file = open(out_filename, 'rb') | 150 | with open(out_filename, 'rb') as pdf_file: |
105 | 148 | pdf = pdf_file.read() | 151 | pdf = pdf_file.read() |
106 | 149 | pdf_file.close() | 152 | os.close(fd) |
107 | 150 | finally: | 153 | finally: |
108 | 151 | if stderr_fd is not None: | 154 | if stderr_fd is not None: |
109 | 152 | os.close(stderr_fd) | 155 | os.close(stderr_fd) |
110 | @@ -160,57 +163,60 @@ | |||
111 | 160 | # override needed to keep the attachments' storing procedure | 163 | # override needed to keep the attachments' storing procedure |
112 | 161 | def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None): | 164 | def create_single_pdf(self, cursor, uid, ids, data, report_xml, context=None): |
113 | 162 | """generate the PDF""" | 165 | """generate the PDF""" |
114 | 166 | |||
115 | 163 | if context is None: | 167 | if context is None: |
117 | 164 | context={} | 168 | context = {} |
118 | 165 | htmls = [] | 169 | htmls = [] |
119 | 166 | if report_xml.report_type != 'webkit': | 170 | if report_xml.report_type != 'webkit': |
121 | 167 | return super(HeaderFooterTextWebKitParser,self).create_single_pdf(cursor, uid, ids, data, report_xml, context=context) | 171 | return super(HeaderFooterTextWebKitParser, self |
122 | 172 | ).create_single_pdf(cursor, uid, ids, data, | ||
123 | 173 | report_xml, context=context) | ||
124 | 168 | 174 | ||
129 | 169 | self.parser_instance = self.parser(cursor, | 175 | parser_instance = self.parser(cursor, |
130 | 170 | uid, | 176 | uid, |
131 | 171 | self.name2, | 177 | self.name2, |
132 | 172 | context=context) | 178 | context=context) |
133 | 173 | 179 | ||
134 | 174 | self.pool = pooler.get_pool(cursor.dbname) | 180 | self.pool = pooler.get_pool(cursor.dbname) |
135 | 175 | objs = self.getObjects(cursor, uid, ids, context) | 181 | objs = self.getObjects(cursor, uid, ids, context) |
137 | 176 | self.parser_instance.set_context(objs, data, ids, report_xml.report_type) | 182 | parser_instance.set_context(objs, data, ids, report_xml.report_type) |
138 | 177 | 183 | ||
140 | 178 | template = False | 184 | template = False |
141 | 179 | 185 | ||
142 | 180 | if report_xml.report_file: | 186 | if report_xml.report_file: |
143 | 181 | path = addons.get_module_resource(*report_xml.report_file.split(os.path.sep)) | 187 | path = addons.get_module_resource(*report_xml.report_file.split(os.path.sep)) |
144 | 182 | if os.path.exists(path): | 188 | if os.path.exists(path): |
145 | 183 | template = file(path).read() | 189 | template = file(path).read() |
146 | 184 | if not template and report_xml.report_webkit_data: | 190 | if not template and report_xml.report_webkit_data: |
148 | 185 | template = report_xml.report_webkit_data | 191 | template = report_xml.report_webkit_data |
149 | 186 | if not template: | 192 | if not template: |
150 | 187 | raise except_osv(_('Error!'), _('Webkit Report template not found !')) | 193 | raise except_osv(_('Error!'), _('Webkit Report template not found !')) |
151 | 188 | header = report_xml.webkit_header.html | 194 | header = report_xml.webkit_header.html |
153 | 189 | footer = report_xml.webkit_header.footer_html | 195 | |
154 | 190 | if not header and report_xml.header: | 196 | if not header and report_xml.header: |
155 | 191 | raise except_osv( | 197 | raise except_osv( |
156 | 192 | _('No header defined for this Webkit report!'), | 198 | _('No header defined for this Webkit report!'), |
158 | 193 | _('Please set a header in company settings') | 199 | _('Please set a header in company settings.') |
159 | 194 | ) | 200 | ) |
160 | 195 | 201 | ||
161 | 196 | css = report_xml.webkit_header.css | 202 | css = report_xml.webkit_header.css |
162 | 197 | if not css: | 203 | if not css: |
163 | 198 | css = '' | 204 | css = '' |
164 | 199 | user = self.pool.get('res.users').browse(cursor, uid, uid) | ||
165 | 200 | 205 | ||
166 | 206 | translate_call = partial(self.translate_call, parser_instance) | ||
167 | 201 | #default_filters=['unicode', 'entity'] can be used to set global filter | 207 | #default_filters=['unicode', 'entity'] can be used to set global filter |
168 | 202 | body_mako_tpl = mako_template(template) | 208 | body_mako_tpl = mako_template(template) |
169 | 203 | helper = WebKitHelper(cursor, uid, report_xml.id, context) | 209 | helper = WebKitHelper(cursor, uid, report_xml.id, context) |
170 | 204 | if report_xml.precise_mode: | 210 | if report_xml.precise_mode: |
171 | 205 | for obj in objs: | 211 | for obj in objs: |
173 | 206 | self.parser_instance.localcontext['objects'] = [obj] | 212 | parser_instance.localcontext['objects'] = [obj] |
174 | 207 | try: | 213 | try: |
175 | 208 | html = body_mako_tpl.render(helper=helper, | 214 | html = body_mako_tpl.render(helper=helper, |
176 | 209 | css=css, | 215 | css=css, |
179 | 210 | _=self.translate_call, | 216 | _=translate_call, |
180 | 211 | **self.parser_instance.localcontext) | 217 | **parser_instance.localcontext) |
181 | 212 | htmls.append(html) | 218 | htmls.append(html) |
183 | 213 | except Exception, e: | 219 | except Exception: |
184 | 214 | msg = exceptions.text_error_template().render() | 220 | msg = exceptions.text_error_template().render() |
185 | 215 | _logger.error(msg) | 221 | _logger.error(msg) |
186 | 216 | raise except_osv(_('Webkit render'), msg) | 222 | raise except_osv(_('Webkit render'), msg) |
187 | @@ -218,15 +224,16 @@ | |||
188 | 218 | try: | 224 | try: |
189 | 219 | html = body_mako_tpl.render(helper=helper, | 225 | html = body_mako_tpl.render(helper=helper, |
190 | 220 | css=css, | 226 | css=css, |
193 | 221 | _=self.translate_call, | 227 | _=translate_call, |
194 | 222 | **self.parser_instance.localcontext) | 228 | **parser_instance.localcontext) |
195 | 223 | htmls.append(html) | 229 | htmls.append(html) |
197 | 224 | except Exception, e: | 230 | except Exception: |
198 | 225 | msg = exceptions.text_error_template().render() | 231 | msg = exceptions.text_error_template().render() |
199 | 226 | _logger.error(msg) | 232 | _logger.error(msg) |
200 | 227 | raise except_osv(_('Webkit render'), msg) | 233 | raise except_osv(_('Webkit render'), msg) |
201 | 228 | 234 | ||
203 | 229 | # NO html footer and header because we write them as text with wkhtmltopdf | 235 | # NO html footer and header because we write them as text with |
204 | 236 | # wkhtmltopdf | ||
205 | 230 | head = foot = False | 237 | head = foot = False |
206 | 231 | 238 | ||
207 | 232 | if report_xml.webkit_debug: | 239 | if report_xml.webkit_debug: |
208 | @@ -234,13 +241,14 @@ | |||
209 | 234 | deb = body_mako_tpl.render(helper=helper, | 241 | deb = body_mako_tpl.render(helper=helper, |
210 | 235 | css=css, | 242 | css=css, |
211 | 236 | _debug=tools.ustr("\n".join(htmls)), | 243 | _debug=tools.ustr("\n".join(htmls)), |
215 | 237 | _=self.translate_call, | 244 | _=translate_call, |
216 | 238 | **self.parser_instance.localcontext) | 245 | **parser_instance.localcontext) |
217 | 239 | except Exception, e: | 246 | except Exception: |
218 | 240 | msg = exceptions.text_error_template().render() | 247 | msg = exceptions.text_error_template().render() |
219 | 241 | _logger.error(msg) | 248 | _logger.error(msg) |
220 | 242 | raise except_osv(_('Webkit render'), msg) | 249 | raise except_osv(_('Webkit render'), msg) |
221 | 243 | return (deb, 'html') | 250 | return (deb, 'html') |
222 | 244 | bin = self.get_lib(cursor, uid) | 251 | bin = self.get_lib(cursor, uid) |
224 | 245 | pdf = self.generate_pdf(bin, report_xml, head, foot, htmls) | 252 | pdf = self.generate_pdf(bin, report_xml, head, foot, htmls, |
225 | 253 | parser_instance=parser_instance) | ||
226 | 246 | return (pdf, 'pdf') | 254 | return (pdf, 'pdf') |
LGTM, taking in account that previous comment on source MP are still valid.