generics.py 2.5 KB

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