Example #1
0
def get_link_url(item, request, actionname=None, backurl=False):
    """Return a url to the given item. On default the link will be a
    link to the update or read view of the item depending on the
    permission. If the application is configured to open items in read
    mode on default the update action will not be checked. If the user
    does not have enough permissions than None is returned. Optionally
    you can provide the name of a action. In this case the url will be
    build for the given actionname if the user has enough
    permissions."""
    readmode = request.registry.settings.get("app.readmode") in [
        "True", "true"
    ]
    if isinstance(item, BaseItem):
        if actionname:
            from ringo.views.helpers import get_item_modul
            modul = get_item_modul(request, item)
            action = modul.get_action(actionname)
            if action is None:
                # This can happen if the action is not part of the modul
                # but a custum userdefined view. No permission checks
                # are done here yet.
                route_name = get_action_routename(item, actionname)
            else:
                permission = action.permission or action.name.lower()
                if security.has_permission(permission, item, request):
                    route_name = get_action_routename(item,
                                                      action.name.lower())
                else:
                    return None
        elif not readmode and security.has_permission("update", item, request):
            route_name = get_action_routename(item, 'update')
        elif security.has_permission("read", item, request):
            route_name = get_action_routename(item, 'read')
        else:
            return None

        query = {}
        if backurl:
            clazz = request.context.__model__
            query['backurl'] = request.session.get(
                '%s.backurl' % clazz) or request.current_route_path()
        return request.route_path(route_name, id=item.id, _query=query)
    return None
Example #2
0
def get_link_url(item, request, actionname=None, backurl=False):
    """Return a url to the given item. On default the link will be a
    link to the update or read view of the item depending on the
    permission. If the user does not have enough permissions than None
    is returned. Optionally you can provide the name of a action. In
    this case the url will be build for the given actionname if the user
    has enough permissions."""
    if isinstance(item, BaseItem):
        if actionname:
            from ringo.views.helpers import get_item_modul
            modul = get_item_modul(request, item)
            action = modul.get_action(actionname)
            if action is None:
                # This can happen if the action is not part of the modul
                # but a custum userdefined view. No permission checks
                # are done here yet.
                route_name = get_action_routename(item, actionname)
            else:
                permission = action.permission or action.name.lower()
                if security.has_permission(permission, item, request):
                    route_name = get_action_routename(item,
                                                      action.name.lower())
                else:
                    return None
        elif security.has_permission("update", item, request):
            route_name = get_action_routename(item, 'update')
        elif security.has_permission("read", item, request):
            route_name = get_action_routename(item, 'read')
        else:
            return None

        query = {}
        if backurl:
            query['backurl'] = request.current_route_path()
        return request.route_path(route_name, id=item.id, _query=query)
    return None
Example #3
0
def handle_POST_request(form, request, callback, event="", renderers=None):
    """@todo: Docstring for handle_POST_request.

    :name: @todo
    :request: @todo
    :callback: @todo
    :renderers: @todo
    :event: Name of the event (update, create...) Used for the event handler
    :returns: True or False

    """
    _ = request.translate
    clazz = request.context.__model__
    item_label = get_item_modul(request, clazz).get_label()
    item = get_item_from_request(request)
    mapping = {"item_type": item_label, "item": item}

    # Add a *special* validator to the form to trigger rendering a
    # permanent info pane at the top of the form in case of errors on
    # validation. This info has been added because users reported data
    # loss because of formbar/ringo default behaviour of not saving
    # anything in case of errors. Users seems to expect that the valid
    # part of the data has been saved. This info should make the user
    # aware of the fact that nothing has been saved in case of errors.
    error_message = _(
        "The information contained errors. "
        "<strong>All entries (including error-free) were not "
        "saved!</strong> Please correct your entries in the "
        "fields marked in red and resave."
    )
    form.add_validator(Validator(None, literal(error_message), callback=form_has_errors, context=form))

    # Begin a nested transaction. In case an error occours while saving
    # the data the nested transaction will be rolled back. The parent
    # session will be still ok.
    request.db.begin_nested()
    if form.validate(request.params) and "blobforms" not in request.params:
        checker = ValueChecker()
        try:
            if event == "create":
                try:
                    factory = clazz.get_item_factory(request)
                except TypeError:
                    # Old version of get_item_factory method which does
                    # not take an request parameter.
                    factory = clazz.get_item_factory()
                    factory._request = request

                checker.check(clazz, form.data, request)
                item = factory.create(request.user, form.data)
                item.save({}, request)
                request.context.item = item
                handle_add_relation(request, item)
            else:
                values = checker.check(clazz, form.data, request, item)
                item.save(values, request)
            handle_event(request, item, event)
            handle_callback(request, callback)
            handle_caching(request)

            if event == "create":
                msg = _("Created new ${item_type} successfully.", mapping=mapping)
                log_msg = u"User {user.login} created {item_label} {item.id}".format(
                    item_label=item_label, item=item, user=request.user
                )
            else:
                msg = _('Edited ${item_type} "${item}" successfully.', mapping=mapping)
                log_msg = u"User {user.login} edited {item_label} {item.id}".format(
                    item_label=item_label, item=item, user=request.user
                )
            log.info(log_msg)
            request.session.flash(msg, "success")

            # Set next form page.
            if request.params.get("_submit") == "nextpage":
                table = clazz.__table__
                itemid = item.id
                page = get_next_form_page(form, get_current_form_page(clazz, request))
                set_current_form_page(table, itemid, page, request)

            # In case all is ok merge the nested session.
            request.db.merge(item)
            return True
        except Exception as error:
            request.db.rollback()
            mapping["error"] = unicode(error.message)
            if event == "create":
                msg = _("Error while saving new " "${item_type}: ${error}.", mapping=mapping)
            else:
                msg = _("Error while saving " '${item_type} "${item}": ${error}.', mapping=mapping)
            log.exception(msg)
            request.session.flash(msg, "critical")
            return False
    elif "blobforms" in request.params:
        pass
    else:
        request.db.rollback()
        if event == "create":
            msg = _("Error on validation new " "${item_type}.", mapping=mapping)
        else:
            msg = _("Error on validation " '${item_type} "${item}".', mapping=mapping)
        log.debug(msg)
        request.session.flash(msg, "error")
    return False
Example #4
0
def handle_POST_request(form, request, callback, event="", renderers=None):
    """@todo: Docstring for handle_POST_request.

    :name: @todo
    :request: @todo
    :callback: @todo
    :renderers: @todo
    :event: Name of the event (update, create...) Used for the event handler
    :returns: True or False

    """
    _ = request.translate
    clazz = request.context.__model__
    item_label = get_item_modul(request, clazz).get_label()
    item = get_item_from_request(request)
    mapping = {'item_type': item_label, 'item': item}

    # Add a *special* validator to the form to trigger rendering a
    # permanent info pane at the top of the form in case of errors on
    # validation. This info has been added because users reported data
    # loss because of formbar/ringo default behaviour of not saving
    # anything in case of errors. Users seems to expect that the valid
    # part of the data has been saved. This info should make the user
    # aware of the fact that nothing has been saved in case of errors.
    error_message = _("The information contained errors. "
                      "<strong>All entries (including error-free) were not "
                      "saved!</strong> Please correct your entries in the "
                      "fields marked in red and resave.")
    form.add_validator(
        Validator(None,
                  literal(error_message),
                  callback=form_has_errors,
                  context=form))

    # Begin a nested transaction. In case an error occours while saving
    # the data the nested transaction will be rolled back. The parent
    # session will be still ok.
    request.db.begin_nested()
    if form.validate(request.params) and "blobforms" not in request.params:
        checker = ValueChecker()
        try:
            # Handle new callback objects wich are configured to be
            # called previous the origin action. Old simple callbacks
            # are ignored.
            handle_callback(request, callback, mode="pre")
            if event == "create":
                try:
                    factory = clazz.get_item_factory(request)
                except TypeError:
                    # Old version of get_item_factory method which does
                    # not take an request parameter.
                    factory = clazz.get_item_factory()
                    factory._request = request

                checker.check(clazz, form.data, request)
                item = factory.create(request.user, form.data)
                handle_add_relation(request, item)
                item.save({}, request)
                request.context.item = item
            else:
                values = checker.check(clazz, form.data, request, item)
                item.save(values, request)
            handle_event(request, item, event)
            # Maintain old behaviour of callbacks. Callback are called
            # post the origin action of the view. Therefor the callback
            # must either be an instance of :class:Callback with mode
            # "post" or it is a simple callable.
            handle_callback(request, callback, mode="post,default")
            handle_caching(request)

            if event == "create":
                msg = _('Created new ${item_type} successfully.',
                        mapping=mapping)
                log_msg = u'User {user.login} created {item_label} {item.id}'\
                    .format(item_label=item_label,
                            item=item, user=request.user)
            else:
                msg = _('Edited ${item_type} "${item}" successfully.',
                        mapping=mapping)
                log_msg = u'User {user.login} edited {item_label} {item.id}'\
                    .format(item_label=item_label,
                            item=item, user=request.user)
            log.info(log_msg)
            request.session.flash(msg, 'success')

            # Set next form page.
            if request.params.get("_submit") == "nextpage":
                table = clazz.__table__
                itemid = item.id
                page = get_next_form_page(
                    form, get_current_form_page(clazz, request))
                set_current_form_page(table, itemid, page, request)

            # In case all is ok merge the nested session.
            request.db.merge(item)
            return True
        except Exception as error:
            request.db.rollback()
            mapping['error'] = unicode(error.message)
            if event == "create":
                log_msg = _(u'User {user.login} created'
                            '{item_label}').format(item_label=item_label,
                                                   user=request.user)
                msg = _('Error while saving new '
                        '${item_type}: ${error}.',
                        mapping=mapping)
            else:
                log_msg = _(u'User {user.login} edited '
                            '{item_label} {item.id}').format(
                                item_label=item_label,
                                item=item,
                                user=request.user)
                msg = _(
                    'Error while saving '
                    '${item_type} "${item}": ${error}.',
                    mapping=mapping)
            log.exception(log_msg)
            request.session.flash(msg, 'critical')
            return False
    elif "blobforms" in request.params:
        pass
    else:
        request.db.rollback()
        if event == "create":
            msg = _('Error on validation new '
                    '${item_type}.',
                    mapping=mapping)
        else:
            msg = _('Error on validation '
                    '${item_type} "${item}".',
                    mapping=mapping)
        log.debug(msg)
        request.session.flash(msg, 'error')
    return False