PDF from external method
Hi, how can I pass a pdf generated by an external method (using Reportlab) back to Zope? Has anybody done this with Reportlab before? I am new to Python, Zope and Reportlab and I wanted to try one of those demo scripts coming with the Reportlab Installation. I think it is a Python problem, what do I have to do in the Python script to return the PDF file handle? -- Juergen Plasser plasser@hexagon.at
On 24 Oct 2001 at 15:14, Juergen R. Plasser / HEXAGON wrote:
how can I pass a pdf generated by an external method (using Reportlab) back to Zope?
Easy, our external method just gets the output from reportlab in a string like object, then writes the data to RESPONSE. def externalmethod(self,REQUEST,RESPONSE, ... other stuff): <snip> report = BufferedBillingReport(orgid=orgid,startDate=start,endDate=end,showActualAmount=showActualAmount,invoiceNumber=invoiceNumber,trackURL=trackURL,mode=mode,carrier=carrier,vendorinvoice=vendorinvoice) data = report.getFileData() siz = len(data) RESPONSE.setHeader("Content-Type","application/pdf") RESPONSE.setHeader("Content-Length",siz) RESPONSE.write(data) (some stolen code) class buffer: def __init__(self): self._buffer = [] self._size = 0 def write(self,line): self._buffer.append(str(line)) def read(self): return string.join(self._buffer,'') def tell(self): return len(self._buffer) class BufferedBillingReport: """billing report that writes to a buffer and returns the buffer object""" def __init__(self,**kw): """Initialize it""" self.buffer = buffer() self.report = apply(BillingReport,(GetDB(),self.buffer,),kw) self.report.generateReport() def getFileData(self): """Return the contents of the buffer""" return self.buffer.read() class BillingReport(PDFLayouter): """Generate a PDF billing report for specified Org""" <snip> Brad Clements, bkc@murkworks.com (315)268-1000 http://www.murkworks.com (315)268-9812 Fax netmeeting: ils://ils.murkworks.com AOL-IM: BKClements
--On Mittwoch, 24. Oktober 2001 13:21 -0400 Brad Clements <bkc@murkworks.com> wrote:
Easy, our external method just gets the output from reportlab in a string like object, then writes the data to RESPONSE.
def externalmethod(self,REQUEST,RESPONSE, ... other stuff): <snip>
How do I define this external method in Zope, or how can I call the external method with the 3 parameters? (sorry newbie). When I declare an external method like this: Id test Title Testmethod Module testmodule Function externalmethod(self,REQUEST,RESPONSE) I receive the following error: Error Type: TypeError Error Value: externalmethod() takes exactly 3 arguments (0 given) Is there any good summary where I can get some more info about external methods? Juergen
Is there any good summary where I can get some more info about external methods?
Read about "Using External Methods" http://www.zope.org/Members/michel/ZB/ScriptingZope.dtml in the Zope Book. /Magnus
Ok, sorry, this was a python script error. Another question: Reportlab examples create files, how can I "RESPONSE" them to Zope? Juergen
Juergen R. Plasser / HEXAGON wrote:
Ok, sorry, this was a python script error.
Another question: Reportlab examples create files, how can I "RESPONSE" them to Zope?
What I am using: pdffile.seek(0) self.REQUEST.RESPONSE.setHeader("Content-type","application/pdf") self.REQUEST.RESPONSE.write(pdffile.read()) -- Jim Washington
On Thu, Oct 25, 2001 at 09:23:59AM -0400, Jim Washington wrote:
Juergen R. Plasser / HEXAGON wrote:
Ok, sorry, this was a python script error.
Another question: Reportlab examples create files, how can I "RESPONSE" them to Zope?
What I am using:
pdffile.seek(0) self.REQUEST.RESPONSE.setHeader("Content-type","application/pdf") self.REQUEST.RESPONSE.write(pdffile.read())
-- Jim Washington
This is very nice. Yet another way is to simply build a HTML file pointing to the .pdf file generated. I.e. def build_pdf(...): ... # omitted code builds pdf file in variable pdf_filename # referenced as pdf_url return "<a href="%s">%s</a>" % (pdf_url, pdf_filename) Advantages: Allows .pdf to be served by static webserver Disadvantages: Requires extra click to get to pdf. Requires a policy to reap stale pdf's Neutral: Caching generated pdf's may (or may not) be a big win. It depends on the nature of your task. I suspect, psychobabblically speaking, that caching will occur more naturally to people who are treating pdf's as semi-static content by delivering a file name, than to those who purely consider a pdf to be something to be delivered as a result of a method invocation. Note: The disadvantages may not be as large as you think. Many people are disconcerted by long load-times and/or sudden pop-up windows. This splits download/viewer startup time away from data gathering/pdf generation time and will typically be perceived as more responsive; despite stop watch time showing that it is far slower due to the necessity of the extra click. (That is, people are often happier with 2 events of duration t/2 than one event of duration t, especially if they have a chance to "walk away" in the middle.) Thus, for many people, the extra click may be perceived as an advantage! The policy for reaping pdf's is actually neutral. Note that Jim Washington's method left the pdf file on the hard disk somewhere. If you regard the external method as generating files rather than byte-streams, the need for a reaping process simply leaps out at you. Jim Penny
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
I've been running Zope (with ZEO) on a Debian GNU/Linux box. Just today everything slowed to a crawl and it turned out that one python process was taking up 75% of system memory. Stopping and restarting Zope cured the problem. I'm doing some caching of DTML pages and MySQL queries. Any idea why Zope would start doing this? Are there any preventative measures? Thanks, Chris
This (unfinished) HowTo describes some methods of diagnosing memory leaks. http://www.zope.org/Members/mcdonc/HowTos/PreventAndDebugMemLeaks ----- Original Message ----- From: "Chris Gray" <cpgray@library.uwaterloo.ca> To: <zope@zope.org> Sent: Thursday, October 25, 2001 11:41 AM Subject: [Zope] Zope Eats Memory
I've been running Zope (with ZEO) on a Debian GNU/Linux box. Just today everything slowed to a crawl and it turned out that one python process was taking up 75% of system memory. Stopping and restarting Zope cured the problem. I'm doing some caching of DTML pages and MySQL queries.
Any idea why Zope would start doing this? Are there any preventative measures?
Thanks, Chris
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
Jim Penny wrote:
On Thu, Oct 25, 2001 at 09:23:59AM -0400, Jim Washington wrote:
Juergen R. Plasser / HEXAGON wrote:
Ok, sorry, this was a python script error.
Another question: Reportlab examples create files, how can I "RESPONSE" them to Zope?
What I am using:
pdffile.seek(0) self.REQUEST.RESPONSE.setHeader("Content-type","application/pdf") self.REQUEST.RESPONSE.write(pdffile.read())
-- Jim Washington
This is very nice.
Yet another way is to simply build a HTML file pointing to the .pdf file generated.
I.e. def build_pdf(...): ... # omitted code builds pdf file in variable pdf_filename # referenced as pdf_url return "<a href="%s">%s</a>" % (pdf_url, pdf_filename)
Advantages: Allows .pdf to be served by static webserver Disadvantages: Requires extra click to get to pdf. Requires a policy to reap stale pdf's Neutral: Caching generated pdf's may (or may not) be a big win. It depends on the nature of your task. I suspect, psychobabblically speaking, that caching will occur more naturally to people who are treating pdf's as semi-static content by delivering a file name, than to those who purely consider a pdf to be something to be delivered as a result of a method invocation.
Note: The disadvantages may not be as large as you think. Many people are disconcerted by long load-times and/or sudden pop-up windows. This splits download/viewer startup time away from data gathering/pdf generation time and will typically be perceived as more responsive; despite stop watch time showing that it is far slower due to the necessity of the extra click. (That is, people are often happier with 2 events of duration t/2 than one event of duration t, especially if they have a chance to "walk away" in the middle.) Thus, for many people, the extra click may be perceived as an advantage!
The policy for reaping pdf's is actually neutral. Note that Jim Washington's method left the pdf file on the hard disk somewhere. If you regard the external method as generating files rather than byte-streams, the need for a reaping process simply leaps out at you.
Jim Penny
Thanks, Jim. I may use some of this. I am currently working on the user interface for a multitude of reports. A small caveat to the above. The PDF's I am generating are small, 150-200k, and not particularly high-traffic. I create the PDFs entirely in memory, so I do not need to reap: from cStringIO import StringIO pdffile = StringIO() doc = BaseDocTemplate(pdffile, pageTemplates=([coverTemplate,secondPageTemplate, mainTemplate,])) doclist = [] ...use platypus... doc.build(doclist) then write to RESPONSE as in my note above. -- Jim Washington
On Thu, Oct 25, 2001 at 01:55:47PM +0200, Juergen R. Plasser / HEXAGON wrote:
Ok, sorry, this was a python script error.
Another question: Reportlab examples create files, how can I "RESPONSE" them to Zope?
Juergen
One way that I do this is after the pdf file is created, I set up a function that opens and reads that file into a string and then return the string back to zope. You can then set up the MIME header of the zope object calling the reportlab script to be PDF which should open up the appropriate pdf viewer in your browser. <Function to read pdf. This is an external method or a python script.> def readPDF(pdf_file_name): BUFSIZE=2000 pdf='' f=open(pdf_file_name) d=f.read(BUFSIZE) while d: pdf=pdf+d d=f.read(BUFSIZE) return pdf </function> <DTML_SCRIPT to call readPDF function> Content-type: application/pdf <dtml-var expr="readPDF(pdf_file_name)"> </DTML_SCRIPT> HTH Chris
participants (8)
-
Brad Clements -
Chris Gray -
Chris McDonough -
Chris Meyers -
Jim Penny -
Jim Washington -
Juergen R. Plasser / HEXAGON -
Magnus Heino