Ejemplo n.º 1
0
def edit():
    if request.method == "GET":
        appid = request.args.get("appid")
        if not appid:
            return "appid not provided", 400
        app = appstorage.get_app(appid)
        if app is None:
            return "App not found", 500

        data = json.loads(app.data)
        text = data["text"]

        return render_template("composers/dummy/edit.html", app=app, text=text)
    elif request.method == "POST":
        appid = request.form["appid"]
        text = request.form["text"]

        # Retrieve the app we're editing by its id.
        app = appstorage.get_app(appid)

        # Build our dummy composer JSON.
        data = {"dummy_version": 1, "text": text}

        appstorage.update_app_data(app, data)

        flash(gettext("Saved successfully"), "success")

        # TODO: Print a success message etc etc.

        # If the user clicked on saveexit we redirect to appview, otherwise
        # we stay here.
        if "saveexit" in request.form:
            return redirect(url_for("user.apps.index"))

        return render_template("composers/dummy/edit.html", app=app, text=text)
Ejemplo n.º 2
0
    def test_data_save(self):
        data = {"MYNAME": "TEST"}
        api.update_app_data(self.tapp, json.dumps(data))

        recdata = api.get_app_by_name("UTApp").data
        pdata = json.loads(recdata)

        assert data == pdata
    def test_data_save(self):
        data = {"MYNAME": "TEST"}
        api.update_app_data(self.tapp, json.dumps(data))

        recdata = api.get_app_by_name("UTApp").data
        pdata = json.loads(recdata)

        assert data == pdata
Ejemplo n.º 4
0
def do_languages_initial_merge(app, bm):
    """
    Carries out an initial merge. Bundles from the language-owners are merged into the
    app.
    @param app: Target app. App into which the bundles of each language owner are merged.
    @param bm: Target BundleManager. Bundle manager into which the bundles of each language owner are merged.
    @note: The App's data is updated automatically to reflect the new merge.
    """

    # Retrieve every single "owned" App for that xmlspec.
    ownerships = _db_get_ownerships(bm.get_gadget_spec())

    for ownership in ownerships:
        language = ownership.value
        ownerapp = ownership.app
        bm.merge_language(language, ownerapp)

    update_app_data(app, bm.to_json())
Ejemplo n.º 5
0
def edit():
    if request.method == "GET":
        appid = request.args.get("appid")
        if not appid:
            return "appid not provided", 400
        app = appstorage.get_app(appid)
        if app is None:
            return "App not found", 500

        data = json.loads(app.data)
        text = data["text"]

        return render_template("composers/dummy/edit.html", app=app, text=text)
    elif request.method == "POST":
        appid = request.form["appid"]
        text = request.form["text"]

        # Retrieve the app we're editing by its id.
        app = appstorage.get_app(appid)

        # Build our dummy composer JSON.
        data = {
            "dummy_version": 1,
            "text": text}

        appstorage.update_app_data(app, data)

        flash(gettext("Saved successfully"), "success")

        # TODO: Print a success message etc etc.

        # If the user clicked on saveexit we redirect to appview, otherwise
        # we stay here.
        if "saveexit" in request.form:
            return redirect(url_for("user.apps.index"))

        return render_template("composers/dummy/edit.html", app=app, text=text)
Ejemplo n.º 6
0
def translate_edit():
    """
    Translation editor for the selected language.

    @note: Returns error 400 if the source language or group don't exist.
    """

    # No matter if we are handling a GET or POST, we require these parameters.
    appid = request.values.get("appid")
    srclang = request.values.get("srclang")
    targetlang = request.values.get("targetlang")
    srcgroup = request.values.get("srcgroup")
    targetgroup = request.values.get("targetgroup")

    # Retrieve the application we want to view or edit.
    app = get_app(appid)
    if app is None:
        return render_template("composers/errors.html", message=gettext("App not found")), 404

    bm = BundleManager.create_from_existing_app(app.data)
    spec = bm.get_gadget_spec()

    # Retrieve the bundles for our lang. For this, we build the code from the info we have.
    srcbundle_code = BundleManager.partialcode_to_fullcode(srclang, srcgroup)
    targetbundle_code = BundleManager.partialcode_to_fullcode(targetlang, targetgroup)

    srcbundle = bm.get_bundle(srcbundle_code)

    # Ensure the existence of the source bundle.
    if srcbundle is None:
        return render_template("composers/errors.html",
                               message=gettext("The source language and group combination does not exist")), 400

    targetbundle = bm.get_bundle(targetbundle_code)

    # The target bundle doesn't exist yet. We need to create it ourselves.
    if targetbundle is None:
        splits = targetlang.split("_")
        if len(splits) == 2:
            lang, country = splits
            targetbundle = Bundle(lang, country, targetgroup)
            bm.add_bundle(targetbundle_code, targetbundle)

    # Get the owner for this target language.
    owner_app = _db_get_lang_owner_app(spec, targetlang)

    # If the language has no owner, we declare ourselves as owners.
    if owner_app is None:
        _db_declare_ownership(app, targetlang)
        owner_app = app

    # We override the standard Ownership's system is_owner.
    # TODO: Verify that this doesn't break anything.
    is_owner = owner_app == app

    # Get the language names
    target_translation_name = targetbundle.get_readable_name()
    source_translation_name = srcbundle.get_readable_name()

    # This is a GET request. We are essentially viewing-only.
    if request.method == "GET":
        pass

    # This is a POST request. We need to save the entries.
    else:

        # Protect against CSRF attacks.
        if not verify_csrf(request):
            return render_template("composers/errors.html",
                                   message=gettext("Request does not seem to come from the right source (csrf check)")), 400

        # Retrieve a list of all the key-values to save. That is, the parameters which start with _message_.
        messages = [(k[len("_message_"):], v) for (k, v) in request.values.items() if k.startswith("_message_")]

        # Save all the messages we retrieved from the POST or GET params into the Bundle.
        for identifier, msg in messages:
            if len(msg) > 0:  # Avoid adding empty messages.
                targetbundle.add_msg(identifier, msg)

        # Now we need to save the changes into the database.
        json_str = bm.to_json()
        update_app_data(app, json_str)

        flash(gettext("Changes have been saved."), "success")

        propose_to_owner = request.values.get("proposeToOwner")
        if propose_to_owner is not None and owner_app != app:

            # Normally we will add the proposal to the queue. However, sometimes the owner wants to auto-accept
            # all proposals. We check for this. If the autoaccept mode is enabled on the app, we do the merge
            # right here and now.
            obm = BundleManager.create_from_existing_app(owner_app.data)
            if obm.get_autoaccept():
                flash(gettext("Changes are being applied instantly because the owner has auto-accept enabled"))

                # Merge into the owner app.
                obm.merge_bundle(targetbundle_code, targetbundle)

                # Now we need to update the owner app's data. Because we aren't the owners, we can't use the appstorage
                # API directly.
                owner_app.data = obm.to_json()
                db.session.add(owner_app)
                db.session.commit()

                # [Context: We are not the leading Bundles, but our changes are merged directly into the leading Bundle]
                # We report the change to a "leading" bundle.
                on_leading_bundle_updated(spec, targetbundle)

            else:

                # We need to propose this Bundle to the owner.
                # Note: May be confusing: app.owner.login refers to the generic owner of the App, and not the owner
                # we are talking about in the specific Translate composer.
                proposal_data = {"from": app.owner.login, "timestamp": time.time(), "bundle_code": targetbundle_code,
                                 "bundle_contents": targetbundle.to_jsonable()}

                proposal_json = json.dumps(proposal_data)

                # Link the proposal with the Owner app.
                add_var(owner_app, "proposal", proposal_json)

                flash(gettext("Changes have been proposed to the owner"))

        # If we are the owner app.
        if owner_app == app:
            # [Context: We are the leading Bundle]
            # We report the change.
            on_leading_bundle_updated(spec, targetbundle)

        # Check whether the user wants to exit or to continue editing.
        if "save_exit" in request.values:
            return redirect(url_for("user.apps.index"))




    return render_template("composers/translate/edit.html", is_owner=is_owner, app=app, srcbundle=srcbundle,
                           targetbundle=targetbundle, spec=spec, target_translation_name=target_translation_name,
                           source_translation_name=source_translation_name)
Ejemplo n.º 7
0
 def save_data(self, app_id, data):
     """ Wrapper of the appstorage API. It saves the data in JSON format. """
     app = appstorage.get_app(app_id)
     appstorage.update_app_data(app, data)
Ejemplo n.º 8
0
def translate_proposed_list():
    """
    Displays the list of proposed translations.
    """

    # No matter if we are handling a GET or POST, we require these parameters.
    appid = request.values["appid"]
    app = get_app(appid)

    appdata = json.loads(app.data)

    # TODO: !!!!! THIS IS MISSING AND IS IMPORTANT !!!!!

    # Ensure that only the app owner can carry out these operations.
    # owner_app = _db_get_owner_app(appdata["spec"])
    # if app != owner_app:
    #    return render_template("composers/errors.html",
    #                           message="Not Authorized: You don't seem to be the owner of this app")

    # Get the list of proposed translations.
    proposal_vars = _db_get_proposals(app)
    proposed_translations = []
    for prop in proposal_vars:
        propdata = json.loads(prop.value)
        propdata["id"] = str(prop.var_id)
        proposed_translations.append(propdata)

    # If we received a POST with acceptButton set then we will need to merge the
    # proposal.
    if request.method == "POST" and request.values.get("acceptButton") is not None:
        proposal_id = request.values.get("proposals")
        if proposal_id is None:
            return render_template("composers/errors.html", message=gettext("Proposal not selected"))

        merge_data = request.values.get("data")
        if merge_data is None:
            return render_template("composers/errors.html", message=gettext("Merge data was not provided"))
        merge_data = json.loads(merge_data)

        # TODO: Optimize this. We already have the vars.
        proposal = AppVar.query.filter_by(app=app, var_id=proposal_id).first()
        if proposal is None:
            return render_template("composers/errors.html", message=gettext("Proposals not found"))

        data = json.loads(proposal.value)
        bundle_code = data["bundle_code"]

        proposed_bundle = Bundle.from_messages(merge_data, bundle_code)

        bm = BundleManager.create_from_existing_app(app.data)
        bm.merge_bundle(bundle_code, proposed_bundle)

        update_app_data(app, bm.to_json())

        flash(gettext("Merge done."), "success")

        # Remove the proposal from the DB.
        remove_var(proposal)

        # Remove it from our current proposal list as well, so that it isn't displayed anymore.
        proposed_translations = [prop for prop in proposed_translations if prop["id"] != proposal_id]

    # The DENY button was pressed. We have to discard the whole proposal.
    elif request.method == "POST" and request.values.get("denyButton") is not None:
        proposal_id = request.values.get("proposals")
        if proposal_id is None:
            return render_template("composers/errors.html", message=gettext("Proposal not selected"))

        proposal = AppVar.query.filter_by(app=app, var_id=proposal_id).first()
        if proposal is None:
            return render_template("composers/errors.html", message=gettext("Proposal not found"))

        remove_var(proposal)

        # Remove it from our current proposal list as well, so that it isn't displayed anymore.
        proposed_translations = [prop for prop in proposed_translations if prop["id"] != proposal_id]

    return render_template("composers/translate/proposed_list.html", app=app, proposals=proposed_translations)
Ejemplo n.º 9
0
 def save_data(self, app_id, data):
     """ Wrapper of the appstorage API. It saves the data in JSON format. """
     app = appstorage.get_app(app_id)
     appstorage.update_app_data(app, data)