diff --git a/tests/test_document.py b/tests/test_document.py new file mode 100644 index 00000000..cf74c719 --- /dev/null +++ b/tests/test_document.py @@ -0,0 +1,73 @@ +from __future__ import unicode_literals + +import io +import tempfile + +from nose import tools + +from PyPDF2 import PdfFileReader + +from xhtml2pdf.document import pisaDocument + + +HTML_CONTENT = """ + +
+ + ++ The quick red fox jumps over the lazy brown dog. +
+ + +""" + + +METADATA = { + "author": "MyCorp Ltd.", + "title": "My Document Title", + "subject": "My Document Subject", + "keywords": "pdf, documents", +} + + +def _compare_pdf_metadata(pdf_file, assertion): + + # Ensure something has been written + tools.assert_not_equal(pdf_file.tell(), 0) + + # Rewind to the start of the file to read the pdf and get the + # docuemnt's metadata + pdf_file.seek(0) + pdf_reader = PdfFileReader(pdf_file) + pdf_info = pdf_reader.documentInfo + + # Check the received metadata matches the expected metadata + for original_key in METADATA: + actual_key = "/{}".format(original_key.capitalize()) + actual_value = pdf_info[actual_key] + expected_value = METADATA[original_key] + + assertion(actual_value, expected_value) + + +def test_document_creation_without_metadata(): + with tempfile.TemporaryFile() as pdf_file: + pisaDocument( + src=io.StringIO(HTML_CONTENT), + dest=pdf_file + ) + _compare_pdf_metadata(pdf_file, tools.assert_not_equal) + + +def test_document_creation_with_metadata(): + with tempfile.TemporaryFile() as pdf_file: + pisaDocument( + src=io.StringIO(HTML_CONTENT), + dest=pdf_file, + context_meta=METADATA + ) + _compare_pdf_metadata(pdf_file, tools.assert_equal) diff --git a/tox.ini b/tox.ini index ebbce407..75b2ec43 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,7 @@ envlist = [testenv] commands = {envpython} -c "from reportlab import Version; print('%s %s' % ('Reportlab Version', Version))" - nosetests --with-xunit --with-coverage --cover-package=xhtml2pdf + {envpython} -m nose.core --with-xunit --with-coverage --cover-package=xhtml2pdf deps = Pillow>=2.0 coverage diff --git a/xhtml2pdf/document.py b/xhtml2pdf/document.py index 38397cb9..61687cf8 100644 --- a/xhtml2pdf/document.py +++ b/xhtml2pdf/document.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import io + from xhtml2pdf.context import pisaContext from xhtml2pdf.default import DEFAULT_CSS from xhtml2pdf.parser import pisaParser @@ -72,16 +74,22 @@ def pisaStory(src, path=None, link_callback=None, debug=0, default_css=None, def pisaDocument(src, dest=None, path=None, link_callback=None, debug=0, default_css=None, xhtml=False, encoding=None, xml_output=None, - raise_exception=True, capacity=100 * 1024, **kw): - log.debug("pisaDocument options:\n src = %r\n dest = %r\n path = %r\n link_callback = %r\n xhtml = %r", + raise_exception=True, capacity=100 * 1024, context_meta=None, + **kw): + log.debug("pisaDocument options:\n src = %r\n dest = %r\n path = %r\n link_callback = %r\n xhtml = %r\n context_meta = %r", src, dest, path, link_callback, - xhtml) + xhtml, + context_meta) # Prepare simple context context = pisaContext(path, debug=debug, capacity=capacity) + + if context_meta is not None: + context.meta.update(context_meta) + context.pathCallback = link_callback # Build story @@ -89,7 +97,7 @@ def pisaDocument(src, dest=None, path=None, link_callback=None, debug=0, encoding, context=context, xml_output=xml_output) # Buffer PDF into memory - out = pisaTempFile(capacity=context.capacity) + out = io.BytesIO() doc = PmlBaseDoc( out, @@ -165,10 +173,14 @@ def pisaDocument(src, dest=None, path=None, link_callback=None, debug=0, if dest is None: # No output file was passed - Let's use a pisaTempFile - dest = pisaTempFile(capacity=context.capacity) + dest = io.BytesIO() context.dest = dest - data = out.getvalue() # TODO: That load all the tempfile in RAM - Why bother with a swapping tempfile then? + data = out.getvalue() + + if isinstance(dest, io.BytesIO): + data = data.encode("utf-8") + context.dest.write(data) # TODO: context.dest is a tempfile as well... return context