# HG changeset patch # User Sylvain Thénault # Date 1270726716 -7200 # Node ID e8235b2789fcdf30fb611dad713a459993b43594 # Parent 955ee1b2475664b773460a6d618f9481f39dc0a9 le patch move-pdf-export-to-cubes a été importé diff -r 955ee1b24756 -r e8235b2789fc __pkginfo__.py --- a/__pkginfo__.py Thu Apr 08 11:04:17 2010 +0200 +++ b/__pkginfo__.py Thu Apr 08 13:38:36 2010 +0200 @@ -46,8 +46,6 @@ 'PIL': '', # for captcha 'pycrypto': '', # for crypto extensions 'fyzz': '>= 0.1.0', # for sparql - 'pysixt': '>= 0.1.0', # XXX for pdf export - 'python-gettext': '>= 1.0', # XXX for pdf export 'vobject': '>= 0.6.0', # for ical view #'Products.FCKeditor':'', #'SimpleTAL':'>= 4.1.6', diff -r 955ee1b24756 -r e8235b2789fc debian/control --- a/debian/control Thu Apr 08 11:04:17 2010 +0200 +++ b/debian/control Thu Apr 08 13:38:36 2010 +0200 @@ -83,7 +83,7 @@ Architecture: all XB-Python-Version: ${python:Versions} Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), python-simplejson (>= 1.3) -Recommends: python-docutils, python-vobject, fckeditor, python-fyzz, python-pysixt, fop, python-imaging +Recommends: python-docutils, python-vobject, fckeditor, python-fyzz, python-imaging Description: web interface library for the CubicWeb framework CubicWeb is a semantic web application framework. . diff -r 955ee1b24756 -r e8235b2789fc ext/xhtml2fo.py --- a/ext/xhtml2fo.py Thu Apr 08 11:04:17 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -from xml.etree.ElementTree import QName -from pysixt.standard.xhtml_xslfo.transformer import XHTML2FOTransformer -from pysixt.utils.xslfo.standard import cm -from pysixt.utils.xslfo import SimplePageMaster -from pysixt.standard.xhtml_xslfo.default_styling import default_styles -from pysixt.standard.xhtml_xslfo import XHTML_NS - - -class ReportTransformer(XHTML2FOTransformer): - """ - Class transforming an XHTML input tree into a FO document - displaying reports (one report for each
- element in the input tree. - """ - - def __init__(self, section, - page_width=21.0, page_height=29.7, - margin_top=1.0, margin_bottom=1.0, - margin_left=1.0, margin_right=1.0, - header_footer_height=0.75, - standard_font_size=11.0, default_lang=u"fr" ): - """ - Initializes a transformer turning an XHTML input tree - containing
elements representing - main content sections into a FO output tree displaying the - reports. - - page_width: float - width of the page (in cm) - page_height: float - height of the page (in cm) - margin_top: float - top margin of the page (in cm) - margin_bottom: float - bottom margin of the page (in cm) - margin_left: float - left margin of the page (in cm) - margin_right: float - right margin of the page (in cm) - header_footer_height: float - height of the header or the footer of the - page that the page number (if any) will be - inserted in. - standard_font_size: float - standard size of the font (in pt) - default_lang: u"" - default language (used for hyphenation) - """ - self.section = section - self.page_width = page_width - self.page_height = page_height - - self.page_tmargin = margin_top - self.page_bmargin = margin_bottom - self.page_lmargin = margin_left - self.page_rmargin = margin_right - - self.hf_height = header_footer_height - - self.font_size = standard_font_size - self.lang = default_lang - - XHTML2FOTransformer.__init__(self) - - - def define_pagemasters(self): - """ - Defines the page masters for the FO output document. - """ - pm = SimplePageMaster(u"page-report") - pm.set_page_dims( self.page_width*cm, self.page_height*cm ) - pm.set_page_margins({u'top' : self.page_tmargin*cm, - u'bottom': self.page_bmargin*cm, - u'left' : self.page_lmargin*cm, - u'right' : self.page_rmargin*cm }) - pm.add_peripheral_region(u"end", self.hf_height) - dims = {} - dims[u"bottom"] = self.hf_height + 0.25 - pm.set_main_region_margins(dims) - return [pm] - - def _visit_report(self, in_elt, _out_elt, params): - """ - Specific visit function for the input
elements whose class is - "report". The _root_visit method of this class selects these input - elements and asks the process of these elements with this specific - visit function. - """ - - ps = self.create_pagesequence(u"page-report") - props = { u"force-page-count": u"no-force", - u"initial-page-number": u"1", - u"format": u"1", } - self._output_properties(ps, props) - - sc = self.create_staticcontent(ps, u"end") - sc_bl = self.create_block(sc) - attrs = { u"hyphenate": u"false", } - attrs[u"font-size"] = u"%.1fpt" % (self.font_size * 0.7) - attrs[u"language"] = self.lang - attrs[u"text-align"] = u"center" - self._output_properties(sc_bl, attrs) - sc_bl.text = u"Page" + u" " # ### Should be localised! - pn = self.create_pagenumber(sc_bl) - pn.tail = u"/" - self.create_pagenumbercitation( - sc_bl, u"last-block-of-report-%d" % params[u"context_pos"]) - - fl = self.create_flow(ps, u"body") - bl = self.create_block(fl) - - # Sets on the highest block element the properties of the XHTML body - # element. These properties (at the least the inheritable ones) will - # be inherited by all the future FO elements. - bodies = list(self.in_tree.getiterator(QName(XHTML_NS, u"body"))) - if len(bodies) > 0: - attrs = self._extract_properties([bodies[0]]) - else: - attrs = default_styles[u"body"].copy() - attrs[u"font-size"] = u"%.1fpt" % self.font_size - attrs[u"language"] = self.lang - self._output_properties(bl,attrs) - - # Processes the report content - self._copy_text(in_elt, bl) - self._process_nodes(in_elt.getchildren(), bl) - - # Inserts an empty block at the end of the report in order to be able - # to compute the last page number of this report. - last_bl = self.create_block(bl) - props = { u"keep-with-previous": u"always", } - props[u"id"] = u"last-block-of-report-%d" % params[u"context_pos"] - self._output_properties(last_bl,props) - - - def _root_visit(self): - """ - Visit function called when starting the process of the input tree. - """ - content = [ d for d in self.in_tree.getiterator(QName(XHTML_NS, u"div")) - if d.get(u"id") == self.section ] - # Asks the process of the report elements with a specific visit - # function - self._process_nodes(content, self.fo_root, - with_function=self._visit_report) - diff -r 955ee1b24756 -r e8235b2789fc i18n/en.po --- a/i18n/en.po Thu Apr 08 11:04:17 2010 +0200 +++ b/i18n/en.po Thu Apr 08 13:38:36 2010 +0200 @@ -368,9 +368,6 @@ msgid "Do you want to delete the following element(s) ?" msgstr "" -msgid "Download page as pdf" -msgstr "" - msgctxt "inlined:CWUser.use_email.subject" msgid "EmailAddress" msgstr "Email address" @@ -1578,12 +1575,6 @@ msgid "contentnavigation_metadata_description" msgstr "" -msgid "contentnavigation_pdfview" -msgstr "view page as pdf icon" - -msgid "contentnavigation_pdfview_description" -msgstr "" - msgid "contentnavigation_prevnext" msgstr "previous / next entity" diff -r 955ee1b24756 -r e8235b2789fc i18n/es.po --- a/i18n/es.po Thu Apr 08 11:04:17 2010 +0200 +++ b/i18n/es.po Thu Apr 08 13:38:36 2010 +0200 @@ -376,9 +376,6 @@ msgid "Do you want to delete the following element(s) ?" msgstr "Desea suprimir el(los) elemento(s) siguiente(s)" -msgid "Download page as pdf" -msgstr "" - msgctxt "inlined:CWUser.use_email.subject" msgid "EmailAddress" msgstr "" @@ -1609,12 +1606,6 @@ msgid "contentnavigation_metadata_description" msgstr "" -msgid "contentnavigation_pdfview" -msgstr "" - -msgid "contentnavigation_pdfview_description" -msgstr "" - msgid "contentnavigation_prevnext" msgstr "Elemento anterior / siguiente" diff -r 955ee1b24756 -r e8235b2789fc i18n/fr.po --- a/i18n/fr.po Thu Apr 08 11:04:17 2010 +0200 +++ b/i18n/fr.po Thu Apr 08 13:38:36 2010 +0200 @@ -387,9 +387,6 @@ msgid "Do you want to delete the following element(s) ?" msgstr "Voulez-vous supprimer le(s) élément(s) suivant(s) ?" -msgid "Download page as pdf" -msgstr "télécharger la page au format PDF" - msgctxt "inlined:CWUser.use_email.subject" msgid "EmailAddress" msgstr "Adresse électronique" @@ -1630,12 +1627,6 @@ msgid "contentnavigation_metadata_description" msgstr "" -msgid "contentnavigation_pdfview" -msgstr "icône pdf" - -msgid "contentnavigation_pdfview_description" -msgstr "" - msgid "contentnavigation_prevnext" msgstr "élément précedent / suivant" diff -r 955ee1b24756 -r e8235b2789fc utils.py --- a/utils.py Thu Apr 08 11:04:17 2010 +0200 +++ b/utils.py Thu Apr 08 13:38:36 2010 +0200 @@ -309,35 +309,6 @@ self.body.getvalue()) -def _pdf_conversion_availability(): - try: - import pysixt - except ImportError: - return False - from subprocess import Popen, STDOUT - if not os.path.isfile('/usr/bin/fop'): - return False - try: - Popen(['/usr/bin/fop', '-q'], - stdout=open(os.devnull, 'w'), - stderr=STDOUT) - except OSError, e: - getLogger('cubicweb').info('fop not usable (%s)', e) - return False - return True - -def can_do_pdf_conversion(__answer_cache=[]): - """pdf conversion depends on - * pysixt (python package) - * fop 0.9x - - NOTE: actual check is done by _pdf_conversion_availability and - result is cached - """ - if not __answer_cache: # first time, not in cache - __answer_cache.append(_pdf_conversion_availability()) - return __answer_cache[0] - try: # may not be there if cubicweb-web not installed from simplejson import dumps, JSONEncoder diff -r 955ee1b24756 -r e8235b2789fc web/data/pdf_icon.gif Binary file web/data/pdf_icon.gif has changed diff -r 955ee1b24756 -r e8235b2789fc web/test/data/sample1.pdf Binary file web/test/data/sample1.pdf has changed diff -r 955ee1b24756 -r e8235b2789fc web/test/data/sample1.xml --- a/web/test/data/sample1.xml Thu Apr 08 11:04:17 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ - - - - - ] > - - - - - - - -Comet 0.2.0 (unset title) - - - - - - - - - - - - - - - - - - - - - - -
-
- - - \ No newline at end of file diff -r 955ee1b24756 -r e8235b2789fc web/test/unittest_pdf.py --- a/web/test/unittest_pdf.py Thu Apr 08 11:04:17 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -import os.path as osp -from tempfile import NamedTemporaryFile -from subprocess import Popen as sub -from xml.etree.cElementTree import ElementTree, fromstring, tostring, dump - -from logilab.common.testlib import TestCase, unittest_main - -from cubicweb.utils import can_do_pdf_conversion -from cubicweb.ext.xhtml2fo import ReportTransformer - -DATADIR = osp.join(osp.dirname(__file__), 'data') - -class PDFTC(TestCase): - - def test_xhtml_to_fop_to_pdf(self): - if not can_do_pdf_conversion(): - self.skip('dependencies not available : check pysixt and fop') - xmltree = ElementTree() - xmltree.parse(osp.join(DATADIR, 'sample1.xml')) - foptree = ReportTransformer(u'contentmain').transform(xmltree) - # next - foptmp = NamedTemporaryFile() - foptree.write(foptmp) - foptmp.flush() - pdftmp = NamedTemporaryFile() - fopproc = sub(['/usr/bin/fop', foptmp.name, pdftmp.name]) - fopproc.wait() - del foptmp - if fopproc.returncode: - self.skip('fop returned status %s' % fopproc.returncode) - pdftmp.seek(0) # a bit superstitious - reference = open(osp.join(DATADIR, 'sample1.pdf'), 'r').read() - output = pdftmp.read() - # XXX almost equals due to ID, creation date, so it seems to fail - self.assertEquals( len(output), len(reference) ) - # cut begin & end 'cause they contain variyng data - self.assertTextEquals(output[150:1500], reference[150:1500]) - -if __name__ == '__main__': - unittest_main() - diff -r 955ee1b24756 -r e8235b2789fc web/views/basecomponents.py --- a/web/views/basecomponents.py Thu Apr 08 11:04:17 2010 +0200 +++ b/web/views/basecomponents.py Thu Apr 08 13:38:36 2010 +0200 @@ -2,7 +2,6 @@ * the rql input form * the logged user link -* pdf view link :organization: Logilab :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. diff -r 955ee1b24756 -r e8235b2789fc web/views/basetemplates.py --- a/web/views/basetemplates.py Thu Apr 08 11:04:17 2010 +0200 +++ b/web/views/basetemplates.py Thu Apr 08 13:38:36 2010 +0200 @@ -14,7 +14,7 @@ from cubicweb.appobject import objectify_selector from cubicweb.selectors import match_kwargs from cubicweb.view import View, MainTemplate, NOINDEX, NOFOLLOW -from cubicweb.utils import UStringIO, can_do_pdf_conversion +from cubicweb.utils import UStringIO from cubicweb.schema import display_name from cubicweb.web import component, formfields as ff, formwidgets as fw from cubicweb.web.views import forms @@ -268,61 +268,6 @@ self.w(u'\n') self.w(u'\n') -if can_do_pdf_conversion(): - try: - from xml.etree.cElementTree import ElementTree - except ImportError: #python2.4 - from elementtree import ElementTree - from subprocess import Popen as sub - from StringIO import StringIO - from tempfile import NamedTemporaryFile - from cubicweb.ext.xhtml2fo import ReportTransformer - - - class PdfViewComponent(component.EntityVComponent): - __regid__ = 'pdfview' - - context = 'ctxtoolbar' - - def cell_call(self, row, col, view): - entity = self.cw_rset.get_entity(row, col) - url = entity.absolute_url(vid=view.__regid__, __template='pdf-main-template') - iconurl = self._cw.build_url('data/pdf_icon.gif') - label = self._cw._('Download page as pdf') - self.w(u'%s' % - (xml_escape(url), label, xml_escape(iconurl), label)) - - class PdfMainTemplate(TheMainTemplate): - __regid__ = 'pdf-main-template' - - def call(self, view): - """build the standard view, then when it's all done, convert xhtml to pdf - """ - super(PdfMainTemplate, self).call(view) - section = self._cw.form.pop('section', 'contentmain') - pdf = self.to_pdf(self._stream, section) - self._cw.set_content_type('application/pdf', filename='report.pdf') - self.binary = True - self.w = None - self.set_stream() - # pylint needs help - self.w(pdf) - - def to_pdf(self, stream, section): - # XXX see ticket/345282 - stream = stream.getvalue().replace(' ', ' ').encode('utf-8') - xmltree = ElementTree() - xmltree.parse(StringIO(stream)) - foptree = ReportTransformer(section).transform(xmltree) - foptmp = NamedTemporaryFile() - pdftmp = NamedTemporaryFile() - foptree.write(foptmp) - foptmp.flush() - fopproc = sub(['/usr/bin/fop', foptmp.name, pdftmp.name]) - fopproc.wait() - pdftmp.seek(0) - pdf = pdftmp.read() - return pdf # page parts templates ########################################################