# HG changeset patch # User Paul Boddie # Date 1383322029 -3600 # Node ID 6ce8836f70752195591dbbec01a2a7192f923c36 # Parent 04eb43f3cd34d0dfaa3512a210492ac5723cb408 Added caching of PDF output by page revision and paper size. diff -r 04eb43f3cd34 -r 6ce8836f7075 actions/ExportPDF.py --- a/actions/ExportPDF.py Fri Nov 01 15:21:36 2013 +0100 +++ b/actions/ExportPDF.py Fri Nov 01 17:07:09 2013 +0100 @@ -6,7 +6,8 @@ @license: GNU GPL (v2 or later), see COPYING.txt for details. """ -from MoinMoin.action import ActionBase +from MoinMoin import caching +from MoinMoin.action import ActionBase, cache from MoinMoin.wikiutil import escape from MoinSupport import ActionSupport, escattr, getFormatterClass, formatText, get_send_headers from os.path import join @@ -147,18 +148,36 @@ _ = self._ form = self.get_form() + request = self.request paper_size = form.get("paper-size", [""])[0] if not paper_size in self._get_paper_sizes() or []: return 0, _("A paper size must be chosen.") + # See if the revision is cached. + + cache_key = cache.key(request, content="%s-%s" % (self.page.rev, paper_size)) + cache_entry = caching.CacheEntry(request, self.page, cache_key, scope="item") + + # Open any available cache entry and read it. + + if cache_entry.exists(): + cache_entry.open() + try: + self._write_pdf(cache_entry.read()) + return 1, None + finally: + cache_entry.close() + + # Otherwise, prepare the PDF. + if self.mode == "docbook": - return self._export_using_docbook(paper_size) + return self._export_using_docbook(paper_size, cache_entry) elif self.mode == "wkhtmltopdf": - return self._export_using_wkhtmltopdf(paper_size) + return self._export_using_wkhtmltopdf(paper_size, cache_entry) elif self.mode == "htmldoc": - return self._export_using_htmldoc(paper_size) + return self._export_using_htmldoc(paper_size, cache_entry) else: return 0, _("The action must be configured to use a particular PDF generation tool.") @@ -233,7 +252,7 @@ self._write_pdf(out) return 1, None - def _export_using_wkhtmltopdf(self, paper_size): + def _export_using_wkhtmltopdf(self, paper_size, cache_entry): """ Send the page HTML to the processor, indicating the given 'paper_size'. @@ -251,9 +270,9 @@ stdout=subprocess.PIPE, stderr=subprocess.PIPE) - return self._write_pdf_for_html(p, self._get_page_as_html()) + return self._write_pdf_for_html(p, self._get_page_as_html(), cache_entry) - def _export_using_htmldoc(self, paper_size): + def _export_using_htmldoc(self, paper_size, cache_entry): """ Send the page HTML to the processor, indicating the given 'paper_size'. @@ -272,9 +291,9 @@ stdout=subprocess.PIPE, stderr=subprocess.PIPE) - return self._write_pdf_for_html(p, self._get_page_as_html()) + return self._write_pdf_for_html(p, self._get_page_as_html(), cache_entry) - def _export_using_docbook(self, paper_size): + def _export_using_docbook(self, paper_size, cache_entry): """ Send the page DocBook XML to the processor, indicating the given @@ -320,10 +339,28 @@ if retcode != 0: return 0, err + self._write_to_cache(out, cache_entry) self._write_pdf(out) return 1, None + def _write_to_cache(self, out, cache_entry): + + "Write the output 'out' to the given 'cache_entry'." + + cache_entry.open(mode="w") + try: + try: + cache_entry.write(out) + finally: + cache_entry.close() + except IOError: + if cache_entry.exists(): + cache_entry.remove() + def _write_pdf(self, out): + + "Write the output 'out' to the request/response." + request = self.request send_headers = get_send_headers(request)