Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d0b0c45

Browse files
author
Chris Glass
committed
Lots of refactoring. Removed two silent catches, exceptions are now *always*
raised. Catching logic *must* be left to wrappers / implementors
1 parent 152d1ec commit d0b0c45

File tree

1 file changed

+123
-173
lines changed

1 file changed

+123
-173
lines changed

xhtml2pdf/document.py

Lines changed: 123 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -39,190 +39,140 @@ def pisaErrorDocument(dest, c):
3939

4040
return pisaDocument(out.getvalue(), dest, raise_exception=False)
4141

42-
def pisaStory(
43-
src,
44-
path = None,
45-
link_callback = None,
46-
debug = 0,
47-
default_css = None,
48-
xhtml = False,
49-
encoding = None,
50-
c = None,
51-
xml_output = None,
52-
**kw):
42+
def pisaStory(src, path = None, link_callback = None, debug = 0, default_css = None,
43+
xhtml = False, encoding = None, context = None, xml_output = None,
44+
**kw):
5345

5446
# Prepare Context
55-
if not c:
56-
c = pisaContext(path, debug=debug)
57-
c.pathCallback = link_callback
47+
if not context:
48+
context = pisaContext(path, debug=debug)
49+
context.pathCallback = link_callback
5850

5951
# Use a default set of CSS definitions to get an expected output
6052
if default_css is None:
6153
default_css = DEFAULT_CSS
6254

6355
# Parse and fill the story
64-
pisaParser(src, c, default_css, xhtml, encoding, xml_output)
65-
66-
#if 0:
67-
# import reportlab.pdfbase.pdfmetrics as pm
68-
# pm.dumpFontData()
56+
pisaParser(src, context, default_css, xhtml, encoding, xml_output)
6957

7058
# Avoid empty documents
71-
if not c.story:
72-
c.story = [Spacer(1,1)]
73-
# c.addPara(force=True)
59+
if not context.story:
60+
context.story = [Spacer(1,1)]
7461

7562
# Remove anchors if they do not exist (because of a bug in Reportlab)
76-
for frag, anchor in c.anchorFrag:
77-
if anchor not in c.anchorName:
63+
for frag, anchor in context.anchorFrag:
64+
if anchor not in context.anchorName:
7865
frag.link = None
79-
80-
return c
81-
82-
def pisaDocument(
83-
src,
84-
dest = None,
85-
path = None,
86-
link_callback = None,
87-
debug = 0,
88-
show_error_as_pdf = False,
89-
default_css = None,
90-
xhtml = False,
91-
encoding = None,
92-
xml_output = None,
93-
raise_exception = True,
94-
capacity = 100 * 1024, # -1,
95-
**kw):
96-
97-
c = None
98-
if show_error_as_pdf:
99-
raise_exception = False
100-
101-
try:
102-
103-
log.debug("pisaDocument options:\n src = %r\n dest = %r\n path = %r\n link_callback = %r\n xhtml = %r",
104-
src,
105-
dest,
106-
path,
107-
link_callback,
108-
xhtml)
109-
110-
# Prepare simple context
111-
c = pisaContext(path, debug=debug, capacity=capacity)
112-
c.pathCallback = link_callback
113-
114-
if dest is None:
115-
dest = pisaTempFile(capacity=c.capacity)
116-
c.dest = dest
117-
118-
# Build story
119-
c = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding, c=c, xml_output=xml_output)
120-
121-
# Buffer PDF into memory
122-
out = pisaTempFile(capacity=c.capacity)
123-
124-
doc = PmlBaseDoc(
125-
out,
126-
pagesize = c.pageSize,
127-
author = c.meta["author"].strip(),
128-
subject = c.meta["subject"].strip(),
129-
keywords = [x.strip() for x in c.meta["keywords"].strip().split(",") if x],
130-
title = c.meta["title"].strip(),
131-
showBoundary = 0,
132-
allowSplitting = 1)
133-
134-
# XXX It is not possible to access PDF info, because it is private in canvas
135-
# doc.info.producer = "pisa <http://www.holtwick.it>"
136-
137-
# Prepare templates and their frames
138-
if c.templateList.has_key("body"):
139-
body = c.templateList["body"]
140-
del c.templateList["body"]
141-
else:
142-
x, y, w, h = getBox("1cm 1cm -1cm -1cm", c.pageSize)
143-
body = PmlPageTemplate(
144-
id="body",
145-
frames=[
146-
Frame(x, y, w, h,
147-
id = "body",
148-
leftPadding = 0,
149-
rightPadding = 0,
150-
bottomPadding = 0,
151-
topPadding = 0)],
152-
pagesize = c.pageSize)
153-
154-
# print body.frames
155-
156-
# print [body] + c.templateList.values()
157-
doc.addPageTemplates([body] + c.templateList.values())
158-
159-
doc._pisa_page_counter = 0
160-
def _page_counter(page_no):
161-
doc._pisa_page_counter += 1
162-
doc.setPageCallBack(_page_counter)
66+
return context
67+
68+
def pisaDocument(src, dest = None, path = None, link_callback = None, debug = 0,
69+
default_css = None, xhtml = False, encoding = None, xml_output = None,
70+
raise_exception = True, capacity = 100 * 1024, **kw):
71+
72+
log.debug("pisaDocument options:\n src = %r\n dest = %r\n path = %r\n link_callback = %r\n xhtml = %r",
73+
src,
74+
dest,
75+
path,
76+
link_callback,
77+
xhtml)
78+
79+
# Prepare simple context
80+
context = pisaContext(path, debug=debug, capacity=capacity)
81+
context.pathCallback = link_callback
82+
83+
# Build story
84+
context = pisaStory(src, path, link_callback, debug, default_css, xhtml, encoding,
85+
context=context, xml_output=xml_output)
86+
87+
# Buffer PDF into memory
88+
out = pisaTempFile(capacity=context.capacity)
89+
90+
doc = PmlBaseDoc(
91+
out,
92+
pagesize = context.pageSize,
93+
author = context.meta["author"].strip(),
94+
subject = context.meta["subject"].strip(),
95+
keywords = [x.strip() for x in context.meta["keywords"].strip().split(",") if x],
96+
title = context.meta["title"].strip(),
97+
showBoundary = 0,
98+
allowSplitting = 1)
99+
100+
# Prepare templates and their frames
101+
if context.templateList.has_key("body"):
102+
body = context.templateList["body"]
103+
del context.templateList["body"]
104+
else:
105+
x, y, w, h = getBox("1cm 1cm -1cm -1cm", context.pageSize)
106+
body = PmlPageTemplate(
107+
id="body",
108+
frames=[
109+
Frame(x, y, w, h,
110+
id = "body",
111+
leftPadding = 0,
112+
rightPadding = 0,
113+
bottomPadding = 0,
114+
topPadding = 0)],
115+
pagesize = context.pageSize)
116+
117+
doc.addPageTemplates([body] + context.templateList.values())
118+
119+
# handle counting pages properly (to allow "page X/Y" stuff)
120+
doc._pisa_page_counter = 0
121+
def _page_counter(page_no):
122+
doc._pisa_page_counter += 1
123+
124+
doc.setPageCallBack(_page_counter)
125+
126+
# Use multibuild e.g. if a TOC has to be created
127+
if context.multiBuild:
128+
doc.multiBuild(context.story)
129+
else:
130+
doc.build(context.story)
131+
132+
context._pisa_page_counter = doc._pisa_page_counter
133+
134+
# Add watermarks
135+
if pyPdf:
163136

164-
# Use multibuild e.g. if a TOC has to be created
165-
if c.multiBuild:
166-
doc.multiBuild(c.story)
167-
else:
168-
doc.build(c.story)
169-
170-
c._pisa_page_counter = doc._pisa_page_counter
171-
172-
# Add watermarks
173-
if pyPdf:
174-
for bgouter in c.pisaBackgroundList:
175-
176-
# If we have at least one background, then lets do it
177-
if bgouter:
178-
179-
istream = out
180-
try:
181-
output = pyPdf.PdfFileWriter()
182-
input1 = pyPdf.PdfFileReader(istream)
183-
ctr = 0
184-
for bg in c.pisaBackgroundList:
185-
page = input1.getPage(ctr)
186-
if bg and not bg.notFound() and (bg.mimetype=="application/pdf"):
187-
bginput = pyPdf.PdfFileReader(bg.getFile())
188-
pagebg = bginput.getPage(0)
189-
pagebg.mergePage(page)
190-
page = pagebg
191-
else:
192-
log.warn(c.warning("Background PDF %s doesn't exist.", bg))
193-
output.addPage(page)
194-
ctr += 1
195-
out = pisaTempFile(capacity=c.capacity)
196-
output.write(out)
197-
# data = sout.getvalue()
198-
except Exception:
199-
log.exception(c.error("pyPDF error"))
200-
if raise_exception:
201-
raise
202-
203-
204-
# Found a background? So leave loop after first occurence
205-
break
206-
else:
207-
log.warn(c.warning("pyPDF not installed!"))
208-
209-
# In web frameworks for debugging purposes maybe an output of
210-
# errors in a PDF is preferred
211-
if show_error_as_pdf and c and c.err:
212-
return pisaErrorDocument(c.dest, c)
213-
214-
# Get the resulting PDF and write it to the file object
215-
# passed from the caller
216-
data = out.getvalue()
217-
c.dest.write(data)
218-
except: # TODO: Kill catch-all!
219-
# log.exception(c.error("Document error"))
220-
log.exception("Document error")
221-
c.err += 1
222-
if raise_exception:
223-
raise
224-
225-
if raise_exception and c.err:
226-
raise Exception("Errors occured, please see log files for more informations")
227-
228-
return c
137+
for bgouter in context.pisaBackgroundList:
138+
139+
# If we have at least one background, then lets do it
140+
if bgouter:
141+
142+
istream = out
143+
144+
output = pyPdf.PdfFileWriter()
145+
input1 = pyPdf.PdfFileReader(istream)
146+
ctr = 0
147+
#TODO: Why do we loop over the same list again? see bgouter at line 137
148+
for bg in context.pisaBackgroundList:
149+
page = input1.getPage(ctr)
150+
if bg and not bg.notFound() and (bg.mimetype=="application/pdf"):
151+
bginput = pyPdf.PdfFileReader(bg.getFile())
152+
pagebg = bginput.getPage(0)
153+
pagebg.mergePage(page)
154+
page = pagebg
155+
else:
156+
log.warn(context.warning("Background PDF %s doesn't exist.", bg))
157+
output.addPage(page)
158+
ctr += 1
159+
out = pisaTempFile(capacity=context.capacity)
160+
output.write(out)
161+
# data = sout.getvalue()
162+
# Found a background? So leave loop after first occurence
163+
break
164+
else:
165+
log.warn(context.warning("pyPDF not installed!"))
166+
167+
# Get the resulting PDF and write it to the file object
168+
# passed from the caller
169+
170+
if dest is None:
171+
# No output file was passed - Let's use a pisaTempFile
172+
dest = pisaTempFile(capacity=context.capacity)
173+
context.dest = dest
174+
175+
data = out.getvalue() # TODO: That load all the tempfile in RAM - Why bother with a swapping tempfile then?
176+
context.dest.write(data) # TODO: context.dest is a tempfile as well...
177+
178+
return context

0 commit comments

Comments
 (0)