コード例 #1
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def update_app_data(composed_app, data):
    """
    update_app_data(composed_app, data)
    Updates the App's composer-specific data.

    @param composed_app: Either the App object itself, or a string containing the app-id.
    @param data: Data to update the app with. Either a JSON-able dictionary, or a JSON string.

    @note: This function can only be used by logged-on users, and they must be the
    owners of the app being saved.
    """

    # Convert ID to App if not done already (otherwise it's NOP).
    composed_app = _get_app_obj(composed_app)

    # TODO: Remove this
    # As a preliminary step towards db migration, we remove bundles information which may be present in the data.
    if type(data) is str or type(data) is unicode:
        data = json.loads(data)

    if type(data) is not str and type(data) is not unicode:
        if "bundles" in data:
            del data["bundles"]
        data = json.dumps(data)

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    composed_app.data = data
    composed_app.modification_date = composed_app.last_access_date = datetime.datetime.utcnow()

    db.session.add(composed_app)
    db.session.commit()
コード例 #2
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def update_app_data(composed_app, data):
    """
    update_app_data(composed_app, data)
    Updates the App's composer-specific data.

    @param composed_app: Either the App object itself, or a string containing the app-id.
    @param data: Data to update the app with. Either a JSON-able dictionary, or a JSON string.

    @note: This function can only be used by logged-on users, and they must be the
    owners of the app being saved.
    """

    # Convert ID to App if not done already (otherwise it's NOP).
    composed_app = _get_app_obj(composed_app)

    # TODO: Remove this
    # As a preliminary step towards db migration, we remove bundles information which may be present in the data.
    if type(data) is str or type(data) is unicode:
        data = json.loads(data)

    if type(data) is not str and type(data) is not unicode:
        if "bundles" in data:
            del data["bundles"]
        data = json.dumps(data)

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    composed_app.data = data
    composed_app.modification_date = composed_app.last_access_date = datetime.datetime.utcnow(
    )

    db.session.add(composed_app)
    db.session.commit()
コード例 #3
0
def transfer_ownership():

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

    # 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

    # Make sure the logged in user owns the app.
    user = current_user()
    if app.owner != user:
        return render_template("composers/errors.html", message=gettext("Not Authorized: User does not own app")), 403

    # Get the XMLSPEC
    bm = BundleManager.create_from_existing_app(app.data)
    spec = bm.get_gadget_spec()

    # Get the language
    lang = request.values.get("lang")
    if lang is None:
        return render_template("composers/errors.html", message=gettext("Lang not specified")), 400

    # Verify that we are the owners of the language we are trying to transfer.
    owner_app = _db_get_lang_owner_app(spec, lang)
    if owner_app != app:
        return render_template("composers/errors.html", message=gettext("Not Authorized: App does not own language")), 403

    # Get the possible apps to which we can concede ownership.
    apps = _db_get_spec_apps(spec)
    apps = [a for a in apps if a != app]

    # We received a POST request. We need to transfer the ownership.
    if request.method == "POST":

        # 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

        # Verify that we were passed the target app.
        targetapp = get_app(request.values.get("transfer"))
        if targetapp is None:
            return render_template("composers/errors.html", message=gettext("Target app not specified")), 400

        # Verify that the target app is of the same spec.
        targetappdata = json.loads(targetapp.data)
        targetspec = targetappdata["spec"]
        if targetspec != spec:
            return render_template("composers/errors.html", message=gettext("Target app does not have the same spec")), 400

        # Carry out the transfer.
        _db_transfer_ownership(lang, app, targetapp)

        # Redirect to selectlang.
        return redirect(url_for("translate.translate_selectlang", appid=app.unique_id))

    # For GET
    return render_template("composers/translate/transfer_ownership.html", app=app, apps=apps, xmlspec=spec, lang=lang)
コード例 #4
0
ファイル: api.py プロジェクト: zstars/appcomposer
def update_app_data(composed_app, data):
    """
    update_app_data(composed_app, data)
    Updates the App's composer-specific data.

    @param composed_app: Either the App object itself, or a string containing the app-id.
    @param data: Data to update the app with. Either a JSON-able dictionary, or a JSON string.

    @note: This function can only be used by logged-on users, and they must be the
    owners of the app being saved.
    """

    # Convert ID to App if not done already (otherwise it's NOP).
    composed_app = _get_app_obj(composed_app)

    if type(data) is not str and type(data) is not unicode:
        data = json.dumps(data)

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    composed_app.data = data
    composed_app.modification_date = composed_app.last_access_date = datetime.datetime.utcnow()

    db.session.add(composed_app)
    db.session.commit()
コード例 #5
0
ファイル: __init__.py プロジェクト: zstars/appcomposer
def new():
    next_url = request.args.get('next', '') or request.form.get('next', '')
    name = request.args.get("name")
    if name is None:
        return "Missing parameter: name", 400
    owner = current_user()
    app = create_app(name, owner, "dummy", "{'message':'Hello world'}")
    return "Application created"
コード例 #6
0
def adapt_type_selection():
    """
    adapt_type_selection()
    Loads the page that lets the user choose the adaptation type, and that lets the user view or duplicate
    an existing adaptation instead. This method DOES NOT REQUIRE LOGIN but will display a different view when
    not logged in.
    """

    # Check if we are logged in.
    logged_in = current_user() is not None

    # If we are not logged in disallow POST.
    if not logged_in and request.method == "POST":
        return render_template("composers/errors.html", message=gettext("Cannot POST to this URL if not logged in")), 403

    # We require the appurl parameter.
    appurl = request.values.get("appurl")
    if appurl is None:
        return render_template("composers/errors.html", message=gettext("appurl parameter not specified"))

    # Obtain a list of every adaptation that exists in the database for the specified appurl.
    # TODO: Move db_helpers somewhere else. Makes no sense to use translator files in the adaptor.
    apps_list = _db_get_spec_apps(appurl)
    apps = []
    for app in apps_list:
        if app.composer != "adapt":
            continue
        apps.append({
            "name": app.name,
            "desc": app.description,
            "owner": app.owner.name,
            "type": "adapt",  # TO-DO: Specify the specific adaptor sub-type.
            "app_id": app.unique_id
        })

    # We will only get here if we are logged in
    if request.method == "POST":

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

        adaptor_type = request.form["adaptor_type"]

        if adaptor_type and adaptor_type in ADAPTORS:
            # In order to show the list of apps we redirect to other url
            return redirect(url_for("adapt.adapt_create", adaptor_type=adaptor_type))
        else:
            # An adaptor_type is required.
            flash("Invalid adaptor type", "error")

    if logged_in:
        return render_template("composers/adapt/type.html", adaptors=ADAPTORS, apps=apps)

    # Version for the public
    else:
        return render_template("composers/adapt/public_type.html", adaptors=ADAPTORS, apps=apps)
コード例 #7
0
    def test_create_app(self):
        app = api.create_app("UTApp", "dummy", None, "{}")
        assert app is not None
        assert app.name == "UTApp"

        id = app.unique_id  # TODO: Probably no point for App to have two different unique ids.
        app = None
        app = api.get_app(id)
        assert app is not None
        assert app.name == "UTApp"
        assert app.owner == current_user()
コード例 #8
0
    def index(self):
        """
        index(self)
        
        This method will be invoked for the Profile Edit view. This view is used for both viewing and updating
        the user profile. It exposes both GET and POST, for viewing and updating respectively.
        """

        # This will be passed as a template parameter to let us change the password.
        # (And display the appropriate form field).
        change_password = True

        user = current_user()
        if user is None:
            return redirect("login")

        # If it is a POST request to edit the form, then request.form will not be None
        # Otherwise we will simply load the form data from the DB
        if len(request.form):
            form = ProfileEditForm(request.form, csrf_enabled=True)
        else:
            # It was a GET request (just viewing).
            form = ProfileEditForm(csrf_enabled=True)
            form.name.data = user.name
            form.login.data = user.login
            form.email.data = user.email
            form.organization.data = user.organization
            form.role.data = user.role
            form.creation_date.data = user.creation_date
            form.last_access_date.data = user.last_access_date
            form.auth_system.data = user.auth_system
            form.password.data = user.auth_data

        # If the method is POST we assume that we want to update and not just view
        if request.method == "POST" and form.validate_on_submit():
            # It was a POST request, the data (which has been modified) will be contained in
            # the request. For security reasons, we manually modify the user for these
            # settings which should actually be modifiable.
            user.email = form.email.data
            user.organization = form.organization.data
            user.role = form.role.data
            user.auth_type = form.auth_system.data  # Probably in the release we shouldn't let users modify the auth this way
            if len(form.password.data) > 0:
                new_password_data = create_salted_password(form.password.data)
                user.auth_data = new_password_data
            db.session.add(user)
            db.session.commit()

            flash("Changes saved", "success")

        return self.render("user/profile-edit.html",
                           user=user,
                           form=form,
                           change_password=change_password)
コード例 #9
0
    def test_create_app(self):
        app = api.create_app("UTApp", "dummy", "{}")
        assert app is not None
        assert app.name == "UTApp"

        id = app.unique_id  # TODO: Probably no point for App to have two different unique ids.
        app = None
        app = api.get_app(id)
        assert app is not None
        assert app.name == "UTApp"
        assert app.owner == current_user()
コード例 #10
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def get_my_apps(**filters):
    """
    get_my_apps(**filters)
    Retrieves the current user's app with a specified set of filters for the AppVars. For example:

    get_my_apps(adaptor_type = 'composer') will only return those apps of the user which match that.

    @note: This function can only be used by logged-on users.
    """
    user = current_user()

    if filters:
        app_vars_query_obj = db.session.query(AppVar.app_id)
        for filter_name, filter_value in filters.iteritems():
            app_vars_query_obj = app_vars_query_obj.filter_by(name=filter_name, value=filter_value)

        subquery = app_vars_query_obj.subquery()

        return App.query.filter(App.id.in_(subquery), App.owner == current_user()).all()
    else:
        return App.query.filter(App.owner == current_user()).all()
コード例 #11
0
ファイル: api.py プロジェクト: zstars/appcomposer
def create_app(name, composer, data, find_new_name=False, description = None):
    """
    create_app(name, data)
    @param name: Unique name to give to the application.
    @param composer: Composer identifier.
    @param data: JSON-able dictionary with the composer-specific data, or the JSON string itself.
    @return: The app that has been created.

    @note: This function can be used by any logged-on user. There are no restrictions other than
    unique (name, owner) combination.
    """

    # Get the current user, who will be the owner of our app.
    owner = current_user()

    # To try to create an app we need to be logged in.
    if owner is None:
        raise NotAuthorizedException("User is not logged in")

    # If the composer-specific data is already a string, we assume
    # it is JSON'ed already.
    if type(data) is not str and type(data) is not unicode:
        data = json.dumps(data)

    # Check if an app with that name and owner exists already.
    existing_app = App.query.filter_by(owner=owner, name=name).first()
    if existing_app is not None:
        if find_new_name:
            MAX = 10000
            counter = 2
            while counter < MAX:
                new_name = '%s (%s)' % (name, counter)
                existing_app = App.query.filter_by(owner=owner, name=new_name).first()
                if existing_app is None:
                    name = new_name
                    break

                counter += 1
            if counter == MAX:
                raise AppExistsException()
        else:
            raise AppExistsException()

    # Create it
    new_app = App(name, owner, composer, description = description)
    new_app.data = data

    # Insert the new app into the database
    db.session.add(new_app)
    db.session.commit()

    return new_app
コード例 #12
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def get_app_by_name(app_name):
    """
    get_app_by_name(app_name)
    Retrieves the current user's app with the specified name.

    @param app_name: Name of the application. Will be unique within the list of user's apps.
    @return: The app if found, None otherwise.

    @note: This function can only be used by logged-on users.
    """
    user = current_user()
    retrieved_app = App.query.filter_by(owner=user, name=app_name).first()
    return retrieved_app
コード例 #13
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def get_app_by_name(app_name):
    """
    get_app_by_name(app_name)
    Retrieves the current user's app with the specified name.

    @param app_name: Name of the application. Will be unique within the list of user's apps.
    @return: The app if found, None otherwise.

    @note: This function can only be used by logged-on users.
    """
    user = current_user()
    retrieved_app = App.query.filter_by(owner=user, name=app_name).first()
    return retrieved_app
コード例 #14
0
    def index(self):
        """
        index(self)
        
        This method will be invoked for the Profile Edit view. This view is used for both viewing and updating
        the user profile. It exposes both GET and POST, for viewing and updating respectively.
        """

        # This will be passed as a template parameter to let us change the password.
        # (And display the appropriate form field).
        change_password = True

        user = current_user()
        if user is None:
            return redirect("login")

        # If it is a POST request to edit the form, then request.form will not be None
        # Otherwise we will simply load the form data from the DB
        if len(request.form):
            form = ProfileEditForm(request.form, csrf_enabled=True)
        else:
            # It was a GET request (just viewing). 
            form = ProfileEditForm(csrf_enabled=True)
            form.name.data = user.name
            form.login.data = user.login
            form.email.data = user.email
            form.organization.data = user.organization
            form.role.data = user.role
            form.creation_date.data = user.creation_date
            form.last_access_date.data = user.last_access_date
            form.auth_system.data = user.auth_system
            form.password.data = user.auth_data

        # If the method is POST we assume that we want to update and not just view
        if request.method == "POST" and form.validate_on_submit():
            # It was a POST request, the data (which has been modified) will be contained in
            # the request. For security reasons, we manually modify the user for these
            # settings which should actually be modifiable.
            user.email = form.email.data
            user.organization = form.organization.data
            user.role = form.role.data
            user.auth_type = form.auth_system.data  # Probably in the release we shouldn't let users modify the auth this way
            if len(form.password.data) > 0:
                new_password_data = create_salted_password(form.password.data)
                user.auth_data = new_password_data
            db.session.add(user)
            db.session.commit()

            flash("Changes saved", "success")

        return self.render("user/profile-edit.html", user=user, form=form, change_password=change_password)
コード例 #15
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def get_my_apps(**filters):
    """
    get_my_apps(**filters)
    Retrieves the current user's app with a specified set of filters for the AppVars. For example:

    get_my_apps(adaptor_type = 'composer') will only return those apps of the user which match that.

    @note: This function can only be used by logged-on users.
    """
    user = current_user()

    if filters:
        app_vars_query_obj = db.session.query(AppVar.app_id)
        for filter_name, filter_value in filters.iteritems():
            app_vars_query_obj = app_vars_query_obj.filter_by(
                name=filter_name, value=filter_value)

        subquery = app_vars_query_obj.subquery()

        return App.query.filter(App.id.in_(subquery),
                                App.owner == current_user()).all()
    else:
        return App.query.filter(App.owner == current_user()).all()
コード例 #16
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def save_app(composed_app):
    """
    save_app(app)
    Saves the App object to the database. Useful when the object has been
    modified.
    @param app: App object
    @return: None.

    @note: This function can only be used by logged on users, and they must
    be the owners of the app being saved.
    """

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    composed_app.modification_date = composed_app.last_access_date = datetime.datetime.utcnow()

    db.session.add(composed_app)
    db.session.commit()
コード例 #17
0
ファイル: view_preview.py プロジェクト: gengivan/appcomposer
def adapt_preview(appid):
    """
    adapt_preview(appid)
    Previews an application. You can preview the app of any user.
    # TODO: Eventually the preview feature should probably be merged into view_edit, through a read-only mode.
    LOGIN IS OPTIONAL FOR THIS METHOD.
    @param appid: Appid of the app to preview.
    """
    if not appid:
        return render_template("composers/errors.html", message=gettext("appid not provided")), 400

    # Check whether we are logged in.
    logged_in = current_user() is not None

    # TODO: Improve this: do not load the whole thing. We just need the variables.
    app = appstorage.get_app(appid)
    if app is None:
        return render_template("composers/errors.html", message=gettext("app not found")), 500

    adaptor_types = [var for var in app.appvars if var.name == 'adaptor_type']
    if not adaptor_types:
        return render_template("composers/errors.html", message=gettext("Error: no attached adaptor_type variable")), 500
    adaptor_type = adaptor_types[0].value

    if adaptor_type not in ADAPTORS:
        return render_template("composers/errors.html", message=gettext("Error: adaptor %s not currently supported") % adaptor_type), 500

    adaptor_plugin = ADAPTORS[adaptor_type]['adaptor']


    # TODO: URLs seem to be dependent on adaptor type. This is meant to work with jsconfig at least.

    # Calculate the URL for the Preview iframe.
    app_url = url_for('%s.app_xml' % adaptor_type, app_id=appid, _external=True)
    preview_url = shindig_url("/gadgets/ifr?nocache=1&url=%s" % app_url)

    # Retrieve the URL from the appdata.
    appdata = json.loads(app.data)
    spec_url = appdata["url"]


    return render_template("composers/adapt/preview.html", logged_in=logged_in, app_id=appid, app_url=app_url, spec_url=spec_url, name=app.name, preview_url=preview_url)
コード例 #18
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def save_app(composed_app):
    """
    save_app(app)
    Saves the App object to the database. Useful when the object has been
    modified.
    @param app: App object
    @return: None.

    @note: This function can only be used by logged on users, and they must
    be the owners of the app being saved.
    """

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    composed_app.modification_date = composed_app.last_access_date = datetime.datetime.utcnow(
    )

    db.session.add(composed_app)
    db.session.commit()
コード例 #19
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def delete_app(composed_app):
    """
    delete_app(composed_app)
    @param composed_app: The app that we want to delete. It can either be the app object itself or an app-id.
    @return: nothing.

    @note: This function can only be used by logged-on users, and they must be the owners of
    the app being saved.
    """

    composed_app = _get_app_obj(composed_app)

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    # Delete every AppVar for that App. Otherwise, as of now, deletion doesn't work because
    # the delete cascade on the relationship has some problem.
    # TODO: Fix me.
    AppVar.query.filter_by(app=composed_app).delete()

    db.session.delete(composed_app)
    db.session.commit()
コード例 #20
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def delete_app(composed_app):
    """
    delete_app(composed_app)
    @param composed_app: The app that we want to delete. It can either be the app object itself or an app-id.
    @return: nothing.

    @note: This function can only be used by logged-on users, and they must be the owners of
    the app being saved.
    """

    composed_app = _get_app_obj(composed_app)

    if composed_app.owner != current_user():
        raise NotAuthorizedException()

    # Delete every AppVar for that App. Otherwise, as of now, deletion doesn't work because
    # the delete cascade on the relationship has some problem.
    # TODO: Fix me.
    AppVar.query.filter_by(app=composed_app).delete()

    db.session.delete(composed_app)
    db.session.commit()
コード例 #21
0
def adapt_type_selection():
    """
    adapt_type_selection()
    Loads the page that lets the user choose the adaptation type, and that lets the user view or duplicate
    an existing adaptation instead. This method DOES NOT REQUIRE LOGIN but will display a different view when
    not logged in.
    """

    # Check if we are logged in.
    logged_in = current_user() is not None

    # If we are not logged in disallow POST.
    if not logged_in and request.method == "POST":
        return render_template(
            "composers/errors.html",
            message=gettext("Cannot POST to this URL if not logged in")), 403

    # We require the appurl parameter.
    appurl = request.values.get("appurl")
    if appurl is None:
        return render_template(
            "composers/errors.html",
            message=gettext("appurl parameter not specified"))

    # Obtain a list of every adaptation that exists in the database for the specified appurl.
    # TODO: Move db_helpers somewhere else. Makes no sense to use translator files in the adaptor.
    apps_list = _db_get_spec_apps(appurl)
    apps = []
    for app in apps_list:
        if app.composer != "adapt":
            continue
        apps.append({
            "name": app.name,
            "desc": app.description,
            "owner": app.owner.name,
            "type": "adapt",  # TO-DO: Specify the specific adaptor sub-type.
            "app_id": app.unique_id
        })

    # We will only get here if we are logged in
    if request.method == "POST":

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

        adaptor_type = request.form["adaptor_type"]

        if adaptor_type and adaptor_type in ADAPTORS:
            # In order to show the list of apps we redirect to other url
            return redirect(
                url_for("adapt.adapt_create", adaptor_type=adaptor_type))
        else:
            # An adaptor_type is required.
            flash("Invalid adaptor type", "error")

    if logged_in:
        return render_template("composers/adapt/type.html",
                               adaptors=ADAPTORS,
                               apps=apps)

    # Version for the public
    else:
        return render_template("composers/adapt/public_type.html",
                               adaptors=ADAPTORS,
                               apps=apps)
コード例 #22
0
ファイル: api.py プロジェクト: gengivan/appcomposer
def create_app(name,
               composer,
               spec_url,
               data,
               find_new_name=False,
               description=None):
    """
    @param {str} name: Unique name to give to the application.
    @param {str} composer: Composer identifier.
    @param {str} spec_url: Spec URL that the app is linked to. It can be None.
    @param {dict} data: JSON-able dictionary with the composer-specific data, or the JSON string itself.
    @param {bool} find_new_name: Whether the name should be auto-modified with a number to make it unique or throw an exception.
    @param {str} description: Description of the app.
    @return {App}: The app that has been created.

    @note: This function can be used by any logged-on user. There are no restrictions other than
    unique (name, owner) combination.
    """

    # Get the current user, who will be the owner of our app.
    owner = current_user()

    # To try to create an app we need to be logged in.
    if owner is None:
        raise NotAuthorizedException("User is not logged in")

    # If the composer-specific data is already a string, we assume
    # it is JSON'ed already.
    if type(data) is not str and type(data) is not unicode:
        data = json.dumps(data)

    # Check if an app with that name and owner exists already.
    existing_app = App.query.filter_by(owner=owner, name=name).first()
    if existing_app is not None:
        if find_new_name:
            MAX = 10000
            counter = 2
            while counter < MAX:
                new_name = '%s (%s)' % (name, counter)
                existing_app = App.query.filter_by(owner=owner,
                                                   name=new_name).first()
                if existing_app is None:
                    name = new_name
                    break

                counter += 1
            if counter == MAX:
                raise AppExistsException()
        else:
            raise AppExistsException()

    # Create the Spec object.
    if spec_url is not None:
        spec = getcreate_spec(spec_url)
    else:
        spec = None

    # Create it
    new_app = App(name, owner, composer, description=description)
    new_app.data = data
    new_app.spec = spec

    # Insert the new app into the database
    db.session.add(new_app)
    db.session.commit()

    return new_app
コード例 #23
0
 def is_accessible(self):
     return current_user() is not None
コード例 #24
0
def _is_admin():
    _current_user = current_user()
    return _current_user and _current_user.role == Role.admin
コード例 #25
0
def _is_admin():
    _current_user = current_user()
    return _current_user and _current_user.role == Role.admin
コード例 #26
0
 def is_accessible(self):
     return current_user() is not None
コード例 #27
0
ファイル: api.py プロジェクト: iasinDev/appcomposer
def create_app(name, composer, spec_url, data, find_new_name=False, description=None):
    """
    @param {str} name: Unique name to give to the application.
    @param {str} composer: Composer identifier.
    @param {str} spec_url: Spec URL that the app is linked to. It can be None.
    @param {dict} data: JSON-able dictionary with the composer-specific data, or the JSON string itself.
    @param {bool} find_new_name: Whether the name should be auto-modified with a number to make it unique or throw an exception.
    @param {str} description: Description of the app.
    @return {App}: The app that has been created.

    @note: This function can be used by any logged-on user. There are no restrictions other than
    unique (name, owner) combination.
    """

    # Get the current user, who will be the owner of our app.
    owner = current_user()

    # To try to create an app we need to be logged in.
    if owner is None:
        raise NotAuthorizedException("User is not logged in")

    # If the composer-specific data is already a string, we assume
    # it is JSON'ed already.
    if type(data) is not str and type(data) is not unicode:
        data = json.dumps(data)

    # Check if an app with that name and owner exists already.
    existing_app = App.query.filter_by(owner=owner, name=name).first()
    if existing_app is not None:
        if find_new_name:
            MAX = 10000
            counter = 2
            while counter < MAX:
                new_name = "%s (%s)" % (name, counter)
                existing_app = App.query.filter_by(owner=owner, name=new_name).first()
                if existing_app is None:
                    name = new_name
                    break

                counter += 1
            if counter == MAX:
                raise AppExistsException()
        else:
            raise AppExistsException()

    # Create the Spec object.
    if spec_url is not None:
        spec = getcreate_spec(spec_url)
    else:
        spec = None

    # Create it
    new_app = App(name, owner, composer, description=description)
    new_app.data = data
    new_app.spec = spec

    # Insert the new app into the database
    db.session.add(new_app)
    db.session.commit()

    return new_app
コード例 #28
0
 def test_current_user(self):
     cu = current_user()
     assert cu.login == "testuser"
コード例 #29
0
 def test_current_user(self):
     cu = current_user()
     assert cu.login == "testuser"