def test_add_cell_styles_will_not_add_lineafter_style_if_borderright_color_not_set_on_context_frag(self): context = pisaContext([]) context.frag.borderRightStyle = "solid" context.frag.borderRightWidth = "3px" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0][0], 'LINEAFTER')
def test_td_rowspan(self): """ Test rowspan on <td> tag; If it works, rowspan="3" will be equal to (0, 2) in _spanCmds of the ReportLab table """ html = """ <html> <head> <style> </style> </head> <body> <table> <tr> <td rowspan="3">AAAAAAAAAAAA</td> <td>BBB</td> </tr> <tr> <td>CCC</td> </tr> <tr> <td>DDD</td> </tr> </table> </body> </html> """ context = pisaParser(BytesIO(html.encode('utf-8')), pisaContext(None)) table = context.story[0] row_span = table._spanCmds[0][2] self.assertEqual(row_span, (0, 2), '"rowspan=" not working properly in the <td> tag!')
def test_add_cell_styles_will_add_all_line_styles_if_all_border_attrs_set_on_context_frag( self): context = pisaContext([]) context.frag.borderTopStyle = "solid" context.frag.borderTopWidth = "3px" context.frag.borderTopColor = "black" context.frag.borderLeftStyle = "solid" context.frag.borderLeftWidth = "3px" context.frag.borderLeftColor = "black" context.frag.borderRightStyle = "solid" context.frag.borderRightWidth = "3px" context.frag.borderRightColor = "black" context.frag.borderBottomStyle = "solid" context.frag.borderBottomWidth = "3px" context.frag.borderBottomColor = "black" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertEqual(instance.styles[0], ('LINEABOVE', (0, 1), (3, 1), '3px', 'black', 'squared')) self.assertEqual(instance.styles[1], ('LINEBEFORE', (0, 1), (0, 5), '3px', 'black', 'squared')) self.assertEqual(instance.styles[2], ('LINEAFTER', (3, 1), (3, 5), '3px', 'black', 'squared')) self.assertEqual(instance.styles[3], ('LINEBELOW', (0, 5), (3, 5), '3px', 'black', 'squared'))
def test_add_cell_styles_will_not_add_linebefore_style_if_borderleft_width_not_set_on_context_frag(self): context = pisaContext([]) context.frag.borderLeftStyle = "solid" context.frag.borderLeftWidth = "3px" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0][0], 'LINEBEFORE')
def test_add_cell_styles_will_not_add_lineabove_style_if_bordertop_style_not_set_on_context_frag(self): context = pisaContext([]) context.frag.borderTopWidth = "3px" context.frag.borderTopColor = "black" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0][0], 'LINEABOVE')
def test_add_cell_styles_will_not_add_linebelow_style_if_borderbottom_color_not_set_on_context_frag(self): context = pisaContext([]) context.frag.borderBottomStyle = "solid" context.frag.borderBottomWidth = "3px" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0][0], 'LINEBELOW')
def test_add_cell_styles_will_not_add_lineabove_style_if_bordertop_color_not_set_on_context_frag( self): context = pisaContext([]) context.frag.borderTopStyle = "solid" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0][0], 'LINEABOVE')
def parseHTML(data, node): path = None link_callback = None debug = 0 default_css = HTML_CSS xhtml = False encoding = None xml_output = None capacity = 100 * 1024 # Prepare simple context context = pisaContext(path, debug=debug, capacity=capacity) context.pathCallback = link_callback # Build story context = pisaStory( data, path, link_callback, debug, default_css, xhtml, encoding, context=context, xml_output=xml_output, ) return context.story
def pisaStory(src, path=None, link_callback=None, debug=0, default_css=None, xhtml=False, encoding=None, context=None, xml_output=None, **kw): # Prepare Context if not context: context = pisaContext(path, debug=debug) context.pathCallback = link_callback # Use a default set of CSS definitions to get an expected output if default_css is None: default_css = DEFAULT_CSS # Parse and fill the story pisaParser(src, context, default_css, xhtml, encoding, xml_output) # Avoid empty documents if not context.story: context.story = [Spacer(1,1)] if context.indexing_story: context.story.append(context.indexing_story) # Remove anchors if they do not exist (because of a bug in Reportlab) for frag, anchor in context.anchorFrag: if anchor not in context.anchorName: frag.link = None return context
def pisaStory(src, path=None, link_callback=None, debug=0, default_css=None, xhtml=False, encoding=None, context=None, xml_output=None, **kw): # Prepare Context if not context: context = pisaContext(path, debug=debug) context.pathCallback = link_callback # Use a default set of CSS definitions to get an expected output if default_css is None: default_css = DEFAULT_CSS # Parse and fill the story pisaParser(src, context, default_css, xhtml, encoding, xml_output) # Avoid empty documents if not context.story: context.story = [Spacer(1, 1)] if context.indexing_story: context.story.append(context.indexing_story) # Remove anchors if they do not exist (because of a bug in Reportlab) for frag, anchor in context.anchorFrag: if anchor not in context.anchorName: frag.link = None return context
def test_tr_background_color(self): """ Test background on <tr> tag; If it works, "darkgreen" will be returned as hexval "0x006400" """ html = """ <html> <head> <style> tr { background-color: darkgreen } </style> </head> <body> <table> <tr> <td>Test</td> </tr> </table> </body> </html> """ context = pisaParser(BytesIO(html.encode('utf-8')), pisaContext(None)) table = context.story[0] color = table._bkgrndcmds[0][3] self.assertEqual(color.hexval(), '0x006400', '"background-color" in CSS not equal with output!')
def test_add_cell_styles_will_add_linebelow_style_if_borderbottom_attrs_set_on_context_frag(self): context = pisaContext([]) context.frag.borderBottomStyle = "solid" context.frag.borderBottomWidth = "3px" context.frag.borderBottomColor = "black" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertEqual(instance.styles[0], ('LINEBELOW', (0, 5), (3, 5), '3px', 'black', 'squared'))
def test_add_cell_styles_will_add_lineafter_style_if_borderright_attrs_set_on_context_frag(self): context = pisaContext([]) context.frag.borderRightStyle = "solid" context.frag.borderRightWidth = "3px" context.frag.borderRightColor = "black" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertEqual(instance.styles[0], ('LINEAFTER', (3, 1), (3, 5), '3px', 'black', 'squared'))
def test_height_as_list(self): """Asserts attributes like 'height: 10px !important" are parsed""" c = pisaContext(".") data = b"<p style='height: 10px !important;width: 10px !important'>test</p>" r = pisaParser(data, c) self.assertEqual(c, r) self.assertEqual(r.err, 0) self.assertEqual(r.warn, 0)
def test_add_cell_styles_will_not_add_background_style_if_context_frag_has_backcolor_set_and_mode_is_tr( self): context = pisaContext([]) context.frag.backColor = "green" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0], ('BACKGROUND', (0, 1), (3, 5), 'green'))
def test_add_cell_styles_will_add_padding_styles_based_on_frag_padding_attrs(self): context = pisaContext([]) context.frag.paddingRight = 5 instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="td") self.assertEqual(instance.styles[0], ('LEFTPADDING', (0, 1), (3, 5), 0)) self.assertEqual(instance.styles[1], ('RIGHTPADDING', (0, 1), (3, 5), 5)) self.assertEqual(instance.styles[2], ('TOPPADDING', (0, 1), (3, 5), 0)) self.assertEqual(instance.styles[3], ('BOTTOMPADDING', (0, 1), (3, 5), 0))
def test_image_os_path(self): c = pisaContext(".") tests_folder = os.path.dirname(os.path.realpath(__file__)) img_path = os.path.join(tests_folder, 'samples', 'img', 'denker.png') data = '<img src="{0}">'.format(img_path).encode('utf-8') r = pisaParser(data, c) self.assertEqual(c, r) self.assertEqual(r.err, 0) self.assertEqual(r.warn, 0)
def test_start_will_add_borders_if_border_and_border_color_set_in_attrs(self): self.attrs.border = 2 self.attrs.bordercolor = "green" tag = tables.pisaTagTABLE(self.element, self.attrs) context = pisaContext([]) tag.start(context) self.assertEqual(context.frag.borderLeftWidth, 2) self.assertEqual(context.frag.borderRightWidth, 2) self.assertEqual(context.frag.borderTopWidth, 2) self.assertEqual(context.frag.borderBottomWidth, 2) self.assertEqual(context.frag.borderLeftColor, "green") self.assertEqual(context.frag.borderRightColor, "green") self.assertEqual(context.frag.borderTopColor, "green") self.assertEqual(context.frag.borderBottomColor, "green") self.assertEqual(context.frag.borderLeftStyle, "solid") self.assertEqual(context.frag.borderRightStyle, "solid") self.assertEqual(context.frag.borderTopStyle, "solid") self.assertEqual(context.frag.borderBottomStyle, "solid")
def parseHTML(data, node): path = None link_callback = None debug = 0 default_css = HTML_CSS xhtml = False encoding = None xml_output = None capacity = 100 * 1024 # Prepare simple context context = pisaContext(path, debug=debug, capacity=capacity) context.pathCallback = link_callback # Build story context = pisaStory( data, path, link_callback, debug, default_css, xhtml, encoding, context=context, xml_output=xml_output ) return context.story
def test_will_set_attrs_on_tabledata(self): self.attrs.cellpadding = 4 self.attrs.align = "left" self.attrs.repeat = True self.attrs.width = 100 tag = tables.pisaTagTABLE(self.element, self.attrs) context = pisaContext([]) tag.start(context) self.assertEqual(context.tableData.padding, 4) self.assertEqual(context.tableData.styles[0], ('LEFTPADDING', (0, 0), (-1, -1), 4)) self.assertEqual(context.tableData.styles[1], ('RIGHTPADDING', (0, 0), (-1, -1), 4)) self.assertEqual(context.tableData.styles[2], ('TOPPADDING', (0, 0), (-1, -1), 4)) self.assertEqual(context.tableData.styles[3], ('BOTTOMPADDING', (0, 0), (-1, -1), 4)) self.assertEqual(context.tableData.align, "LEFT") self.assertEqual(context.tableData.col, 0) self.assertEqual(context.tableData.row, 0) self.assertEqual(context.tableData.colw, []) self.assertEqual(context.tableData.rowh, []) self.assertEqual(context.tableData.repeat, True) self.assertEqual(context.tableData.width, 100.0)
def test_add_cell_styles_will_add_all_line_styles_if_all_border_attrs_set_on_context_frag(self): context = pisaContext([]) context.frag.borderTopStyle = "solid" context.frag.borderTopWidth = "3px" context.frag.borderTopColor = "black" context.frag.borderLeftStyle = "solid" context.frag.borderLeftWidth = "3px" context.frag.borderLeftColor = "black" context.frag.borderRightStyle = "solid" context.frag.borderRightWidth = "3px" context.frag.borderRightColor = "black" context.frag.borderBottomStyle = "solid" context.frag.borderBottomWidth = "3px" context.frag.borderBottomColor = "black" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertEqual(instance.styles[0], ('LINEABOVE', (0, 1), (3, 1), '3px', 'black', 'squared')) self.assertEqual(instance.styles[1], ('LINEBEFORE', (0, 1), (0, 5), '3px', 'black', 'squared')) self.assertEqual(instance.styles[2], ('LINEAFTER', (3, 1), (3, 5), '3px', 'black', 'squared')) self.assertEqual(instance.styles[3], ('LINEBELOW', (0, 5), (3, 5), '3px', 'black', 'squared'))
def test_empty_table(self): """ Test, if an empty table will return an empty story; This will also raise a log.warning() """ html = """ <html> <head> </head> <body> <table> </table> </body> </html> """ context = pisaParser(BytesIO(html.encode('utf-8')), pisaContext(None)) self.assertEqual(context.story, [], "Empty table doesn't return an empty story!")
def pisaStory( src, path = None, link_callback = None, debug = 0, default_css = None, xhtml = False, encoding = None, c = None, xml_output = None, **kw): # Prepare Context if not c: c = pisaContext(path, debug=debug) c.pathCallback = link_callback # Use a default set of CSS definitions to get an expected output if default_css is None: default_css = DEFAULT_CSS # Parse and fill the story pisaParser(src, c, default_css, xhtml, encoding, xml_output) #if 0: # import reportlab.pdfbase.pdfmetrics as pm # pm.dumpFontData() # Avoid empty documents if not c.story: c.story = [Spacer(1,1)] # c.addPara(force=True) # Remove anchors if they do not exist (because of a bug in Reportlab) for frag, anchor in c.anchorFrag: if anchor not in c.anchorName: frag.link = None return c
def test_td_width_and_height(self): """ Test width and height on <td> tag; If it works, width: 2pt will be equal to 2.0 and height: 3pt will be equal to 3.0 in the ReportLab table """ html = """ <html> <head> <style> td { width: 2pt; height: 3pt } </style> </head> <body> <table> <tr> <td>AAA</td> <td>BBB</td> </tr> <tr> <td>CCC</td> <td>DDD</td> </tr> </table> </body> </html> """ context = pisaParser(BytesIO(html.encode('utf-8')), pisaContext(None)) table = context.story[0] col_widths = table._colWidths row_heights = table._rowHeights for width in col_widths: self.assertEqual(width, 2.0, '<td> width in CSS not equal with output!') for height in row_heights: self.assertEqual(height, 3.0, '<td> height in CSS not equal with output!')
def test_td_tag_doesnt_collapse_when_empty(self): dom = minidom.parseString("<td></td>") element = dom.getElementsByTagName("td")[0] attrs = AttrContainer({ 'align': None, 'colspan': None, 'rowspan': None, 'width': None, 'valign': None, }) context = pisaContext([]) table_data = tables.TableData() table_data.col = 0 table_data.row = 0 table_data.colw = [] table_data.rowh = [] context.tableData = table_data context.frag.paddingLeft = 0 context.frag.paddingRight = 0 instance = tables.pisaTagTD(element, attrs) instance.start(context) self.assertEqual(context.tableData.colw, [None])
def testParser(self): c = pisaContext(".") r = pisaParser(_data, c) self.assertEqual(c, r)
def test_getFile(self): c = pisaContext(".") r = pisaParser(_data, c) self.assertEqual(c.getFile(None), None)
def test_image_base64(self): c = pisaContext(".") data = b'<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=">' r = pisaParser(data, c) self.assertEqual(r.warn, 0)
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", src, dest, path, link_callback, xhtml) # Prepare simple context context = pisaContext(path, debug=debug, capacity=capacity) context.pathCallback = link_callback # Build story context = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding, context=context, xml_output=xml_output) # Buffer PDF into memory out = pisaTempFile(capacity=context.capacity) doc = PmlBaseDoc(out, pagesize=context.pageSize, author=context.meta["author"].strip(), subject=context.meta["subject"].strip(), keywords=[ x.strip() for x in context.meta["keywords"].strip().split(",") if x ], title=context.meta["title"].strip(), showBoundary=0, allowSplitting=1) # Prepare templates and their frames if "body" in context.templateList: body = context.templateList["body"] del context.templateList["body"] else: x, y, w, h = getBox("1cm 1cm -1cm -1cm", context.pageSize) body = PmlPageTemplate(id="body", frames=[ Frame(x, y, w, h, id="body", leftPadding=0, rightPadding=0, bottomPadding=0, topPadding=0) ], pagesize=context.pageSize) doc.addPageTemplates([body] + context.templateList.values()) # Use multibuild e.g. if a TOC has to be created if context.multiBuild: doc.multiBuild(context.story) else: doc.build(context.story) # Add watermarks if pyPdf: for bgouter in context.pisaBackgroundList: # If we have at least one background, then lets do it if bgouter: istream = out output = pyPdf.PdfFileWriter() input1 = pyPdf.PdfFileReader(istream) ctr = 0 # TODO: Why do we loop over the same list again? # see bgouter at line 137 for bg in context.pisaBackgroundList: page = input1.getPage(ctr) if (bg and not bg.notFound() and (bg.mimetype == "application/pdf")): bginput = pyPdf.PdfFileReader(bg.getFile()) pagebg = bginput.getPage(0) pagebg.mergePage(page) page = pagebg else: log.warn( context.warning("Background PDF %s doesn't exist.", bg)) output.addPage(page) ctr += 1 out = pisaTempFile(capacity=context.capacity) output.write(out) # data = sout.getvalue() # Found a background? So leave loop after first occurence break else: log.warn(context.warning("pyPDF not installed!")) # Get the resulting PDF and write it to the file object # passed from the caller if dest is None: # No output file was passed - Let's use a pisaTempFile dest = pisaTempFile(capacity=context.capacity) context.dest = dest data = out.getvalue( ) # TODO: That load all the tempfile in RAM - Why bother with a swapping tempfile then? context.dest.write(data) # TODO: context.dest is a tempfile as well... return context
def pisaDocument( src, dest = None, path = None, link_callback = None, debug = 0, show_error_as_pdf = False, default_css = None, xhtml = False, encoding = None, xml_output = None, raise_exception = True, capacity = 100 * 1024, # -1, **kw): c = None if show_error_as_pdf: raise_exception = False try: log.debug("pisaDocument options:\n src = %r\n dest = %r\n path = %r\n link_callback = %r\n xhtml = %r", src, dest, path, link_callback, xhtml) # Prepare simple context c = pisaContext(path, debug=debug, capacity=capacity) c.pathCallback = link_callback if dest is None: dest = pisaTempFile(capacity=c.capacity) c.dest = dest # Build story c = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding, c=c, xml_output=xml_output) # Buffer PDF into memory out = pisaTempFile(capacity=c.capacity) doc = PmlBaseDoc( out, pagesize = c.pageSize, author = c.meta["author"].strip(), subject = c.meta["subject"].strip(), keywords = [x.strip() for x in c.meta["keywords"].strip().split(",") if x], title = c.meta["title"].strip(), showBoundary = 0, allowSplitting = 1) # XXX It is not possible to access PDF info, because it is private in canvas # doc.info.producer = "pisa <http://www.holtwick.it>" # Prepare templates and their frames if c.templateList.has_key("body"): body = c.templateList["body"] del c.templateList["body"] else: x, y, w, h = getBox("1cm 1cm -1cm -1cm", c.pageSize) body = PmlPageTemplate( id="body", frames=[ Frame(x, y, w, h, id = "body", leftPadding = 0, rightPadding = 0, bottomPadding = 0, topPadding = 0)], pagesize = c.pageSize) # print body.frames # print [body] + c.templateList.values() doc.addPageTemplates([body] + c.templateList.values()) doc._pisa_page_counter = 0 def _page_counter(page_no): doc._pisa_page_counter += 1 doc.setPageCallBack(_page_counter) # Use multibuild e.g. if a TOC has to be created if c.multiBuild: doc.multiBuild(c.story) else: doc.build(c.story) c._pisa_page_counter = doc._pisa_page_counter # Add watermarks if pyPdf: for bgouter in c.pisaBackgroundList: # If we have at least one background, then lets do it if bgouter: istream = out try: output = pyPdf.PdfFileWriter() input1 = pyPdf.PdfFileReader(istream) ctr = 0 for bg in c.pisaBackgroundList: page = input1.getPage(ctr) if bg and not bg.notFound() and (bg.mimetype=="application/pdf"): bginput = pyPdf.PdfFileReader(bg.getFile()) pagebg = bginput.getPage(0) pagebg.mergePage(page) page = pagebg else: log.warn(c.warning("Background PDF %s doesn't exist.", bg)) output.addPage(page) ctr += 1 out = pisaTempFile(capacity=c.capacity) output.write(out) # data = sout.getvalue() except Exception: log.exception(c.error("pyPDF error")) if raise_exception: raise # Found a background? So leave loop after first occurence break else: log.warn(c.warning("pyPDF not installed!")) # In web frameworks for debugging purposes maybe an output of # errors in a PDF is preferred if show_error_as_pdf and c and c.err: return pisaErrorDocument(c.dest, c) # Get the resulting PDF and write it to the file object # passed from the caller data = out.getvalue() c.dest.write(data) c.dest.close() except: # TODO: Kill catch-all! # log.exception(c.error("Document error")) log.exception("Document error") c.err += 1 if raise_exception: raise if raise_exception and c.err: raise Exception("Errors occured, please see log files for more informations") return c
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", src, dest, path, link_callback, xhtml) # Prepare simple context context = pisaContext(path, debug=debug, capacity=capacity) context.pathCallback = link_callback # Build story context = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding, context=context, xml_output=xml_output) # Buffer PDF into memory out = pisaTempFile(capacity=context.capacity) doc = PmlBaseDoc( out, pagesize=context.pageSize, author=context.meta["author"].strip(), subject=context.meta["subject"].strip(), keywords=[x.strip() for x in context.meta["keywords"].strip().split(",") if x], title=context.meta["title"].strip(), showBoundary=0, allowSplitting=1) # Prepare templates and their frames if "body" in context.templateList: body = context.templateList["body"] del context.templateList["body"] else: x, y, w, h = getBox("1cm 1cm -1cm -1cm", context.pageSize) body = PmlPageTemplate( id="body", frames=[ Frame(x, y, w, h, id="body", leftPadding=0, rightPadding=0, bottomPadding=0, topPadding=0)], pagesize = context.pageSize) doc.addPageTemplates([body] + context.templateList.values()) # Use multibuild e.g. if a TOC has to be created if context.multiBuild: doc.multiBuild(context.story) else: doc.build(context.story) # Add watermarks if pyPdf: for bgouter in context.pisaBackgroundList: # If we have at least one background, then lets do it if bgouter: istream = out output = pyPdf.PdfFileWriter() input1 = pyPdf.PdfFileReader(istream) ctr = 0 # TODO: Why do we loop over the same list again? # see bgouter at line 137 for bg in context.pisaBackgroundList: page = input1.getPage(ctr) if (bg and not bg.notFound() and (bg.mimetype=="application/pdf")): bginput = pyPdf.PdfFileReader(bg.getFile()) pagebg = bginput.getPage(0) pagebg.mergePage(page) page = pagebg else: log.warn(context.warning( "Background PDF %s doesn't exist.", bg)) output.addPage(page) ctr += 1 out = pisaTempFile(capacity=context.capacity) output.write(out) # data = sout.getvalue() # Found a background? So leave loop after first occurence break else: log.warn(context.warning("pyPDF not installed!")) # Get the resulting PDF and write it to the file object # passed from the caller if dest is None: # No output file was passed - Let's use a pisaTempFile dest = pisaTempFile(capacity=context.capacity) context.dest = dest data = out.getvalue() # TODO: That load all the tempfile in RAM - Why bother with a swapping tempfile then? context.dest.write(data) # TODO: context.dest is a tempfile as well... return context
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, 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, 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 context = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding, context=context, xml_output=xml_output) # Buffer PDF into memory out = io.BytesIO() doc = PmlBaseDoc(out, pagesize=context.pageSize, author=context.meta["author"].strip(), subject=context.meta["subject"].strip(), keywords=[ x.strip() for x in context.meta["keywords"].strip().split(",") if x ], title=context.meta["title"].strip(), showBoundary=0, allowSplitting=1) # Prepare templates and their frames multi_template_list = False if "body" in context.templateList: body = context.templateList["body"] del context.templateList["body"] else: x, y, w, h = getBox("1cm 1cm -1cm -1cm", context.pageSize) body = PmlPageTemplate(id="body", frames=[ Frame(x, y, w, h, id="body", leftPadding=0, rightPadding=0, bottomPadding=0, topPadding=0) ], pagesize=context.pageSize) ptl = build_grid_templates(doc, context) if ptl == []: doc.addPageTemplates([body] + list(context.templateList.values())) if ptl != []: if out_grid == []: doc.addPageTemplates(ptl) else: doc.addPageTemplates([body] + ptl) # Use multibuild e.g. if a TOC has to be created if context.multiBuild: doc.multiBuild(context.story) else: doc.build(context.story) # Add watermarks if PyPDF2: file_handler = None for bgouter in context.pisaBackgroundList: # If we have at least one background, then lets do it if bgouter: istream = out output = PyPDF2.PdfFileWriter() input1 = PyPDF2.PdfFileReader(istream) ctr = 0 # TODO: Why do we loop over the same list again? # see bgouter at line 137 for bg in context.pisaBackgroundList: page = input1.getPage(ctr) if (bg and not bg.notFound() and (bg.mimetype == "application/pdf")): file_handler = open(bg.uri, 'rb') bginput = PyPDF2.PdfFileReader(file_handler) pagebg = bginput.getPage(0) pagebg.mergePage(page) page = pagebg # Todo: the else-statement doesn't make a lot of sense to me; it's just throwing warnings # on unittesting \tests. Probably we have to rewrite the whole "background-image" stuff # to deal with cases like: # Page1 .jpg background # Page1 .pdf background # Page1 .jpg background, Page2 no background # Page1 .pdf background, Page2 no background # Page1 .jpg background, Page2 .pdf background # Page1 .pdf background, Page2 .jpg background # etc. # Right now it's kind of confusing. (fbernhart) # else: # log.warning(context.warning( # "Background PDF %s doesn't exist.", bg)) output.addPage(page) ctr += 1 out = pisaTempFile(capacity=context.capacity) output.write(out) if file_handler: file_handler.close() # data = sout.getvalue() # Found a background? So leave loop after first occurence break else: log.warning(context.warning("PyPDF2 not installed!")) # Get the resulting PDF and write it to the file object # passed from the caller if dest is None: # No output file was passed - Let's use a pisaTempFile dest = io.BytesIO() context.dest = dest data = out.getvalue() context.dest.write(data) # TODO: context.dest is a tempfile as well... return context
def test_add_cell_styles_will_not_add_background_style_if_context_frag_has_backcolor_set_and_mode_is_tr(self): context = pisaContext([]) context.frag.backColor = "green" instance = self.sut() instance.add_cell_styles(context, (0, 1), (3, 5), mode="tr") self.assertNotEqual(instance.styles[0], ('BACKGROUND', (0, 1), (3, 5), 'green'))