import functools

from flask import Flask, render_template, request, Response, make_response
import requests

from open511.converter import json_doc_to_xml, xml_to_json, FORMATS, FORMATS_LIST, open511_convert
from open511.validator import validate, Open511ValidationError
from open511.utils.serialization import deserialize, serialize

app = Flask(__name__)
 
def no_cache(f):
    def new_func(*args, **kwargs):
        resp = make_response(f(*args, **kwargs))
        resp.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
        return resp
    return functools.update_wrapper(new_func, f)

@app.route('/', methods=['GET', 'POST'])
@no_cache
def validator():
    ctx = {
        'conversion_formats': FORMATS_LIST
    }
    if request.method == 'GET' and 'url' not in request.args:
        return render_template('validator.html', **ctx)
    else:
        try:
            doc_content = _load_document()
        except FetchError as e:
            ctx['fetch_error'] = unicode(e)
            return render_template('validator.html', **ctx)
        try:
            if not isinstance(doc_content, unicode):
                doc_content = doc_content.decode('utf8')
            doc, doc_format = deserialize(doc_content)
        except Exception as e:
            ctx.update(doc_content=doc_content, deserialize_error=unicode(e))
            return render_template('validator.html', **ctx)

        if doc_format == 'json':
            json_doc = doc
            try:
                xml_doc = json_doc_to_xml(json_doc, custom_namespace='http://validator.open511.com/custom-field')
            except Exception as e:
                ctx.update(error=unicode(e), doc_content=doc_content)
                return render_template('validator.html', **ctx)
        elif doc_format == 'xml':
            xml_doc = doc
            try:
                json_doc = xml_to_json(xml_doc)
            except:
                json_doc = 'Error generating JSON'
        else:
            raise NotImplementedError

        try:
            validate(xml_doc)
            success = True
        except Open511ValidationError as e:
            success = False
            error = unicode(e)
        ctx.update(
            success=success,
            error=None if success else error,
            xml_string=serialize(xml_doc),
            json_string=serialize(json_doc),
            doc_format=doc_format
        )
        return render_template('validator.html', **ctx)

class FetchError(Exception):
    pass

def _load_document():
    if 'url' in request.values:
        url = request.values['url']
        if not url.startswith('http'):
            url = 'http://' + url
        try:
            doc_content = requests.get(url, headers={'Accept': 'application/xml, application/json;q=0.9'}).content
        except Exception as e:
            raise FetchError(unicode(e))
    elif 'doc_content' in request.form:
        doc_content = request.form['doc_content']
    elif 'upload' in request.files:
        doc_content = request.files['upload'].read()
    else:
        raise NotImplementedError
    return doc_content

@app.route('/convert', methods=['GET', 'POST'])
@no_cache
def convert():
    doc_content = _load_document()
    if not isinstance(doc_content, unicode):
        doc_content = doc_content.decode('utf8')
    doc, doc_format = deserialize(doc_content)

    format = request.values['format']
    result = open511_convert(doc, format)
    format_info = FORMATS[format]
    return Response(result, mimetype=format_info.content_type)

if __name__ == '__main__':
    app.run(debug=True)
@@ -9,16 +9,41 @@
 unctools
+%0Aimport logging%0Aimport os
 %0A%0Afrom f
@@ -375,16 +375,1077 @@
 _name__)
+%0A%0Aif os.environ.get('OPEN511_EMAIL_ERRORS'):%0A    from logging.handlers import SMTPHandler%0A    if os.environ.get('MANDRILL_USERNAME'):%0A        # Automatically support Mandrill config%0A        mailhost = 'smtp.mandrillapp.com'%0A        mailport = '587'%0A        username = os.environ.get('MANDRILL_USERNAME')%0A        password = os.environ.get('MANDRILL_APIKEY')%0A    else:%0A        mailhost = os.environ.get('SMTP_SERVER')%0A        mailport = os.environ.get('SMTP_SERVER_PORT', 25)%0A        username = os.environ.get('SMTP_USERNAME')%0A        password = os.environ.get('SMTP_PASSWORD')%0A    mail_config = dict(%0A        mailhost=(mailhost,mailport),%0A        fromaddr=os.environ.get('OPEN511_EMAIL_ERRORS_FROM', 'server-error@validator.open511.org'),%0A        toaddrs=%5Bos.environ%5B'OPEN511_EMAIL_ERRORS'%5D%5D,%0A        subject='Open511 Validator server error'%0A    )%0A    if username and password:%0A        mail_config%5B'credentials'%5D = (username, password)%0A    mail_handler = SMTPHandler(**mail_config)%0A    mail_handler.setLevel(logging.ERROR)%0A    app.logger.addHandler(mail_handler)
 %0A %0Adef n

Add email error logging