Beispiel #1
0
def review_translation(translation_id):
    '''
    Formulario de revisión de traducción
    '''

    page = request.args.get("page", 0, int)
    mode = request.args.get("show", "old", str)
    size = request.args.get("size", 15, int)

    # Optimización: si envío en un campo la lista de strids, no la pido a BBDD
    data = None
    if request.form.get("field_keys", None):
        data_fields = {i:"" for i in request.form.get("fields").replace("‚",",").replace("&","&").split(",")}
    else:
        data = pagesdb.get_translation(translation_id)
        data_fields = data["texts"]

    # Lenguaje base
    base_lang = pomanager.get_lang("en")

    # Campos de traducción
    fields = {"field_%s" % key:
        TextAreaField(key, default=unfix_lang_values(value, base_lang[key]) or value)
        if len(value) > 40 else
        TextField(key, default=unfix_lang_values(value, base_lang[key]) or value)
        for key, value in data_fields.iteritems() if key in base_lang}

    # Checkboxes
    fields.update(
        ("check_%s" % key,  BooleanField(default=False))
        for key in data_fields.iterkeys())

    form = expanded_instance(ValidateTranslationForm, fields, request.form, prefix="translation_")

    # Guardo en el Hiddenfield la lista de strids
    form.field_keys = "&".join(i.replace("&","&").replace(",","‚") for i in data_fields.iterkeys())

    if request.method=='POST' and form.validate():
        if form.submit.data:
            # Actualizamos el lenguaje de destino con los valores con checkbox marcado
            pomanager.update_lang(data["dest_lang"],
                {key: form["field_%s" % key].data
                    for key in data_fields.iterkeys() if form["check_%s" % key].data})
        pagesdb.update_translation({"_id":translation_id,"processed":True})
        flash("admin_saved")
        return redirect(url_for('admin.translations', page=page, mode=mode, size=size))
    elif data is None:
        # Si no he pedido a base de datos la traducción por optimizar, pero no queda otra
        data = pagesdb.get_translation(translation_id)

    pomanager.preload((g.lang, data["dest_lang"], data["user_lang"]))

    cur_lang = pomanager.get_lang(g.lang)
    user_lang = pomanager.get_lang(data["user_lang"])
    dest_lang = pomanager.get_lang(data["dest_lang"])

    translation = {
        key:(
             cur_lang[key] if key in cur_lang else None,
             user_lang[key] if key in user_lang else None,
             dest_lang[key] if key in dest_lang else None)
        for key, value in data.pop("texts").iteritems()
        if key in base_lang
        }

    return render_template('admin/translation_review.html',
        page_title=_('admin_translation_review'),
        title=admin_title('admin_translation_review'),
        form=form,
        langs=(g.lang, data["user_lang"], data["dest_lang"]),
        data=data,
        page=page,
        list_mode=mode,
        field_keys=",".join(translation.iterkeys()),
        fields=translation)
Beispiel #2
0
def db_edit(collection, document_id=None):
    '''
    Edición de base de datos
    '''

    page = request.args.get("page", 0, int)
    grps = request.args.get("mode", "all", str)
    mode = request.args.get("show", "current", str)
    size = request.args.get("size", 15, int)

    page_title = "admin_edit"
    form_title = "admin_edit"
    data = None

    form_force_fields = ("_id",) if document_id is None else ()
    form_readonly_fields = ("_id",) if document_id else ()
    form_ignored_fields = ()
    form_fieldtypes = {}
    form_fieldkwargs = {}
    form_fieldparams = {}

    document = {}
    deleteable = bool(document_id) # Mostrar o no el botón de borrar

    # Especificidades de las colecciones
    if collection == "user":
        # Nota: El campo "password" es un hash, de modo que lo establezco de
        #       sólo lectura y creo un nuevo campo "new password" para
        #       cambiarla (ver endpoint "db_confirm").
        page_title = 'admin_users'
        form_title = 'admin_users_info'
        form_force_fields += ("karma", "token", "username", "email", "new password", "lang", "location", "karma", "active", "type", "oauthid")
        form_readonly_fields += ("created","password")
        data = usersdb.find_userid(document_id) if document_id else {}
    elif collection == "origin":
        deleteable = current_app.debug
        page_title = 'admin_origins_info'
        form_title = 'admin_origins_info'
        form_force_fields += ("tb", "crbl", "d", "g", "ig")
        #form_readonly_fields += ()
        data = filesdb.get_source_by_id(float(document_id)) if document_id else {}
    elif collection == "alternatives":
        url_id = "admin.alternatives"
        available_methods = configdb.list_alternatives_methods()
        available_endpoints = configdb.list_alternatives_endpoints(document_id) if document_id else []
        available_param_types = configdb.list_alternatives_param_types()
        form_force_fields += ("default", "methods", "param_name", "param_type", "remember_id", "probability")
        form_fieldtypes["probability"] = TextAreaField
        form_fieldtypes["param_type"] = SelectField

        if document_id:
            form_fieldtypes["default"] = SelectField
            form_fieldkwargs["default"] = {"choices": ((repr(i), repr(i)) for i in available_endpoints)}
            data = {"default":available_endpoints[0] if available_endpoints else None}
            data.update(configdb.get_alternative_config(document_id))
            if not "_id" in data: data["_id"] = document_id
            if not "remember_id" in data: data["remember_id"] = document_id
            if not "param_name" in data: data["param_name"] = "alt"
        else:
            data = {}

        data["available_methods"] = ", ".join(available_methods)
        form_fieldkwargs["param_type"] = {"choices": ((i, i) for i in available_param_types)}
        form_fieldparams["available_methods"] = form_fieldparams["available_endpoints"] = {"readonly":"readonly"}
        form_fieldparams["probability"] = {"rows": len(available_endpoints), "class":"monospaced"}
    else:
        abort(404)

    document.update((i, db_ftd(collection, i, "")) for i in form_force_fields)
    if data: document.update(data)

    document_defaults = document
    document_writeable = sorted(k for k in document.iterkeys() if not (k in form_readonly_fields or k in form_ignored_fields))

    edict = {}
    edit_form = expanded_instance(EditForm, {
        db_fnm(k): form_fieldtypes.get(k, TextField)(k, default=db_dtf(collection, k, document[k]), **form_fieldkwargs.get(k, edict))
        for k in document_writeable
        }, request.form)

    edit_form.defaults.data = db_serialize(collection, document_defaults)
    edit_form.editable.data = json.dumps(document_writeable)

    return render_template('admin/edit.html',
        deleteable = deleteable,
        collection=collection,
        document_id=document_id,
        title = admin_title(page_title),
        page_title = _(page_title),
        edit_form = edit_form,
        form_title = _(form_title),
        fieldname = db_fnm,
        fieldparams = form_fieldparams,
        document_writeable = [(k, document[k]) for k in document_writeable],
        document_readonly = [(k, document[k]) for k in document if not (k in document_writeable or k in form_ignored_fields)],
        list_mode = grps, mode = mode, page = page)
Beispiel #3
0
def db_confirm(collection, document_id=None):
    '''
    Confirmación de edición de base de datos
    '''
    page = request.args.get("page", 0, int)
    grps = request.args.get("mode", "all", str)
    mode = request.args.get("show", "current", str)
    size = request.args.get("size", 15, int)

    document = db_unserialize(collection, request.form.get("defaults"))
    document_writeable = json.loads(request.form.get("editable"))

    request_form_dict = MultiDict(request.form)

    # Valores por defecto

    page_title = "admin_edit"
    form_title = "admin_edit"

    success_msgid = "admin_saved"
    unchanged_msgid = "admin_nochanges"

    form_fieldtypes = {}
    form_fieldkwargs = {}

    url_id = "admin.index"

    goback = lambda : redirect(url_for(url_id, page = page, mode = grps, show = mode, size = size))

    # Especificaciones de las colecciones
    if collection == "user":
        page_title = 'admin_users'
        form_title = 'admin_users_info'
        success_msgid = "admin_users_updated"
        url_id = "admin.users"
        save_fnc = lambda data: (
            usersdb.create_user(data)
            if document_id is None else
            usersdb.update_user(data)
            )
        # La contraseña se mueve del campo "new password" a "password"
        new_password = request_form_dict.pop(db_fnm("new password"), None)
        if new_password:
            document_writeable.append("password")
            request_form_dict[db_fnm("password")] = new_password
    elif collection == "origin":
        page_title = 'admin_origins_info'
        form_title = 'admin_origins_info'
        url_id = "admin.origins"
        save_fnc = lambda data: (
            filesdb.create_source(data)
            if document_id is None else
            filesdb.update_source(data)
            )
    elif collection == "alternatives":
        url_id = "admin.alternatives"
        save_fnc = lambda data: configdb.update_alternative_config(document_id or data["_id"], data)
    else:
        abort(404)

    if db_confirm_debug: # debug mode
        def dummy_save(x):
            logging.debug(("Update:" if document_id else "Create: ") + repr(x))
        save_fnc = dummy_save

    # Procesamiento de formulario
    if request.form.get("confirmed", "False") == "True":
        # La petición ya ha sido confirmada, procesamos
        check_form = expanded_instance(EditForm,
            {db_fnm(k): BooleanField(k) for k in document_writeable},
            request_form_dict)
        data = {k: document[k] for k in document_writeable if check_form[db_fnm(k)].data}
        if data:
            # Hay datos que modificar, se ejecuta save_fnc y redirigimos
            if not document_id is None:
                data["_id"] = db_ftd(collection, "_id", document_id)
            try:
                save_fnc(data)
                flash(success_msgid, "success")
                return goback()
            except BaseException as e:
                flash(traceback.format_exc(e), "error")
                return goback()
        else:
            # No hay datos que modificar, redirigimos
            flash(unchanged_msgid, "error")
            return goback()
    else:
        # No se trata de la petición confirmada, procesamos el formulario como
        # viene de db_edit, generamos el formulario de confirmación.
        edict = {}
        edit_form = expanded_instance(EditForm, {
            db_fnm(k): form_fieldtypes.get(k, TextField)( k,
                default=db_dtf(collection, k, document[k]) if k in document else None,
                **form_fieldkwargs.get(k, edict))
            for k in document_writeable
            }, request_form_dict)
        document_changes = [
            (k, document.get(k, None), db_ftd(collection, k, edit_form[db_fnm(k)].data))
            for k in document_writeable
            if document.get(k, None) != db_ftd(collection, k, edit_form[db_fnm(k)].data)
            ]
        if document_changes:
            # Si hay cambios, generamos el formulario de confirmación
            check_form = expanded_instance(EditForm,
                {db_fnm(k): BooleanField(k, default=False) for k, w, w in document_changes})
            check_form.defaults.data = db_serialize(collection, {k: w for k, v, w in document_changes})
            check_form.editable.data = json.dumps([k for k, w, v in document_changes])
            check_form.confirmed.data = True
        else:
            # Si no hay cambios, redirigimos
            flash(unchanged_msgid, "error")
            return goback()

    return render_template('admin/confirm.html',
        collection=collection,
        document_id=document_id,
        title = admin_title(page_title),
        page_title = _(page_title),
        check_form = check_form,
        form_title = _(form_title),
        fieldname = db_fnm,
        repr=repr,
        document_changes = document_changes,
        list_mode = grps, mode = mode, page = page)
Beispiel #4
0
def translate():
    '''
    Edita la traducción a un idioma
    '''
    def fix_values(entry,sample=False):
        '''
        Si la traduccion contiene campos de valores los sustituimos por ______[X] y ponemos un ejemplo de uso,
        además se eliminan los saltos de linea
        '''
        result=re.finditer(r'(%\(([^\)]+)\)([s|d]))', entry.msgstr)
        subs=dict()
        # se cargan los ejemplos si es necesario
        if entry.msgid in samples:
            subs=samples[entry.msgid]

        # para cada valor encontrado se sustituye por _____[X]
        for i,item in enumerate(result):
            entry.msgstr=entry.msgstr.replace(item.group(1),"_____["+str(i+1)+"]")
            # para los ejemplos numericos se utiliza uno aleatorio
            if item.group(3)=="d":
                subs[item.group(2)]=random.randint(2,10)

        if sample:
            if subs!={}:
                return (entry.msgid,(entry.msgstr,_(entry.msgid,**subs)))
            else:
                return (entry.msgid,(entry.msgstr,False))

        # se sustituyen los saltos de linea html y se devuelve todo
        return (entry.msgid,entry.msgstr.replace("<br>","\n").replace("<br />","\n").replace("<br/>","\n") if "<br" in entry.msgstr else entry.msgstr)

    languages = localedata.load(g.lang)["languages"]
    keystrcoll = cmp_to_key(locale.strcoll)
    form = None
    forml = SelectLanguageForm(request.form)
    forml.lang.choices = [("", "-- "+_("choose_language")+" --")] + sorted(
        ((code, localedata.load(code)["languages"][code].capitalize()+" ("+languages[code].capitalize()+")")
            for code, language in languages.items()
            if code in current_app.config["TRANSLATE_LANGS"] and not code in current_app.config["LANGS"] and localedata.exists(code) and code in localedata.load(code)["languages"]),
        key=lambda x: keystrcoll(x[1]))

    total=99999
    no_translation=0
    msgids=[]
    lang_edit = request.args.get("lang")
    if not lang_edit in languages:
        lang_edit = None

    formfields = {}
    # mostrar el idioma a traducir
    if lang_edit is not None:
        forml.lang.default=lang_edit
        # cargar idioma actual
        current_lang = dict(fix_values(entry,True) for entry in polib.pofile(lang_path(g.lang)))

        # si existe el idioma se carga, sino vacio
        lpath = lang_path(lang_edit)
        new_lang = dict(fix_values(entry) for entry in polib.pofile(lpath)) if lpath else {}

        # recorre los ids en ingles y los coge el mensaje del idioma actual y el valor del nuevo
        for i, (msgid, msgstr) in enumerate(fix_values(entry,True) for entry in polib.pofile(lang_path("en"))):
            # se excluyen los textos legales que concluyen con safe_
            if not msgid.startswith(("safe_","admin_")):
                # si no esta traducida la cadena en el idioma actual se deja vacio
                if not msgid in new_lang:
                    no_translation+=1
                    new_lang[msgid]=""

                # si el mensaje esta traducido al idioma actual se usa, sino se usa el ingles
                if msgid in current_lang:
                    msg=current_lang[msgid][0]
                    description=current_lang[msgid][1]
                else:
                    msg=msgstr[0]
                    description=msgstr[1]

                # si la traduccion es mayor de 80 caracteres se utiliza un textarea en vez de un input text
                length=len(new_lang[msgid] or msg)
                if length>80:
                    formfields[msgid]=TextAreaField(msg,default=new_lang[msgid],description=description)
                    # se le establecen las filas al text area dependiendo del tamaño de la traduccion
                    formfields["_args_%s" % msgid]={"rows":length/50}
                else:
                    formfields[msgid]=TextField(msg,default=new_lang[msgid],description=description)
                    formfields["_args_%s" % msgid]={}

                #se añade a la lista que se le envia al formulario
                msgids.append(msgid)

        total=float(len(msgids))
        form=expanded_instance(TranslateForm, formfields, request.form, prefix="translate_")
        # si es el envio de la traducción
        if request.method == 'POST' and form.validate():
            pagesdb.create_translation({"ip":request.remote_addr,"user_lang":g.lang,"dest_lang":lang_edit,"texts":{field.short_name: field.data for field in form if not field.short_name in ("captcha", "submit_form") and field.data!=new_lang[field.short_name]}})
            flash("translation_sent")
            return redirect(url_for('index.home'))

    if lang_edit: forml.lang.data = lang_edit
    # sino se muestra la seleccion de idioma a traducir
    g.title+=_("translate_to_your_language")
    return render_template('pages/translate.html',
        page_title=_("translate_to_your_language"),
        lang=lang_edit,
        forml=forml,
        form=form,
        msgids=msgids,
        complete=round(((total-no_translation)/total)*100,2))
Beispiel #5
0
def translate():
    '''
    Edita la traducción a un idioma
    '''

    languages = localedata.load(g.lang)["languages"]
    keystrcoll = cmp_to_key(locale.strcoll)
    form = None
    forml = SelectLanguageForm(request.form)
    forml.lang.choices = [("", "-- "+_("choose_language")+" --")] + sorted(
        ((code, localedata.load(code)["languages"][code].capitalize()+" ("+languages[code].capitalize()+")")
            for code, language in languages.items()
            if code in current_app.config["TRANSLATE_LANGS"] and not code in current_app.config["LANGS"] and localedata.exists(code) and code in localedata.load(code)["languages"]),
        key=lambda x: keystrcoll(x[1]))

    total=99999
    no_translation=0
    msgids=[]
    lang_edit = request.args.get("lang")
    if not lang_edit in languages:
        lang_edit = None

    formfields = {}
    # mostrar el idioma a traducir
    if lang_edit is not None:
        forml.lang.default=lang_edit
        # cargar idioma actual
        current_lang = dict(fix_lang_values(entry,True) for entry in polib.pofile(lang_path(g.lang)))

        # si existe el idioma se carga, sino vacio
        lpath = lang_path(lang_edit)
        new_lang = dict(fix_lang_values(entry) for entry in polib.pofile(lpath)) if lpath else {}

        # recorre los ids en ingles y los coge el mensaje del idioma actual y el valor del nuevo
        for i, (msgid, msgstr) in enumerate(fix_lang_values(entry,True) for entry in polib.pofile(lang_path("en"))):
            # se excluyen los textos legales que concluyen con safe_
            if not msgid.startswith(current_app.config["PRIVATE_MSGID_PREFIXES"]):
                # si no esta traducida la cadena en el idioma actual se deja vacio
                if not msgid in new_lang:
                    no_translation+=1
                    new_lang[msgid]=""

                # si el mensaje esta traducido al idioma actual se usa, sino se usa el ingles
                if msgid in current_lang:
                    msg=current_lang[msgid][0]
                    description=current_lang[msgid][1]
                else:
                    msg=msgstr[0]
                    description=msgstr[1]

                # si la traduccion es mayor de 80 caracteres se utiliza un textarea en vez de un input text
                length=len(new_lang[msgid] or msg)
                if length>50:
                    formfields[msgid]=TextAreaField(msg,default=new_lang[msgid],description=description)
                    # se le establecen las filas al text area dependiendo del tamaño de la traduccion
                    formfields["_args_%s" % msgid]={"rows":length/15}
                else:
                    formfields[msgid]=TextField(msg,default=new_lang[msgid],description=description)
                    formfields["_args_%s" % msgid]={}

                #se añade a la lista que se le envia al formulario
                msgids.append(msgid)

        total=float(len(msgids))
        form=expanded_instance(TranslateForm, formfields, request.form, prefix="translate_")
        # si es el envio de la traducción
        if request.method == 'POST' and form.validate():
            pagesdb.create_translation({"ip":request.remote_addr,"user_lang":g.lang,"dest_lang":lang_edit,"texts":{field.short_name: field.data for field in form if not field.short_name in ("captcha", "submit_form") and field.data!=new_lang[field.short_name]}})
            flash("translation_sent")
            return redirect(url_for('index.home'))

    if lang_edit: forml.lang.data = lang_edit
    # sino se muestra la seleccion de idioma a traducir
    g.title+=_("translate_to_your_language")
    return render_template('pages/translate.html',
        page_title=_("translate_to_your_language"),
        pagination=["submitlink","submitlink",2,2],
        lang=lang_edit,
        forml=forml,
        form=form,
        pname="translate",
        msgids=msgids,
        complete=round(((total-no_translation)/total)*100,2))
Beispiel #6
0
def db_confirm(collection, document_id=None):
    """
    Confirmación de edición de base de datos
    """
    page = request.args.get("page", 0, int)
    grps = request.args.get("mode", "all", str)
    mode = request.args.get("show", "current", str)
    size = request.args.get("size", 15, int)

    goback = lambda: redirect(url_for(url_id, page=page, mode=grps, show=mode, size=size))

    document = json.loads(request.form.get("defaults"))
    document_writeable = json.loads(request.form.get("editable"))

    request_form_dict = MultiDict(request.form)

    success_msgid = "admin_saved"
    unchanged_msgid = "admin_nochanges"

    if collection == "user":
        page_title = "admin_users"
        form_title = "admin_users_info"
        success_msgid = "admin_users_updated"
        url_id = "admin.users"
        save_fnc = lambda data: usersdb.update_user(data)
        new_password = request_form_dict.pop(db_fnm("new password"), None)
        if new_password:
            document_writeable.append("password")
            request_form_dict[db_fnm("password")] = new_password
    elif collection == "origin":
        page_title = "admin_origins_info"
        form_title = "admin_origins_info"
        url_id = "admin.origins"
        save_fnc = lambda data: filesdb.update_source(data)

    if request.form.get("confirmed", "False") == "True":
        # La petición ha sido realizada por el formulario de confirmación,
        # lo procesamos.
        check_form = expanded_instance(
            EditForm, {db_fnm(k): BooleanField(k) for k in document_writeable}, request_form_dict
        )
        data = {k: document[k] for k in document_writeable if check_form[db_fnm(k)].data}
        if data:
            data["_id"] = hex2mid(document_id)
            save_fnc(data)
            flash(success_msgid, "success")
            return goback()
        else:
            flash(unchanged_msgid, "error")
            return goback()
    else:
        # No se trata del petición confirmada, procesamos el formulario como
        # viene de db_edit, generamos el formulario de confirmación.

        edit_form = expanded_instance(
            EditForm,
            {db_fnm(k): TextField(k, default=db_dtf(collection, k, document[k])) for k in document_writeable},
            request_form_dict,
        )
        document_changes = [
            (k, document[k], db_ftd(collection, k, edit_form[db_fnm(k)].data))
            for k in document_writeable
            if edit_form[db_fnm(k)].data != db_dtf(collection, k, document[k])
        ]
        if document_changes:
            check_form = expanded_instance(
                EditForm, {db_fnm(k): BooleanField(k, default=False) for k, w, w in document_changes}
            )
            check_form.defaults.data = json.dumps({k: v for k, w, v in document_changes})
            check_form.editable.data = json.dumps([k for k, w, v in document_changes])
            check_form.confirmed.data = True
        else:
            flash(unchanged_msgid, "error")
            return goback()

    return render_template(
        "admin/confirm.html",
        collection=collection,
        document_id=document_id,
        title=admin_title(page_title),
        page_title=_(page_title),
        check_form=check_form,
        form_title=_(form_title),
        fieldname=db_fnm,
        repr=repr,
        document_changes=document_changes,
        list_mode=grps,
        mode=mode,
        page_size=size,
        page=page,
    )
Beispiel #7
0
def db_edit(collection, document_id=None):
    """
    Edición de base de datos
    """
    page = request.args.get("page", 0, int)
    grps = request.args.get("mode", "all", str)
    mode = request.args.get("show", "current", str)
    size = request.args.get("size", 15, int)

    page_title = "admin_edit"
    form_title = "admin_edit"
    data = None

    form_force_fields = ()
    form_readonly_fields = ("_id",)
    document = {}
    if collection == "user":
        page_title = "admin_users"
        form_title = "admin_users_info"
        form_force_fields += (
            "karma",
            "token",
            "username",
            "email",
            "new password",
            "lang",
            "location",
            "karma",
            "active",
            "type",
            "oauthid",
        )
        form_readonly_fields += ("created", "password")
        data = usersdb.find_userid(document_id) if document_id else {}
    elif collection == "origin":
        page_title = "admin_origins_info"
        form_title = "admin_origins_info"
        form_force_fields += ("tb", "crbl", "d", "g")
        # form_readonly_fields += ()
        data = filesdb.get_source_by_id(float(document_id)) if document_id else {}
    else:
        abort(500)

    document.update((i, db_ftd(collection, i, "")) for i in form_force_fields)
    document.update(data)

    document_defaults = {fjson(i): fjson(j) for i, j in document.iteritems()}
    document_writeable = [k for k in document.iterkeys() if k not in form_readonly_fields]

    edit_form = expanded_instance(
        EditForm,
        {db_fnm(k): TextField(k, default=db_dtf(collection, k, document[k])) for k in document_writeable},
        request.form,
    )

    edit_form.defaults.data = json.dumps(document_defaults)
    edit_form.editable.data = json.dumps(document_writeable)

    return render_template(
        "admin/edit.html",
        collection=collection,
        document_id=document_id,
        title=admin_title(page_title),
        page_title=_(page_title),
        edit_form=edit_form,
        form_title=_(form_title),
        fieldname=db_fnm,
        document_writeable=[(k, document[k]) for k in document_writeable],
        document_readonly=[(k, document[k]) for k in document if not k in document_writeable],
        list_mode=grps,
        mode=mode,
        page_size=size,
        page=page,
    )
Beispiel #8
0
def review_translation(translation_id):
    """
    Formulario de revisión de traducción
    """
    page = request.args.get("page", 0, int)
    mode = request.args.get("show", "old", str)
    size = request.args.get("size", 15, int)
    select = request.args.get("select", "default", str)

    # Optimización: si envío en un campo la lista de strids, no la pido a BBDD
    data = None
    if request.form.get("field_keys", None):
        data_fields = {
            i: "" for i in request.form.get("fields").replace("&sbquo;", ",").replace("&amp;", "&").split(",")
        }
    else:
        data = pagesdb.get_translation(translation_id)
        data_fields = data["texts"]

    def denuke(o):
        """Evita nukeos de msgstrs malformados"""
        try:
            return _(o)  # TODO: Investigar porqué esto hace falta
        except:
            return o

    # Campos de traducción
    fields = {
        "field_%s" % key: TextAreaField(key, default=value, description=denuke(key))
        if len(value) > 40
        else TextField(key, default=value, description=denuke(key))
        for key, value in data_fields.iteritems()
    }

    # Checkboxes
    fields.update(("check_%s" % key, BooleanField(default=(select == all))) for key in data_fields.iterkeys())

    form = expanded_instance(ValidateTranslationForm, fields, request.form, prefix="translation_")

    # Guardo en el Hiddenfield la lista de strids
    form.field_keys = "&".join(i.replace("&", "&amp;").replace(",", "&sbquo;") for i in data_fields.iterkeys())

    if request.method == "POST" and form.validate():
        if form.submit.data:
            pomanager.update_lang(
                data["dest_lang"],
                {key: form["field_%s" % key].data for key in data_fields.iterkeys() if form["check_%s" % key].data},
            )
        pagesdb.update_translation({"_id": translation_id, "processed": True})
        return redirect(url_for("admin.translations", page=page, mode=mode, size=size))
    elif data is None:
        # Si no he pedido a base de datos la traducción por optimizar
        data = pagesdb.get_translation(translation_id)

    dest_lang = {key: value for key, value in pomanager.get_lang(data["dest_lang"]).iteritems() if key in data["texts"]}

    user_lang_path = lang_path(data["user_lang"])
    user_lang = (
        {i.msgid: i.msgstr for i in polib.pofile(user_lang_path) if i.msgid in data["texts"]} if user_lang_path else {}
    )

    def try_current(o):
        try:
            return _(o)
        except:
            return None

    translation = {
        key: (
            user_lang[key] if key in user_lang else None,
            dest_lang[key] if key in dest_lang else None,
            try_current(key),
        )
        for key, value in data.pop("texts").iteritems()
    }

    return render_template(
        "admin/translation_review.html",
        page_title=_("admin_translation_review"),
        title=admin_title("admin_translation_review"),
        form=form,
        select=select,
        data=data,
        page=page,
        list_mode=mode,
        page_size=size,
        field_keys=",".join(translation.iterkeys()),
        fields=translation,
    )