Mercurial > odfcast > odfcast
view odfcast/convert.py @ 42:6d511e93a331
Return requested format when an error has occured
Introduce ErrorResponse class which returns the error in the format as
requested.
author | Björn Ricks <bjoern.ricks@intevation.de> |
---|---|
date | Wed, 22 Oct 2014 14:38:31 +0200 |
parents | a1100ec32be2 |
children | e99cbb47eafb |
line wrap: on
line source
# -*- coding: utf-8 -*- import logging import tempfile from flask import request, Response, json, render_template from flask.views import MethodView from py3o.template import Template from PyPDF2 import PdfFileMerger log = logging.getLogger(__name__) ALLOWED_FORMATS = ["pdf", "doc", "docx", "odt"] PDF_MIMETYPE = "application/pdf" MIMETYPES = { "odt": "application/vnd.oasis.opendocument.text", "doc": "application/msword", "docx": "application/vnd.openxmlformats-officedocument" ".wordprocessingml.document", "pdf": PDF_MIMETYPE, } DEFAULT_MIMETYPE = "application/octet-stream" class ErrorResponse(object): def __init__(self, title, details="", html_error_code=500): self.title = title self.details = details self.html_error_code = html_error_code def __call__(self): if self.is_wants_json(): return self.json() else: return self.html() def json(self): return json.dumps({ "error": self.title, "details": self.details }), self.html_error_code def html(self): return self.title, self.html_error_code def is_wants_json(self): best = request.accept_mimetypes.best_match(['application/json', 'text/html']) return best == 'application/json' and \ request.accept_mimetypes[best] > \ request.accept_mimetypes['text/html'] class ConvertView(MethodView): def __init__(self, pyuno_driver_name="", hostname="localhost", port=2001): driver_module = self._load_driver_module(pyuno_driver_name) self.convertor = driver_module.Convertor(hostname, port) def _load_driver_module(self, pyuno_driver_name): return __import__(pyuno_driver_name, globals(), locals(), ["Convertor"]) def is_format_supported(self, fformat): return fformat and fformat.lower() in ALLOWED_FORMATS def post(self): ffile = request.files['file'] if not ffile.filename: error = ErrorResponse("Please upload a file for conversion", html_error_code=401) return error() fformat = request.form['format'] if not self.is_format_supported(fformat): error = ErrorResponse("Format %s not allowed" % fformat, html_error_code=401) return error() datadict = self.get_datadict() mimetype = self.get_mimetype_for_format(fformat) outfile = self.save_form_file(ffile) if datadict: try: tfile = tempfile.NamedTemporaryFile() t = Template(outfile, tfile, ignore_undefined_variables=True) t.render(datadict) outfile.close() outfile = tfile except Exception, e: log.exception("Template error") error = ErrorResponse( "Template error", details=str(e), html_error_code=500) return error() if fformat != "odt": try: outfile = self.convert(outfile, fformat) except Exception, e: log.exception("Conversion error") error = ErrorResponse( "Conversion error", details=str(e), html_error_code=500) return error() return Response(outfile, mimetype=mimetype) def get(self): return render_template("convert.html") def save_form_file(self, infile): outfile = tempfile.NamedTemporaryFile() infile.save(outfile) infile.close() outfile.seek(0) return outfile def convert(self, infile, fformat): outfile = tempfile.NamedTemporaryFile() self.convertor.convert(infile.name, outfile.name, fformat) infile.close() return outfile def get_mimetype_for_format(self, fformat): return MIMETYPES.get(fformat, DEFAULT_MIMETYPE) def get_datadict(self): vars = request.form.get('datadict') if not vars: return None return json.loads(vars) class MergeView(MethodView): def get(self): return render_template("merge.html") def post(self): merger = PdfFileMerger() ffiles = request.files.getlist('files') for ffile in ffiles: merger.append(ffile) outfile = tempfile.NamedTemporaryFile() merger.write(outfile.name) merger.close() return Response(outfile, mimetype=PDF_MIMETYPE) class TemplateView(MethodView): template_name = "" def __init__(self, template_name=None): if template_name: self.template_name = template_name def get_template_name(self): return self.template_name def get(self): return render_template(self.get_template_name())