示例#1
0
def s3_rest_controller(prefix=None, resourcename=None, **attr):
    """
        Helper function to apply the S3Resource REST interface

        @param prefix: the application prefix
        @param resourcename: the resource name (without prefix)
        @param attr: additional keyword parameters

        Any keyword parameters will be copied into the output dict (provided
        that the output is a dict). If a keyword parameter is callable, then
        it will be invoked, and its return value will be added to the output
        dict instead. The callable receives the S3Request as its first and
        only parameter.

        CRUD can be configured per table using:

            s3db.configure(tablename, **attr)

        *** Redirection:

        create_next             URL to redirect to after a record has been created
        update_next             URL to redirect to after a record has been updated
        delete_next             URL to redirect to after a record has been deleted

        *** Form configuration:

        list_fields             list of names of fields to include into list views
        subheadings             Sub-headings (see separate documentation)
        listadd                 Enable/Disable add-form in list views

        *** CRUD configuration:

        editable                Allow/Deny record updates in this table
        deletable               Allow/Deny record deletions in this table
        insertable              Allow/Deny record insertions into this table
        copyable                Allow/Deny record copying within this table

        *** Callbacks:

        create_onvalidation     Function for additional record validation on create
        create_onaccept         Function after successful record insertion

        update_onvalidation     Function for additional record validation on update
        update_onaccept         Function after successful record update

        onvalidation            Fallback for both create_onvalidation and update_onvalidation
        onaccept                Fallback for both create_onaccept and update_onaccept
        ondelete                Function after record deletion
    """

    # Parse the request
    dynamic = attr.get("dynamic")
    if dynamic:
        # Dynamic table controller
        c = request.controller
        f = request.function
        attr = settings.customise_controller("%s_%s" % (c, f), **attr)
        from s3 import DYNAMIC_PREFIX, s3_get_extension
        r = s3_request(DYNAMIC_PREFIX,
                       dynamic,
                       f = "%s/%s" % (f, dynamic),
                       args = request.args[1:],
                       extension = s3_get_extension(request),
                       )
    else:
        # Customise Controller from Template
        attr = settings.customise_controller(
                    "%s_%s" % (prefix or request.controller,
                               resourcename or request.function,
                               ),
                    **attr)
        r = s3_request(prefix, resourcename)

    # Customize target resource(s) from Template
    r.customise_resource()

    # Configure standard method handlers
    set_handler = r.set_handler
    from s3db.cms import S3CMS
    set_handler("cms", S3CMS)
    set_handler("compose", s3base.S3Compose)
    # @ToDo: Make work in Component Tabs:
    set_handler("copy", lambda r, **attr: \
                               redirect(URL(args="create",
                                            vars={"from_record":r.id})))
    set_handler("deduplicate", s3base.S3Merge)
    set_handler("filter", s3base.S3Filter)
    set_handler("grouped", s3base.S3GroupedItemsReport)
    set_handler("hierarchy", s3base.S3HierarchyCRUD)
    set_handler("import", s3base.S3Importer)
    set_handler("map", s3base.S3Map)
    set_handler("mdata", s3base.S3MobileCRUD, representation="json")
    set_handler("mform", s3base.S3MobileCRUD, representation="json")
    set_handler("profile", s3base.S3Profile)
    set_handler("report", s3base.S3Report)
    set_handler("report", s3base.S3Report, transform=True)
    set_handler("search_ac", s3base.search_ac)
    set_handler("summary", s3base.S3Summary)
    set_handler("timeplot", s3base.S3TimePlot)
    set_handler("xform", s3base.S3XForms)

    # Don't load S3PDF unless needed (very slow import with Reportlab)
    method = r.method
    if method == "import" and r.representation == "pdf":
        from s3.s3pdf import S3PDF
        set_handler("import", S3PDF(),
                    http = ("GET", "POST"),
                    representation="pdf")

    # Plugin OrgRoleManager when appropriate
    s3base.S3OrgRoleManager.set_method(r)

    # Execute the request
    output = r(**attr)

    if isinstance(output, dict) and \
       method in (None,
                  "report",
                  "search",
                  "datatable",
                  "datatable_f",
                  "summary"):

        if s3.actions is None:

            # Add default action buttons
            prefix, name, table, tablename = r.target()
            authorised = s3_has_permission("update", tablename)

            # If a component has components itself, then action buttons
            # can be forwarded to the native controller by setting native=True
            if r.component and s3db.has_components(table):
                native = output.get("native", False)
            else:
                native = False

            # Get table config
            get_config = s3db.get_config
            listadd = get_config(tablename, "listadd", True)
            editable = get_config(tablename, "editable", True) and \
                       not auth.permission.ownership_required("update", table)
            deletable = get_config(tablename, "deletable", True)
            copyable = get_config(tablename, "copyable", False)

            # URL to open the resource
            open_url = r.resource.crud._linkto(r,
                                               authorised=authorised,
                                               update=editable,
                                               native=native)("[id]")

            # Add action buttons for Open/Delete/Copy as appropriate
            s3_action_buttons(r,
                              deletable=deletable,
                              copyable=copyable,
                              editable=editable,
                              read_url=open_url,
                              update_url=open_url
                              # To use modals
                              #update_url="%s.popup?refresh=list" % open_url
                              )

            # Override Add-button, link to native controller and put
            # the primary key into get_vars for automatic linking
            if native and not listadd and \
               s3_has_permission("create", tablename):
                label = s3base.S3CRUD.crud_string(tablename,
                                                  "label_create")
                hook = r.resource.components[name]
                fkey = "%s.%s" % (name, hook.fkey)
                get_vars_copy = get_vars.copy()
                get_vars_copy.update({fkey: r.record[hook.fkey]})
                url = URL(prefix, name, args=["create"], vars=get_vars_copy)
                add_btn = A(label, _href=url, _class="action-btn")
                output.update(add_btn=add_btn)

    elif method not in ("import",
                        "review",
                        "approve",
                        "reject",
                        "deduplicate"):
        s3.actions = None

    if get_vars.tour:
        output = s3db.tour_builder(output)

    return output
示例#2
0
    def __call__(self):
        """ The userstats controller """

        # Require ORG_GROUP_ADMIN
        auth = current.auth
        if not auth.s3_has_role("ORG_GROUP_ADMIN"):
            auth.permission.fail()

        from s3 import S3CRUD, s3_get_extension, s3_request

        request = current.request
        args = request.args

        # Create an S3Request
        r = s3_request(
            "org",
            "organisation",
            c="default",
            f="index/%s" % args[0],
            args=args[1:],
            extension=s3_get_extension(request),
        )

        # Filter to root organisations
        resource = r.resource
        resource.add_filter(FS("id").belongs(self.root_orgs))

        # Configure field methods
        from gluon import Field
        table = resource.table
        table.total_accounts = Field.Method("total_accounts",
                                            self.total_accounts)
        table.active_accounts = Field.Method("active_accounts",
                                             self.active_accounts)
        table.disabled_accounts = Field.Method("disabled_accounts",
                                               self.disabled_accounts)
        table.active30 = Field.Method("active30", self.active30)

        # Labels for field methods
        T = current.T
        TOTAL = T("Total User Accounts")
        ACTIVE = T("Active")
        DISABLED = T("Inactive")
        ACTIVE30 = T("Logged-in Last 30 Days")

        # Configure list_fields
        list_fields = (
            "id",
            "name",
            (TOTAL, "total_accounts"),
            (ACTIVE, "active_accounts"),
            (DISABLED, "disabled_accounts"),
            (ACTIVE30, "active30"),
        )

        # Configure form
        from s3 import S3SQLCustomForm, S3SQLVirtualField
        crud_form = S3SQLCustomForm(
            "name",
            S3SQLVirtualField(
                "total_accounts",
                label=TOTAL,
            ),
            S3SQLVirtualField(
                "active_accounts",
                label=ACTIVE,
            ),
            S3SQLVirtualField(
                "disabled_accounts",
                label=DISABLED,
            ),
            S3SQLVirtualField(
                "active30",
                label=ACTIVE30,
            ),
        )

        # Configure read-only
        resource.configure(
            insertable=False,
            editable=False,
            deletable=False,
            crud_form=crud_form,
            filter_widgets=None,
            list_fields=list_fields,
        )

        output = r(rheader=self.rheader)

        if isinstance(output, dict):

            output["title"] = T("User Statistics")

            # URL to open the resource
            open_url = resource.crud._linkto(r, update=False)("[id]")

            # Add action button for open
            action_buttons = S3CRUD.action_buttons
            action_buttons(
                r,
                deletable=False,
                copyable=False,
                editable=False,
                read_url=open_url,
            )

        return output
示例#3
0
文件: 00_utils.py 项目: nursix/eden
def s3_rest_controller(prefix=None, resourcename=None, **attr):
    """
        Helper function to apply the S3Resource REST interface

        @param prefix: the application prefix
        @param resourcename: the resource name (without prefix)
        @param attr: additional keyword parameters

        Any keyword parameters will be copied into the output dict (provided
        that the output is a dict). If a keyword parameter is callable, then
        it will be invoked, and its return value will be added to the output
        dict instead. The callable receives the S3Request as its first and
        only parameter.

        CRUD can be configured per table using:

            s3db.configure(tablename, **attr)

        *** Redirection:

        create_next             URL to redirect to after a record has been created
        update_next             URL to redirect to after a record has been updated
        delete_next             URL to redirect to after a record has been deleted

        *** Form configuration:

        list_fields             list of names of fields to include into list views
        subheadings             Sub-headings (see separate documentation)
        listadd                 Enable/Disable add-form in list views

        *** CRUD configuration:

        editable                Allow/Deny record updates in this table
        deletable               Allow/Deny record deletions in this table
        insertable              Allow/Deny record insertions into this table
        copyable                Allow/Deny record copying within this table

        *** Callbacks:

        create_onvalidation     Function for additional record validation on create
        create_onaccept         Function after successful record insertion

        update_onvalidation     Function for additional record validation on update
        update_onaccept         Function after successful record update

        onvalidation            Fallback for both create_onvalidation and update_onvalidation
        onaccept                Fallback for both create_onaccept and update_onaccept
        ondelete                Function after record deletion
    """

    # Parse the request
    dynamic = attr.get("dynamic")
    if dynamic:
        # Dynamic table controller
        c = request.controller
        f = request.function
        attr = settings.customise_controller("%s_%s" % (c, f), **attr)
        from s3 import DYNAMIC_PREFIX, s3_get_extension
        r = s3_request(DYNAMIC_PREFIX,
                       dynamic,
                       f = "%s/%s" % (f, dynamic),
                       args = request.args[1:],
                       extension = s3_get_extension(request),
                       )
    else:
        # Customise Controller from Template
        attr = settings.customise_controller(
                    "%s_%s" % (prefix or request.controller,
                               resourcename or request.function,
                               ),
                    **attr)
        r = s3_request(prefix, resourcename)

    # Customize target resource(s) from Template
    r.customise_resource()

    # Configure standard method handlers
    set_handler = r.set_handler
    from s3db.cms import S3CMS
    set_handler("cms", S3CMS)
    set_handler("compose", s3base.S3Compose)
    # @ToDo: Make work in Component Tabs:
    set_handler("copy", lambda r, **attr: \
                               redirect(URL(args="create",
                                            vars={"from_record":r.id})))
    set_handler("deduplicate", s3base.S3Merge)
    set_handler("filter", s3base.S3Filter)
    set_handler("grouped", s3base.S3GroupedItemsReport)
    set_handler("hierarchy", s3base.S3HierarchyCRUD)
    set_handler("import", s3base.S3Importer)
    set_handler("map", s3base.S3Map)
    set_handler("mform", s3base.S3MobileCRUD, representation="json")
    set_handler("organize", s3base.S3Organizer)
    set_handler("profile", s3base.S3Profile)
    set_handler("report", s3base.S3Report) # For HTML, JSON
    set_handler("report", s3base.S3Report, transform=True) # For GeoJSON
    set_handler("search_ac", s3base.search_ac)
    set_handler("summary", s3base.S3Summary)
    set_handler("timeplot", s3base.S3TimePlot)
    set_handler("xform", s3base.S3XForms)

    # Don't load S3PDF unless needed (very slow import with Reportlab)
    method = r.method
    if method == "import" and r.representation == "pdf":
        from s3.s3pdf import S3PDF
        set_handler("import", S3PDF(),
                    http = ("GET", "POST"),
                    representation="pdf")

    # Plugin OrgRoleManager when appropriate
    s3base.S3OrgRoleManager.set_method(r)

    # Execute the request
    output = r(**attr)

    if isinstance(output, dict) and \
       method in (None,
                  "report",
                  "search",
                  "datatable",
                  "datatable_f",
                  "summary"):

        if s3.actions is None:

            # Add default action buttons
            prefix, name, table, tablename = r.target()
            authorised = s3_has_permission("update", tablename)

            # If a component has components itself, then action buttons
            # can be forwarded to the native controller by setting native=True
            if r.component and s3db.has_components(table):
                native = output.get("native", False)
            else:
                native = False

            # Get table config
            get_config = s3db.get_config
            listadd = get_config(tablename, "listadd", True)

            # Which is the standard open-action?
            if settings.get_ui_open_read_first():
                # Always read, irrespective permissions
                editable = False
            else:
                editable = get_config(tablename, "editable", True)
                if editable and \
                   auth.permission.ownership_required("update", table):
                    # User cannot edit all records in the table
                    if settings.get_ui_auto_open_update():
                        # Decide automatically per-record (implicit method)
                        editable = "auto"
                    else:
                        # Always open read first (explicit read)
                        editable = False

            deletable = get_config(tablename, "deletable", True)
            copyable = get_config(tablename, "copyable", False)

            # URL to open the resource
            open_url = r.resource.crud._linkto(r,
                                               authorised=authorised,
                                               update=editable,
                                               native=native)("[id]")

            # Add action buttons for Open/Delete/Copy as appropriate
            s3_action_buttons(r,
                              deletable=deletable,
                              copyable=copyable,
                              editable=editable,
                              read_url=open_url,
                              update_url=open_url
                              # To use modals
                              #update_url="%s.popup?refresh=list" % open_url
                              )

            # Override Add-button, link to native controller and put
            # the primary key into get_vars for automatic linking
            if native and not listadd and \
               s3_has_permission("create", tablename):
                label = s3base.S3CRUD.crud_string(tablename,
                                                  "label_create")
                component = r.resource.components[name]
                fkey = "%s.%s" % (name, component.fkey)
                get_vars_copy = get_vars.copy()
                get_vars_copy.update({fkey: r.record[component.fkey]})
                url = URL(prefix, name, args=["create"], vars=get_vars_copy)
                add_btn = A(label, _href=url, _class="action-btn")
                output.update(add_btn=add_btn)

    elif method not in ("import",
                        "review",
                        "approve",
                        "reject",
                        "deduplicate"):
        s3.actions = None

    if get_vars.tour:
        output = s3db.tour_builder(output)

    return output
示例#4
0
    def __call__(self):
        """ The userstats controller """

        # Require ORG_GROUP_ADMIN
        auth = current.auth
        if not auth.s3_has_role("ORG_GROUP_ADMIN"):
            auth.permission.fail()

        from s3 import S3CRUD, s3_get_extension, s3_request

        request = current.request
        args = request.args

        # Create an S3Request
        r = s3_request("org", "organisation",
                       c = "default",
                       f = "index/%s" % args[0],
                       args = args[1:],
                       extension = s3_get_extension(request),
                       )

        # Filter to root organisations
        resource = r.resource
        resource.add_filter(FS("id").belongs(self.root_orgs))

        # Configure field methods
        from gluon import Field
        table = resource.table
        table.total_accounts = Field.Method("total_accounts", self.total_accounts)
        table.active_accounts = Field.Method("active_accounts", self.active_accounts)
        table.disabled_accounts = Field.Method("disabled_accounts", self.disabled_accounts)
        table.active30 = Field.Method("active30", self.active30)

        # Labels for field methods
        T = current.T
        TOTAL = T("Total User Accounts")
        ACTIVE = T("Active")
        DISABLED = T("Inactive")
        ACTIVE30 = T("Logged-in Last 30 Days")

        # Configure list_fields
        list_fields = ("id",
                       "name",
                       (TOTAL, "total_accounts"),
                       (ACTIVE, "active_accounts"),
                       (DISABLED, "disabled_accounts"),
                       (ACTIVE30, "active30"),
                       )

        # Configure form
        from s3 import S3SQLCustomForm, S3SQLVirtualField
        crud_form = S3SQLCustomForm("name",
                                    S3SQLVirtualField("total_accounts",
                                                      label = TOTAL,
                                                      ),
                                    S3SQLVirtualField("active_accounts",
                                                      label = ACTIVE,
                                                      ),
                                    S3SQLVirtualField("disabled_accounts",
                                                      label = DISABLED,
                                                      ),
                                    S3SQLVirtualField("active30",
                                                      label = ACTIVE30,
                                                      ),
                                    )

        # Configure read-only
        resource.configure(insertable = False,
                           editable = False,
                           deletable = False,
                           crud_form = crud_form,
                           filter_widgets = None,
                           list_fields = list_fields,
                           )

        output = r(rheader=self.rheader)

        if isinstance(output, dict):

            output["title"] = T("User Statistics")

            # URL to open the resource
            open_url = resource.crud._linkto(r, update=False)("[id]")

            # Add action button for open
            action_buttons = S3CRUD.action_buttons
            action_buttons(r,
                           deletable = False,
                           copyable = False,
                           editable = False,
                           read_url = open_url,
                           )

        return output