From 67791ff194e98cfbb95f81d556cf73e2bf42b33b Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Thu, 26 Dec 2019 14:41:33 +0530 Subject: [PATCH] fix(pdf): error when trying to print PDFs --- frappe/utils/pdf.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/frappe/utils/pdf.py b/frappe/utils/pdf.py index b631406a8e..c69dc430cf 100644 --- a/frappe/utils/pdf.py +++ b/frappe/utils/pdf.py @@ -2,14 +2,24 @@ # MIT License. See license.txt from __future__ import unicode_literals -import pdfkit, os, frappe +import io +import os +import re from distutils.version import LooseVersion -from frappe.utils import scrub_urls, get_wkhtmltopdf_version -from frappe import _ -import six, re, io + +import pdfkit +import six from bs4 import BeautifulSoup from PyPDF2 import PdfFileReader, PdfFileWriter +import frappe +from frappe import _ +from frappe.utils import get_wkhtmltopdf_version, scrub_urls + +PDF_CONTENT_ERRORS = ["ContentNotFoundError", "ContentOperationNotPermittedError", + "UnknownContentError", "RemoteHostClosedError"] + + def get_pdf(html, options=None, output=None): html = scrub_urls(html) html, options = prepare_options(html, options) @@ -30,20 +40,14 @@ def get_pdf(html, options=None, output=None): # https://pythonhosted.org/PyPDF2/PdfFileReader.html # create in-memory binary streams from filedata and create a PdfFileReader object reader = PdfFileReader(io.BytesIO(filedata)) - - except IOError as e: - if ("ContentNotFoundError" in e.message - or "ContentOperationNotPermittedError" in e.message - or "UnknownContentError" in e.message - or "RemoteHostClosedError" in e.message): + except OSError as e: + if any([error in str(e) for error in PDF_CONTENT_ERRORS]): + if not filedata: + frappe.throw(_("PDF generation failed because of broken image links")) # allow pdfs with missing images if file got created - if filedata: - if output: # output is a PdfFileWriter object - output.appendPagesFromReader(reader) - - else: - frappe.throw(_("PDF generation failed because of broken image links")) + if output: # output is a PdfFileWriter object + output.appendPagesFromReader(reader) else: raise @@ -66,6 +70,7 @@ def get_pdf(html, options=None, output=None): return filedata + def get_file_data_from_writer(writer_obj): # https://docs.python.org/3/library/io.html @@ -112,6 +117,7 @@ def prepare_options(html, options): return html, options + def read_options_from_html(html): options = {} soup = BeautifulSoup(html, "html5lib") @@ -132,6 +138,7 @@ def read_options_from_html(html): return soup.prettify(), options + def prepare_header_footer(soup): options = {} @@ -174,6 +181,7 @@ def prepare_header_footer(soup): return options + def cleanup(fname, options): if os.path.exists(fname): os.remove(fname) @@ -182,6 +190,7 @@ def cleanup(fname, options): if options.get(key) and os.path.exists(options[key]): os.remove(options[key]) + def toggle_visible_pdf(soup): for tag in soup.find_all(attrs={"class": "visible-pdf"}): # remove visible-pdf class to unhide