From e458be4a14173a74960ffc2efaa99ec78307b8fe Mon Sep 17 00:00:00 2001
From: DEEP SILVER ACCESSORY <fordeep@hotmail.com>
Date: Tue, 16 Sep 2014 17:25:48 +0200
Subject: [PATCH] [FIX] Report: compatibility issues on Windows

This commit fixes two different issues specific to Windows:
* NamedTemporaryFile behavior, requiring a file to be closed before being
  accessed a second time
* Wkhtmltopdf crash when the document's dpi is inferor to 96
---
 addons/report/models/report.py | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 38492e09f0cb..c9b4490d34f7 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'])])
-- 
GitLab