mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-19 14:32:16 +00:00
Added printing requirements
This commit is contained in:
149
z3c/rml/pdfinclude.py
Normal file
149
z3c/rml/pdfinclude.py
Normal file
@@ -0,0 +1,149 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2012 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
"""``pdfInclude`` Directive.
|
||||
"""
|
||||
__docformat__ = "reStructuredText"
|
||||
import cStringIO
|
||||
try:
|
||||
import PyPDF2
|
||||
from PyPDF2.generic import NameObject
|
||||
except ImportError:
|
||||
PyPDF2 = None
|
||||
from reportlab.platypus import flowables
|
||||
|
||||
from z3c.rml import attr, flowable, interfaces, occurence, page
|
||||
|
||||
class ConcatenationPostProcessor(object):
|
||||
|
||||
def __init__(self):
|
||||
self.operations = []
|
||||
|
||||
def process(self, inputFile1):
|
||||
input1 = PyPDF2.PdfFileReader(inputFile1)
|
||||
merger = PyPDF2.PdfFileMerger()
|
||||
merger.output._info.getObject().update(input1.documentInfo)
|
||||
|
||||
prev_insert = 0
|
||||
for start_page, inputFile2, pages, num_pages in self.operations:
|
||||
if prev_insert < start_page:
|
||||
merger.append(inputFile1, pages=(prev_insert, start_page))
|
||||
if not pages:
|
||||
merger.append(inputFile2)
|
||||
else:
|
||||
# Note, users start counting at 1. ;-)
|
||||
for page in pages:
|
||||
merger.append(inputFile2, pages=(page-1, page))
|
||||
prev_insert = start_page + num_pages
|
||||
|
||||
input1 = PyPDF2.PdfFileReader(inputFile1)
|
||||
num_pages = input1.getNumPages()
|
||||
if prev_insert < num_pages:
|
||||
merger.append(
|
||||
inputFile1, pages=(prev_insert, num_pages))
|
||||
|
||||
outputFile = cStringIO.StringIO()
|
||||
merger.write(outputFile)
|
||||
return outputFile
|
||||
|
||||
|
||||
class PDFPageFlowable(flowables.Flowable):
|
||||
|
||||
def __init__(self, width, height):
|
||||
flowables.Flowable.__init__(self)
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
def split(self, availWidth, availheight):
|
||||
return [self]
|
||||
|
||||
|
||||
class IncludePdfPagesFlowable(flowables.Flowable):
|
||||
|
||||
def __init__(self, pdf_file, pages, concatprocessor):
|
||||
flowables.Flowable.__init__(self)
|
||||
self.pdf_file = pdf_file
|
||||
self.proc = concatprocessor
|
||||
self.pages = pages
|
||||
|
||||
self.width = 10<<32
|
||||
self.height = 10<<32
|
||||
|
||||
def draw():
|
||||
return NotImplementedError('PDFPages shall be drawn not me')
|
||||
|
||||
def split(self, availWidth, availheight):
|
||||
pages = self.pages
|
||||
if not pages:
|
||||
pdf = PyPDF2.PdfFileReader(self.pdf_file)
|
||||
num_pages = pdf.getNumPages()
|
||||
pages = range(num_pages)
|
||||
else:
|
||||
num_pages = len(pages)
|
||||
|
||||
start_page = self.canv.getPageNumber()
|
||||
self.proc.operations.append(
|
||||
(start_page, self.pdf_file, self.pages, num_pages))
|
||||
|
||||
result = []
|
||||
for i in pages:
|
||||
result.append(flowables.PageBreak())
|
||||
result.append(PDFPageFlowable(availWidth, availheight))
|
||||
return result
|
||||
|
||||
|
||||
class IIncludePdfPages(interfaces.IRMLDirectiveSignature):
|
||||
"""Inserts a set of pages from a given PDF."""
|
||||
|
||||
filename = attr.File(
|
||||
title=u'Path to file',
|
||||
description=u'The pdf file to include.',
|
||||
required=True)
|
||||
|
||||
pages = attr.IntegerSequence(
|
||||
title=u'Pages',
|
||||
description=u'A list of pages to insert.',
|
||||
required=False)
|
||||
|
||||
|
||||
class IncludePdfPages(flowable.Flowable):
|
||||
signature = IIncludePdfPages
|
||||
|
||||
def getProcessor(self):
|
||||
manager = attr.getManager(self, interfaces.IPostProcessorManager)
|
||||
procs = dict(manager.postProcessors)
|
||||
if 'CONCAT' not in procs:
|
||||
proc = ConcatenationPostProcessor()
|
||||
manager.postProcessors.append(('CONCAT', proc))
|
||||
return proc
|
||||
return procs['CONCAT']
|
||||
|
||||
def process(self):
|
||||
if PyPDF2 is None:
|
||||
raise Exception(
|
||||
'PyPDF2 is not installed, so this feature is not available.')
|
||||
args = dict(self.getAttributeValues())
|
||||
proc = self.getProcessor()
|
||||
self.parent.flow.append(
|
||||
IncludePdfPagesFlowable(args['filename'], args.get('pages'), proc))
|
||||
|
||||
|
||||
flowable.Flow.factories['includePdfPages'] = IncludePdfPages
|
||||
flowable.IFlow.setTaggedValue(
|
||||
'directives',
|
||||
flowable.IFlow.getTaggedValue('directives') +
|
||||
(occurence.ZeroOrMore('includePdfPages', IIncludePdfPages),)
|
||||
)
|
||||
Reference in New Issue
Block a user