Attachment 'RenderAsPDF.py'

Download

   1 import os, subprocess
   2 from MoinMoin.Page import Page
   3 from MoinMoin.action import ActionBase
   4 
   5 temp_direcotry = '/home2/sixmen/tmp'
   6 cmd_xmllint = '/usr/bin/xmllint'
   7 cmd_saxon = '/home2/sixmen/tool/docbook/bin/saxon.sh'
   8 cmd_fop = '/home2/sixmen/tool/docbook/bin/fo2pdf.sh'
   9 docbook_xsl = '/home2/sixmen/tool/docbook/stylesheet/dbk-fo.xsl'
  10 show_pdf_as_inline = True
  11 #show_pdf_as_inline = False
  12 
  13 class Msg:
  14     def __init__(self, msg):
  15         self.msg = msg
  16     def render(self):
  17         return self.msg
  18 
  19 def make_url(request, pagename, stage, add_param=True, add_def=False):
  20     if add_param:
  21         url = Page(request, pagename).url(request, {
  22             'action': 'RenderAsPDF',
  23             'stage': stage,
  24             'check_double_sided': request.values.get('check_double_sided', '0'),
  25             'check_indent_body': request.values.get('check_indent_body', '0'),
  26             'check_break_refentry': request.values.get('check_break_refentry', '0'),
  27         })
  28     else:
  29         url = Page(request, pagename).url(request, {'action': 'RenderAsPDF', 'stage': stage})
  30     if add_def:
  31         url += ''.join(['&docbookdef=%s' % (d) for d in request.values.getlist('docbookdef')]) # add docbookdef
  32     return url
  33 
  34 class RenderAsPDF(ActionBase):
  35     def __init__(self, pagename, request):
  36         ActionBase.__init__(self, pagename, request)
  37         self.form_trigger = 'renderaspdf'
  38         self.form_trigger_label = 'Render As PDF'
  39 
  40     def do_action(self):
  41         return True, ""
  42 
  43     def do_action_finish(self, success):
  44         if not success:
  45             self.render_msg(self.make_form(), "dialog")
  46             return
  47 
  48         request = self.request
  49         pagename = self.pagename
  50         page = self.page
  51 
  52         request.theme.add_msg(Msg("Wait for a while..."))
  53         request.theme.send_title(page.split_title(), pagename=pagename)
  54         request.write(request.formatter.startContent("content"))
  55         request.write(request.formatter.endContent())
  56         request.theme.send_footer(pagename)
  57         request.theme.send_closing_html()
  58         url = make_url(request, pagename, 'begin', add_def=True)
  59         request.write("<iframe src='%s' width=0 height=0 style='visibility:hidden;'></iframe>" % (url))
  60 
  61     def get_form_html(self, buttons_html):
  62         _ = self._
  63         defines_html = []
  64         if self.page.pi.has_key('docbook'):
  65             from MoinMoin.wikiutil import ParameterParser
  66             pp = ParameterParser("%(title)s%(doctype)s%(rootattr)s%(define)s")
  67             count, param = pp.parse_parameters(self.page.pi['docbook'])
  68             defines = param.get('define')
  69             if defines:
  70                 for define in defines.split(','):
  71                     defines_html.append('<input type="checkbox" name="docbookdef" value="%s"> <label>%s</label>' % (define,define))
  72         defines_html = "<br>".join(defines_html)
  73         return '''
  74 <h3>Select Style Options</h3>
  75 <input type="checkbox" name="check_double_sided" value="1" %(check_double_sided)s>
  76 <label>Double sided</label>
  77 <!--
  78 <br>
  79 <input type="checkbox" name="check_indent_body" value="1" %(check_indent_body)s>
  80 <label>Indent body</label>
  81 -->
  82 <br>
  83 <input type="checkbox" name="check_break_refentry" value="1" %(check_break_refentry)s>
  84 <label>Refentry pagebreak</label>
  85 <hr>
  86 <h3>Select Definitions to Enable</h3>
  87 %(defines_html)s
  88 <hr>
  89 %(buttons_html)s
  90 ''' % {
  91             'check_double_sided': ('', 'checked')[self.request.values.get('check_double_sided', '0') == '1'],
  92             'check_indent_body': ('', 'checked')[self.request.values.get('check_indent_body', '0') == '1'],
  93             'check_break_refentry': ('', 'checked')[self.request.values.get('check_break_refentry', '0') == '1'],
  94             'buttons_html': buttons_html,
  95             'defines_html': defines_html
  96         }
  97 
  98 def runCommand(cmdstr):
  99     process = subprocess.Popen(cmdstr, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 100     output, unused_err = process.communicate()
 101     output = output.replace('"', '\\"').replace('\n', '\\n')
 102     retcode = process.poll()
 103     return (retcode, output)
 104 
 105 def execute(pagename, request):
 106     temp_file_path = temp_direcotry + '/_renderaspdf_' + request.user.name
 107     stage = request.values.get('stage')
 108 
 109     def stage_success(msg, result, url):
 110         request.write("""
 111 <script type="text/javascript">
 112 msg = parent.document.getElementById('message');
 113 msg.innerHTML = "<p>%s</p><pre>%s</pre>";
 114 location.href = '%s';
 115 </script>
 116 """ % (msg, result, url))
 117 
 118     def stage_fail(msg, result):
 119         request.write("""
 120 <script type="text/javascript">
 121 msg = parent.document.getElementById('message');
 122 msg.innerHTML = "<p>%s</p><pre>%s</pre>";
 123 </script>
 124 """ % (msg, result))
 125 
 126     if stage=='begin':
 127         stage_success('Creating DocBook XML...', '', make_url(request, pagename, 'xml', add_def=True))
 128 
 129     elif stage=='xml':
 130         page = Page(request, pagename, formatter='text/docbook')
 131         request.redirect(open(temp_file_path + '.xml', 'wb'))
 132         try:
 133             page.send_page(emit_headers=0)
 134         finally:
 135             request.redirect()
 136         stage_success('Validating XML...', '', make_url(request, pagename, 'validate'))
 137 
 138     elif stage=='validate':
 139         cmd = [cmd_xmllint, '--noout', '--valid', temp_file_path + '.xml']
 140         status, output = runCommand(cmd)
 141         stage_success('Creating DocBook FO...', output, make_url(request, pagename, 'fo'))
 142 
 143     elif stage=='fo':
 144         import datetime
 145         cmd = [cmd_saxon, '-o', temp_file_path + '.fo', temp_file_path + '.xml', docbook_xsl]
 146         cmd.append("build.date='%s'" % (datetime.date.today()))
 147         if request.values.get('check_double_sided', '0')=='1':
 148             cmd.append('double.sided=1')
 149         if request.values.get('check_indent_body', '0')=='1':
 150             cmd.append('body.start.indent=4pc')
 151         if request.values.get('check_break_refentry', '0')=='1':
 152             cmd.append('refentry.pagebreak=1')
 153         status, output = runCommand(cmd)
 154         if status==0:
 155             stage_success('Creating DocBook PDF...', output, make_url(request, pagename, 'pdf', add_param=False))
 156         else:
 157             stage_fail('Fail to create FO...', output)
 158         os.remove(temp_file_path + '.xml')
 159 
 160     elif stage=='pdf':
 161         cmd = [cmd_fop, temp_file_path + '.fo', temp_file_path + '.pdf']
 162         status, output = runCommand(cmd)
 163         if status==0:
 164             url = make_url(request, pagename, 'send_pdf', add_param=False)
 165             request.write("""
 166 <script type="text/javascript">
 167 msg = parent.document.getElementById('message');
 168 msg.innerHTML = "<p>Finished</p><pre>%s</pre>";
 169 %s.href = '%s';
 170 </script>
 171 """ % (output, ['location','parent.location'][show_pdf_as_inline], url))
 172         else:
 173             stage_fail('Fail to create PDF...', output)
 174         os.remove(temp_file_path + '.fo')
 175 
 176     elif stage=='send_pdf':
 177         pdf_filename = temp_file_path + '.pdf'
 178         request.headers.add('Content-Type', 'application/pdf')
 179         request.headers.add('Content-Length', os.path.getsize(pdf_filename))
 180         request.headers.add('Content-Disposition', '%s; filename="%s"' % (['attachment', 'inline'][show_pdf_as_inline], 'docbook.pdf'))
 181 
 182         pf = open(pdf_filename, 'rb')
 183         request.send_file(pf)
 184         pf.close()
 185 
 186         os.remove(pdf_filename)
 187 
 188     else:
 189         RenderAsPDF(pagename, request).render()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2012-02-09 08:27:39, 7.2 KB) [[attachment:RenderAsPDF.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.