1 | # fix response |
---|
2 | |
---|
3 | import os |
---|
4 | from gluon import current, HTTP |
---|
5 | from gluon.html import markmin_serializer, TAG, HTML, BODY, UL, XML, H1 |
---|
6 | from gluon.contrib.fpdf import FPDF, HTMLMixin |
---|
7 | from gluon.sanitizer import sanitize |
---|
8 | from gluon.contrib.markmin.markmin2latex import markmin2latex |
---|
9 | from gluon.contrib.markmin.markmin2pdf import markmin2pdf |
---|
10 | |
---|
11 | |
---|
12 | def wrapper(f): |
---|
13 | def g(data): |
---|
14 | try: |
---|
15 | output = f(data) |
---|
16 | return XML(ouput) |
---|
17 | except (TypeError, ValueError) as e: |
---|
18 | raise HTTP(405, '%s serialization error' % e) |
---|
19 | except ImportError as e: |
---|
20 | raise HTTP(405, '%s not available' % e) |
---|
21 | except Exception as e: |
---|
22 | raise HTTP(405, '%s error' % e) |
---|
23 | return g |
---|
24 | |
---|
25 | |
---|
26 | def latex_from_html(html): |
---|
27 | markmin = TAG(html).element('body').flatten(markmin_serializer) |
---|
28 | return markmin2latex(markmin) |
---|
29 | |
---|
30 | |
---|
31 | def pdflatex_from_html(html): |
---|
32 | if os.system('which pdflatex > /dev/null') == 0: |
---|
33 | markmin = TAG(html).element('body').flatten(markmin_serializer) |
---|
34 | out, warnings, errors = markmin2pdf(markmin) |
---|
35 | if errors: |
---|
36 | current.response.headers['Content-Type'] = 'text/html' |
---|
37 | raise HTTP(405, HTML(BODY(H1('errors'), |
---|
38 | UL(*errors), |
---|
39 | H1('warnings'), |
---|
40 | UL(*warnings))).xml()) |
---|
41 | else: |
---|
42 | return out |
---|
43 | |
---|
44 | |
---|
45 | def pyfpdf_from_html(html): |
---|
46 | request = current.request |
---|
47 | |
---|
48 | def image_map(path): |
---|
49 | if path.startswith('/%s/static/' % request.application): |
---|
50 | return os.path.join(request.folder, path.split('/', 2)[2]) |
---|
51 | return 'http%s://%s%s' % (request.is_https and 's' or '', request.env.http_host, path) |
---|
52 | |
---|
53 | class MyFPDF(FPDF, HTMLMixin): |
---|
54 | pass |
---|
55 | pdf = MyFPDF() |
---|
56 | pdf.add_page() |
---|
57 | # pyfpdf needs some attributes to render the table correctly: |
---|
58 | html = sanitize( |
---|
59 | html, allowed_attributes={ |
---|
60 | 'a': ['href', 'title'], |
---|
61 | 'img': ['src', 'alt'], |
---|
62 | 'blockquote': ['type'], |
---|
63 | 'td': ['align', 'bgcolor', 'colspan', 'height', 'width'], |
---|
64 | 'tr': ['bgcolor', 'height', 'width'], |
---|
65 | 'table': ['border', 'bgcolor', 'height', 'width'], |
---|
66 | }, escape=False) |
---|
67 | pdf.write_html(html, image_map=image_map) |
---|
68 | return XML(pdf.output(dest='S')) |
---|
69 | |
---|
70 | |
---|
71 | def pdf_from_html(html): |
---|
72 | # try use latex and pdflatex |
---|
73 | if os.system('which pdflatex > /dev/null') == 0: |
---|
74 | return pdflatex_from_html(html) |
---|
75 | else: |
---|
76 | return pyfpdf_from_html(html) |
---|