diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 38492e09f0cbbd183b779e3679a154a6a7a5d775..c9b4490d34f706988b1a666d90ae36b125c9348f 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -36,7 +36,9 @@ import cStringIO import subprocess from distutils.version import LooseVersion from functools import partial +from os import name as OsName from pyPdf import PdfFileWriter, PdfFileReader +from shutil import rmtree _logger = logging.getLogger(__name__) @@ -353,7 +355,7 @@ class Report(osv.Model): """ command = ['wkhtmltopdf'] command_args = [] - tmp_dir = tempfile.gettempdir() + tmp_dir = tempfile.mkdtemp(prefix='report.tmp.') # Passing the cookie to wkhtmltopdf in order to resolve internal links. try: @@ -381,9 +383,16 @@ class Report(osv.Model): # Execute WKhtmltopdf pdfdocuments = [] + + # Workaround the NamedTemporaryFile limitation on Windows, which requires the file to + # be closed before accessing it by its name. + delete_tempfile = True + if OsName == 'nt': + delete_tempfile = False + for index, reporthtml in enumerate(bodies): local_command_args = [] - pdfreport = tempfile.NamedTemporaryFile(suffix='.pdf', prefix='report.tmp.', mode='w+b') + pdfreport = tempfile.NamedTemporaryFile(delete=delete_tempfile, suffix='.pdf', prefix='report.tmp.', dir=tmp_dir, mode='w+b') # Directly load the document if we already have it if save_in_attachment and save_in_attachment['loaded_documents'].get(reporthtml[0]): @@ -394,18 +403,18 @@ class Report(osv.Model): # Wkhtmltopdf handles header/footer as separate pages. Create them if necessary. if headers: - head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.', dir=tmp_dir, mode='w+') + head_file = tempfile.NamedTemporaryFile(delete=delete_tempfile, suffix='.html', prefix='report.header.tmp.', dir=tmp_dir, mode='w+') head_file.write(headers[index]) head_file.seek(0) local_command_args.extend(['--header-html', head_file.name]) if footers: - foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.', dir=tmp_dir, mode='w+') + foot_file = tempfile.NamedTemporaryFile(delete=delete_tempfile, suffix='.html', prefix='report.footer.tmp.', dir=tmp_dir, mode='w+') foot_file.write(footers[index]) foot_file.seek(0) local_command_args.extend(['--footer-html', foot_file.name]) # Body stuff - content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.', dir=tmp_dir, mode='w+') + content_file = tempfile.NamedTemporaryFile(delete=delete_tempfile, suffix='.html', prefix='report.body.tmp.', dir=tmp_dir, mode='w+') content_file.write(reporthtml[1]) content_file.seek(0) @@ -437,6 +446,8 @@ class Report(osv.Model): pdfreport.seek(0) pdfdocuments.append(pdfreport) + content_file.close() + if headers: head_file.close() if footers: @@ -451,6 +462,8 @@ class Report(osv.Model): else: content = self._merge_pdf(pdfdocuments) + rmtree(tmp_dir) + return content def _get_report_from_name(self, cr, uid, report_name): @@ -486,7 +499,11 @@ class Report(osv.Model): if specific_paperformat_args and specific_paperformat_args.get('data-report-dpi'): command_args.extend(['--dpi', str(specific_paperformat_args['data-report-dpi'])]) elif paperformat.dpi: - command_args.extend(['--dpi', str(paperformat.dpi)]) + if OsName == 'nt' and int(paperformat.dpi) <= 95: + _logger.info("Generating PDF on Windows platform require DPI >= 96. Using 96 instead.") + command_args.extend(['--dpi', '96']) + else: + command_args.extend(['--dpi', str(paperformat.dpi)]) if specific_paperformat_args and specific_paperformat_args.get('data-report-header-spacing'): command_args.extend(['--header-spacing', str(specific_paperformat_args['data-report-header-spacing'])])