Ejemplo n.º 1
0
def organisation_needs(row, need_type=None):
    """
        Field.Method to render structured organisation needs (list views)

        @param row: the row (passed from Field.Method)
        @param need_type: the need type (skills|items)
    """

    NONE = current.messages["NONE"]

    try:
        needs = getattr(row, "req_organisation_needs")
    except AttributeError:
        return NONE
    needs_id = needs.id

    s3db = current.s3db
    if need_type == "skills":
        ltable = s3db.req_organisation_needs_skill
        stable = s3db.hrm_skill
        left = stable.on(stable.id == ltable.skill_id)
    elif need_type == "items":
        ltable = s3db.req_organisation_needs_item
        stable = s3db.supply_item
        left = stable.on(stable.id == ltable.item_id)

    query = (ltable.organisation_needs_id == needs_id)
    rows = current.db(query).select(ltable.demand,
                                    stable.name,
                                    left = left,
                                    )
    if not rows:
        return NONE

    needs = {}
    dfield = str(ltable.demand)
    nfield = str(stable.name)
    for row in rows:
        demand = row[dfield]
        if demand not in needs:
            needs[demand] = [row[nfield]]
        else:
            needs[demand].append(row[nfield])

    T = current.T
    output = DIV(_class="org-needs")
    for demand in (4, 3, 2, 1):
        if demand not in needs:
            continue
        title = "%s:" % T(demand_options[demand])
        items = UL([LI(T(need))
                    for need in needs[demand] if need is not None])
        output.append(TAG[""](title, items))
    return output

# END =========================================================================
Ejemplo n.º 2
0
    def test_DIV(self):
        # Empty DIV()
        self.assertEqual(DIV().xml(), b'<div></div>')
        self.assertEqual(DIV('<>', _a='1', _b='2').xml(),
                         b'<div a="1" b="2">&lt;&gt;</div>')
        # attributes can be updated like in a dict
        div = DIV('<>', _a='1')
        div['_b'] = '2'
        self.assertEqual(div.xml(),
                         b'<div a="1" b="2">&lt;&gt;</div>')
        # also with a mapping
        div.update(_b=2, _c=3)
        self.assertEqual(div.xml(),
                         b'<div a="1" b="2" c="3">&lt;&gt;</div>')
        # length of the DIV is the number of components
        self.assertEqual(len(DIV('a', 'bc')), 2)
        # also if empty, DIV is True in a boolean evaluation
        self.assertTrue(True if DIV() else False)
        # parent and siblings
        a = DIV(SPAN('a'), DIV('b'))
        s = a.element('span')
        d = s.parent
        d['_class'] = 'abc'
        self.assertEqual(a.xml(), b'<div class="abc"><span>a</span><div>b</div></div>')
        self.assertEqual([el.xml() for el in s.siblings()], [b'<div>b</div>'])
        self.assertEqual(s.sibling().xml(), b'<div>b</div>')
        # siblings with wrong args
        self.assertEqual(s.siblings('a'), [])
        # siblings with good args
        self.assertEqual(s.siblings('div')[0].xml(), b'<div>b</div>')
        # Check for siblings with wrong kargs and value
        self.assertEqual(s.siblings(a='d'), [])
        # Check for siblings with good kargs and value
        # Can't figure this one out what is a right value here??
        # Commented for now...
        # self.assertEqual(s.siblings(div='<div>b</div>'), ???)
        # No other sibling should return None
        self.assertEqual(DIV(P('First element')).element('p').sibling(), None)
        # --------------------------------------------------------------------------------------------------------------
        # This use unicode to hit xmlescape() line :
        #     """
        #     elif isinstance(data, unicode):
        #         data = data.encode('utf8', 'xmlcharrefreplace')
        #     """
        self.assertEqual(DIV(u'Texte en français avec des caractères accentués...').xml(),
                         b'<div>Texte en fran\xc3\xa7ais avec des caract\xc3\xa8res accentu\xc3\xa9s...</div>')
        # --------------------------------------------------------------------------------------------------------------
        self.assertEqual(DIV('Test with an ID', _id='id-of-the-element').xml(),
                         b'<div id="id-of-the-element">Test with an ID</div>')
        self.assertEqual(DIV().element('p'), None)

        # Corner case for raise coverage of one line
        # I think such assert fail cause of python 2.6
        # Work under python 2.7
        # with self.assertRaises(SyntaxError) as cm:
        #     DIV(BR('<>')).xml()
        # self.assertEqual(cm.exception[0], '<br/> tags cannot have components')

        # test .get('attrib')
        self.assertEqual(DIV('<p>Test</p>', _class="class_test").get('_class'), 'class_test')
Ejemplo n.º 3
0
    def xml(self):
        """ XML """

        self.components = []
        self.components.append(self.root.render())

        return DIV.xml(self)
Ejemplo n.º 4
0
 def buttons(edit=False,view=False,record=None):
     buttons = DIV(gridbutton('buttonback', 'Back', referrer),
                   _class='form_header row_buttons %(header)s %(cornertop)s' % ui)
     if edit and (not callable(edit) or edit(record)):
         args = ['edit',table._tablename,request.args[-1]]
         buttons.append(gridbutton('buttonedit', 'Edit',
                                   url(args=args)))
     if view:
         args = ['view',table._tablename,request.args[-1]]
         buttons.append(gridbutton('buttonview', 'View',
                                   url(args=args)))
     if record and links:
         for link in links:
             if isinstance(link,dict):
                 buttons.append(link['body'](record))
             elif link(record):
                 buttons.append(link(record))
     return buttons
Ejemplo n.º 5
0
def formstyle_bootstrap_modal(form, fields, **kwargs):
    """"
    Bootstrap format modal form layout
    """
    span = kwargs.get('span') or 'span8'
    select_attributes = kwargs.get('select_attributes', '')
    form.add_class('form-horizontal')
    parent = FIELDSET()
    for id, label, controls, help in fields:
        _controls = DIV(controls, _class='controls')
        # submit unflag by default
        _submit = False

        if isinstance(controls, INPUT):
            controls.add_class(span)
            if controls['_type'] == 'submit':
                # flag submit button
                _submit = True
                controls['_class'] = 'btn btn-primary'
            if controls['_type'] == 'file':
                controls['_class'] = 'input-file'

        # For password fields, which are wrapped in a CAT object.
        if isinstance(controls, CAT) and isinstance(controls[0], INPUT):
            controls[0].add_class(span)

        if isinstance(controls, SELECT):
            controls.add_class(span)

        if isinstance(controls, TEXTAREA):
            controls.add_class(span)

        if isinstance(label, LABEL):
            label['_class'] = 'control-label'
            if help:
                label.append(
                    I(_class="icon-question-sign",
                      _rel="tooltip",
                      **{'_data-content': help}))

        if _submit:
            # submit button has unwrapped label and controls, different class
            parent.append(
                DIV(label,
                    BUTTON("Close",
                           _class="btn",
                           **{
                               '_data-dismiss': 'modal',
                               '_aria-hidden': True
                           }),
                    controls,
                    _class='modal-footer',
                    _id=id))
            # unflag submit (possible side effect)
            _submit = False
        else:
            # unwrapped label
            _class = 'control-group'
            parent.append(DIV(label, _controls, _class=_class, _id=id))

    # append tooltip and chosen field attributes
    if 'id' not in form.attributes:
        form.attributes['_id'] = "%s-id" % (str(form.table))
    script_data = """$(document).ready(function() {{
    $("[rel=tooltip]").popover({{
        placement: 'right',
        trigger: 'hover',
    }});
    $('#{0:s} select').select2({{{1:s}}});
    {2:s}
}});""".format(form.attributes['_id'], select_attributes,
               kwargs.get('script', ''))
    parent.append(SCRIPT(script_data))
    return parent
Ejemplo n.º 6
0
    def apply_method(self, r, **attr):
        """
            Entry point for REST API

            @param r: the request (S3Request)
            @param attr: REST controller parameters
        """

        if r.record and r.representation in ("html", "aadata"):

            T = current.T
            db = current.db
            s3db = current.s3db

            auth = current.auth
            is_admin = auth.s3_has_role("ADMIN")
            accessible = auth.s3_accessible_query

            # Profile widgets
            profile_widgets = []
            add_widget = profile_widgets.append

            dt_row_actions = self.dt_row_actions
            from s3 import FS

            # Organisations
            widget = {
                "label":
                T("My Organizations"),
                "icon":
                "organisation",
                "insert":
                False,
                "tablename":
                "org_organisation",
                "type":
                "datatable",
                "actions":
                dt_row_actions("org", "organisation"),
                "list_fields": [
                    "name",
                    (T("Type"),
                     "organisation_organisation_type.organisation_type_id"),
                    "phone",
                    (T("Email"), "email.value"),
                    "website",
                ],
            }
            if not is_admin:
                otable = s3db.org_organisation
                rows = db(accessible("update",
                                     "org_organisation")).select(otable.id)
                organisation_ids = [row.id for row in rows]
                widget["filter"] = FS("id").belongs(organisation_ids)
            add_widget(widget)

            # Facilities
            widget = {
                "label":
                T("My Facilities"),
                "icon":
                "facility",
                "insert":
                False,
                "tablename":
                "org_facility",
                "type":
                "datatable",
                "actions":
                dt_row_actions("org", "facility"),
                "list_fields": [
                    "name",
                    "code",
                    "site_facility_type.facility_type_id",
                    "organisation_id",
                    "location_id",
                ],
            }
            if not is_admin:
                ftable = s3db.org_facility
                rows = db(accessible("update",
                                     "org_facility")).select(ftable.id)
                facility_ids = [row.id for row in rows]
                widget["filter"] = FS("id").belongs(facility_ids)
            add_widget(widget)

            # Networks (only if user can update any records)
            widget_filter = None
            if not is_admin:
                gtable = s3db.org_group
                rows = db(accessible("update", "org_group")).select(gtable.id)
                group_ids = [row.id for row in rows]
                if group_ids:
                    widget_filter = FS("id").belongs(group_ids)
            if is_admin or widget_filter:
                widget = {
                    "label": T("My Networks"),
                    "icon": "org-network",
                    "insert": False,
                    "tablename": "org_group",
                    "filter": widget_filter,
                    "type": "datatable",
                    "actions": dt_row_actions("org", "group"),
                }
                add_widget(widget)

            # Groups (only if user can update any records)
            widget_filter = None
            if not is_admin:
                gtable = s3db.pr_group
                rows = db(accessible("update", "pr_group")).select(gtable.id)
                group_ids = [row.id for row in rows]
                if group_ids:
                    widget_filter = FS("id").belongs(group_ids)
            if is_admin or widget_filter:
                widget = {
                    "label":
                    T("My Groups"),
                    "icon":
                    "group",
                    "insert":
                    False,
                    "tablename":
                    "pr_group",
                    "filter":
                    widget_filter,
                    "type":
                    "datatable",
                    "actions":
                    dt_row_actions("hrm", "group"),
                    "list_fields": [
                        (T("Network"), "group_team.org_group_id"),
                        "name",
                        "description",
                        (T("Chairperson"), "chairperson"),
                    ],
                }
                add_widget(widget)

            # CMS Content
            from gluon.html import A, DIV, H2, TAG
            item = None
            title = T("Dashboard")
            if current.deployment_settings.has_module("cms"):
                name = "Dashboard"
                ctable = s3db.cms_post
                query = (ctable.name == name) & (ctable.deleted != True)
                row = db(query).select(ctable.id,
                                       ctable.title,
                                       ctable.body,
                                       limitby=(0, 1)).first()
                get_vars = {
                    "page": name,
                    "url": URL(args="dashboard", vars={}),
                }
                if row:
                    title = row.title
                    if is_admin:
                        item = DIV(
                            XML(row.body),
                            DIV(
                                A(
                                    T("Edit"),
                                    _href=URL(
                                        c="cms",
                                        f="post",
                                        args=[row.id, "update"],
                                        vars=get_vars,
                                    ),
                                    _class="action-btn",
                                ),
                                _class="cms-edit",
                            ),
                        )
                    else:
                        item = DIV(XML(row.body))
                elif is_admin:
                    item = DIV(
                        DIV(
                            A(
                                T("Edit"),
                                _href=URL(
                                    c="cms",
                                    f="post",
                                    args="create",
                                    vars=get_vars,
                                ),
                                _class="action-btn",
                            ),
                            _class="cms-edit",
                        ))

            # Rheader
            if r.representation == "html":
                profile_header = DIV(
                    DIV(
                        DIV(A(
                            T("Personal Profile"),
                            _href=URL(c="default", f="person"),
                            _class="action-btn",
                        ),
                            _class="dashboard-links right",
                            _style="padding:0.5rem 0;"),
                        H2(title),
                        _class="medium-6 columns end",
                    ),
                    _class="row",
                )
                if item:
                    # Append CMS content
                    profile_header = TAG[""](
                        profile_header,
                        DIV(
                            DIV(
                                item,
                                _class="medium-12 columns",
                            ),
                            _class="row",
                        ),
                    )
            else:
                profile_header = None

            # Configure profile
            tablename = r.tablename
            s3db.configure(
                tablename,
                profile_cols=2,
                profile_header=profile_header,
                profile_widgets=profile_widgets,
            )

            # Render profile
            from s3 import S3Profile
            profile = S3Profile()
            profile.tablename = tablename
            profile.request = r
            output = profile.profile(r, **attr)

            if r.representation == "html":
                output["title"] = \
                current.response.title = T("Personal Dashboard")
            return output
        else:
            raise HTTP(501, current.ERROR.BAD_METHOD)
Ejemplo n.º 7
0
def customize_deploy_mission(**attr):
    """
        Customize deploy_mission controller
    """

    db = current.db
    s3db = current.s3db
    s3 = current.response.s3
    MEMBER = T("Member")
    from gluon.html import DIV
    hr_comment =  \
        DIV(_class="tooltip",
            _title="%s|%s" % (MEMBER,
                              T("Enter some characters to bring up "
                                "a list of possible matches")))

    table = s3db.deploy_mission
    table.code.label = T("Operation Code")
    table.event_type_id.label = T("Disaster Type")
    table.organisation_id.readable = table.organisation_id.writable = False

    # Restrict Location to just Countries
    from s3.s3fields import S3Represent
    from s3.s3widgets import S3SelectChosenWidget
    field = table.location_id
    field.label = current.messages.COUNTRY
    field.requires = s3db.gis_country_requires
    field.widget = S3SelectChosenWidget()
    field.represent = S3Represent(lookup="gis_location", translate=True)

    rtable = s3db.deploy_response
    rtable.human_resource_id.label = MEMBER
    rtable.human_resource_id.comment = hr_comment

    from s3.s3validators import IS_ONE_OF
    atable = s3db.deploy_assignment
    atable.human_resource_id.label = MEMBER
    atable.human_resource_id.comment = hr_comment
    field = atable.job_title_id
    field.comment = None
    field.label = T("Sector")
    field.requires = IS_ONE_OF(
        db,
        "hrm_job_title.id",
        field.represent,
        filterby="type",
        filter_opts=(4, ),
    )

    # CRUD Strings
    s3.crud_strings["deploy_assignment"] = Storage(
        title_create=T("New Deployment"),
        title_display=T("Deployment Details"),
        title_list=T("Deployments"),
        title_update=T("Edit Deployment Details"),
        title_search=T("Search Deployments"),
        title_upload=T("Import Deployments"),
        subtitle_create=T("Add New Deployment"),
        label_list_button=T("List Deployments"),
        label_create_button=T("Add Deployment"),
        label_delete_button=T("Delete Deployment"),
        msg_record_created=T("Deployment added"),
        msg_record_modified=T("Deployment Details updated"),
        msg_record_deleted=T("Deployment deleted"),
        msg_list_empty=T("No Deployments currently registered"))

    # Custom prep
    standard_prep = s3.prep

    def custom_prep(r):
        # Call standard prep
        if callable(standard_prep):
            result = standard_prep(r)
        else:
            result = True

        if not r.component and r.method == "create":
            # Org is always IFRC
            otable = s3db.org_organisation
            query = (
                otable.name ==
                "International Federation of Red Cross and Red Crescent Societies"
            )
            organisation = db(query).select(
                otable.id,
                limitby=(0, 1),
            ).first()
            if organisation:
                r.table.organisation_id.default = organisation.id

        return result

    s3.prep = custom_prep

    return attr
Ejemplo n.º 8
0
def mavc_rheader(r, tabs=None):
    """ Custom rheaders """

    if r.representation != "html":
        return None

    from s3 import s3_rheader_resource, s3_rheader_tabs
    from gluon import A, DIV, H1, H2, TAG

    tablename, record = s3_rheader_resource(r)
    if record is None:
        return None

    T = current.T
    s3db = current.s3db

    if tablename != r.tablename:
        resource = s3db.resource(tablename,
                                 id = record.id if record else None,
                                 )
    else:
        resource = r.resource

    rheader = ""

    if tablename == "org_organisation":

        # Tabs
        if not tabs:
            INDIVIDUALS = current.deployment_settings.get_hrm_staff_label()

            tabs = [(T("About"), None),
                    (INDIVIDUALS, "human_resource"),
                    (T("Services"), "service_location"),
                    (T("Facilities"), "facility"),
                    (T("Projects"), "project"),
                    (T("Attachments"), "document"),
                    ]

        # Use OrganisationRepresent for title to get L10n name if available
        represent = s3db.org_OrganisationRepresent(acronym=False,
                                                   parent=False,
                                                   )
        title = represent(record.id)

        # Retrieve details for the rheader
        data = resource.select(["organisation_organisation_type.organisation_type_id",
                                "country",
                                "website",
                                ],
                               raw_data = True,
                               represent = True,
                               )
        row = data.rows[0]
        raw = row["_row"]

        # Construct subtitle
        subtitle_fields = ("org_organisation_organisation_type.organisation_type_id",
                           "org_organisation.country",
                           )
        items = []
        for fname in subtitle_fields:
            if raw[fname]:
                items.append(s3_unicode(row[fname]))
        subtitle = ", ".join(items)

        # Website
        website = row["org_organisation.website"]

        # Compose the rheader
        rheader = DIV(DIV(H1(title),
                          H2(subtitle),
                          website if record.website else "",
                          _class="rheader-details",
                          ),
                      )

    elif tablename == "project_project":

        if not tabs:
            tabs = [(T("About"), None),
                    (T("Locations"), "location"),
                    (T("Attachments"), "document"),
                    ]

        # Retrieve details for the rheader
        data = resource.select(["name",
                                "organisation_id",
                                ],
                               represent = True,
                               )
        row = data.rows[0]

        # Title and Subtitle
        title = row["project_project.name"]
        subtitle = row["project_project.organisation_id"]

        # Compose the rheader
        rheader = DIV(DIV(H1(title),
                          H2(subtitle),
                          _class="rheader-details",
                          ),
                      )

    elif tablename == "pr_person":

        if not tabs:
            tabs = [(T("Person Details"), None),
                    ]

        from s3 import s3_fullname
        title = s3_fullname(record)

        # Link organisation_id representation to staff tab
        linkto = URL(c = "org",
                     f = "organisation",
                     args = ["[id]", "human_resource"],
                     )
        htable = s3db.hrm_human_resource
        field = htable.organisation_id
        field.represent = s3db.org_OrganisationRepresent(show_link = True,
                                                         linkto = linkto,
                                                         )

        # Retrieve details for the rheader
        data = resource.select(["human_resource.job_title_id",
                                "human_resource.organisation_id",
                                ],
                               raw_data = True,
                               represent = True,
                               )
        row = data.rows[0]
        raw = row["_row"]

        # Construct subtitle
        organisation_id = raw["hrm_human_resource.organisation_id"]
        if organisation_id:
            subtitle = row["hrm_human_resource.organisation_id"]
            job_title_id = raw["hrm_human_resource.job_title_id"]
            if job_title_id:
                subtitle = TAG[""]("%s, " % row["hrm_human_resource.job_title_id"],
                                   subtitle,
                                   )

        # Compose the rheader
        rheader = DIV(DIV(H1(title),
                          H2(subtitle),
                          _class="rheader-details",
                          ),
                      )

    if tabs:
        rheader_tabs = s3_rheader_tabs(r, tabs)
        rheader.append(rheader_tabs)

    return rheader
Ejemplo n.º 9
0
    def __call__(self):

        output = {}

        T = current.T
        s3 = current.response.s3

        auth = current.auth
        settings = current.deployment_settings
        roles = current.session.s3.roles
        system_roles = auth.get_system_roles()

        # Allow editing of page content from browser using CMS module
        if settings.has_module("cms"):
            ADMIN = system_roles.ADMIN in roles
            s3db = current.s3db
            table = s3db.cms_post
            ltable = s3db.cms_post_module
            module = "default"
            resource = "index"
            query = (ltable.module == module) & \
                    ((ltable.resource == None) | \
                     (ltable.resource == resource)) & \
                    (ltable.post_id == table.id) & \
                    (table.deleted != True)
            item = current.db(query).select(table.id,
                                            table.body,
                                            limitby=(0, 1)).first()
            if item:
                if ADMIN:
                    item = DIV(XML(item.body),
                               BR(),
                               A(current.T("Edit"),
                                 _href=URL(c="cms", f="post",
                                           args=[item.id, "update"]),
                                 _class="action-btn"))
                else:
                    item = DIV(XML(item.body))
            elif ADMIN:
                if s3.crud.formstyle == "bootstrap":
                    _class = "btn"
                else:
                    _class = "action-btn"
                item = A(T("Edit"),
                         _href=URL(c="cms", f="post", args="create",
                                   vars={"module": module,
                                         "resource": resource
                                         }),
                         _class="%s cms-edit" % _class)
            else:
                item = ""
        else:
            item = ""
        output["item"] = item

        # Login/Registration forms
        self_registration = settings.get_security_self_registration()
        registered = False
        login_form = None
        login_div = None
        register_form = None
        register_div = None

        # Check logged in and permissions
        if system_roles.AUTHENTICATED not in roles:

            login_buttons = DIV(A(T("Login"),
                                  _id="show-login",
                                  _class="tiny secondary button"),
                                _id="login-buttons"
                                )
            # @ToDo: Move JS to static
            script = '''
$('#show-intro').click(function(e){
 e.preventDefault()
 $('#intro').slideDown(400, function() {
   $('#login_box').hide()
 });
})
$('#show-login').click(function(e){
 e.preventDefault()
 $('#login_form').show()
 $('#register_form').hide()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
            s3.jquery_ready.append(script)

            # This user isn't yet logged-in
            if current.request.cookies.has_key("registered"):
                # This browser has logged-in before
                registered = True

            if self_registration is True:
                # Provide a Registration box on front page
                login_buttons.append(A(T("Register"),
                                       _id="show-register",
                                       _class="tiny secondary button",
                                       # @ToDo: Move to CSS
                                       _style="margin-left:5px"))
                script = '''
$('#show-register').click(function(e){
 e.preventDefault()
 $('#login_form').hide()
 $('#register_form').show()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
                s3.jquery_ready.append(script)

                register_form = auth.register()
                register_div = DIV(H3(T("Register")),
                                   P(XML(T("If you would like to help, then please %(sign_up_now)s") % \
                                            dict(sign_up_now=B(T("sign-up now"))))))

                register_script = '''
$('#register-btn').click(function(e){
 e.preventDefault()
 $('#register_form').show()
 $('#login_form').hide()
})
$('#login-btn').click(function(e){
 e.preventDefault()
 $('#register_form').hide()
 $('#login_form').show()
})'''
                s3.jquery_ready.append(register_script)

            # Provide a login box on front page
            auth.messages.submit_button = T("Login")
            login_form = auth.login(inline=True)
            login_div = DIV(H3(T("Login")),
                            P(XML(T("Registered users can %(login)s to access the system") % \
                                  dict(login=B(T("login"))))))

        else:
            login_buttons = ""

        output["login_buttons"] = login_buttons
        output["self_registration"] = self_registration
        output["registered"] = registered
        output["login_div"] = login_div
        output["login_form"] = login_form
        output["register_div"] = register_div
        output["register_form"] = register_form

        output["items"] = network()()

        self._view(THEME, "index.html")
        return output
Ejemplo n.º 10
0
    def customise_deploy_mission_controller(**attr):

        db = current.db
        s3db = current.s3db
        s3 = current.response.s3
        MEMBER = T("Member")
        from gluon.html import DIV
        hr_comment =  \
            DIV(_class="tooltip",
                _title="%s|%s" % (MEMBER,
                                  current.messages.AUTOCOMPLETE_HELP))

        table = s3db.deploy_mission
        table.code.label = T("Appeal Code")
        table.event_type_id.label = T("Disaster Type")
        table.organisation_id.readable = table.organisation_id.writable = False

        # Restrict Location to just Countries
        from s3 import S3Represent, S3MultiSelectWidget
        field = table.location_id
        field.label = current.messages.COUNTRY
        field.requires = s3db.gis_country_requires
        field.widget = S3MultiSelectWidget(multiple=False)
        field.represent = S3Represent(lookup="gis_location", translate=True)

        rtable = s3db.deploy_response
        rtable.human_resource_id.label = MEMBER
        rtable.human_resource_id.comment = hr_comment

        _customise_assignment_fields()

        # Report options
        report_fact = [(T("Number of Missions"), "count(id)"),
                       (T("Number of Countries"), "count(location_id)"),
                       (T("Number of Disaster Types"), "count(event_type_id)"),
                       (T("Number of Responses"), "sum(response_count)"),
                       (T("Number of Deployments"), "sum(hrquantity)"),
                      ]
        report_axis = ["code",
                       "location_id",
                       "event_type_id",
                       "status",
                       ]
        report_options = Storage(rows = report_axis,
                                 cols = report_axis,
                                 fact = report_fact,
                                 defaults = Storage(rows = "location_id",
                                                    cols = "event_type_id",
                                                    fact = "sum(hrquantity)",
                                                    totals = True,
                                                    ),
                                 )

        s3db.configure("deploy_mission",
                       report_options = report_options,
                       )

        # CRUD Strings
        s3.crud_strings["deploy_assignment"] = Storage(
            label_create = T("New Deployment"),
            title_display = T("Deployment Details"),
            title_list = T("Deployments"),
            title_update = T("Edit Deployment Details"),
            title_upload = T("Import Deployments"),
            label_list_button = T("List Deployments"),
            label_delete_button = T("Delete Deployment"),
            msg_record_created = T("Deployment added"),
            msg_record_modified = T("Deployment Details updated"),
            msg_record_deleted = T("Deployment deleted"),
            msg_list_empty = T("No Deployments currently registered"))

        # Custom prep
        standard_prep = s3.prep
        def custom_prep(r):
            # Call standard prep
            if callable(standard_prep):
                result = standard_prep(r)
            else:
                result = True

            if r.interactive and not current.auth.s3_has_role("RDRT_ADMIN"):
                # Limit write-access to these fields to RDRT Admins:
                fields = ("name",
                          "event_type_id",
                          "location_id",
                          "code",
                          "status",
                          )
                table = r.resource.table
                for f in fields:
                    if f in table:
                        table[f].writable = False

            #if not r.component and r.method == "create":
            #    # Org is always IFRC
            #    otable = s3db.org_organisation
            #    query = (otable.name == "International Federation of Red Cross and Red Crescent Societies")
            #    organisation = db(query).select(otable.id,
            #                                    limitby = (0, 1),
            #                                    ).first()
            #    if organisation:
            #        r.table.organisation_id.default = organisation.id

            return result
        s3.prep = custom_prep

        return attr
Ejemplo n.º 11
0
def mavc_rheader(r, tabs=None):
    """ Custom rheaders """

    if r.representation != "html":
        return None

    from s3 import s3_rheader_resource, s3_rheader_tabs
    from gluon import A, DIV, H1, H2, TAG

    tablename, record = s3_rheader_resource(r)
    if record is None:
        return None

    T = current.T
    s3db = current.s3db

    if tablename != r.tablename:
        resource = s3db.resource(tablename,
                                 id = record.id if record else None,
                                 )
    else:
        resource = r.resource

    rheader = ""

    if tablename == "org_organisation":

        # Tabs
        if not tabs:
            INDIVIDUALS = current.deployment_settings.get_hrm_staff_label()

            tabs = [(T("About"), None),
                    (INDIVIDUALS, "human_resource"),
                    (T("Services"), "service_location"),
                    (T("Facilities"), "facility"),
                    (T("Projects"), "project"),
                    ]

        # Use OrganisationRepresent for title to get L10n name if available
        represent = s3db.org_OrganisationRepresent(acronym=False,
                                                   parent=False,
                                                   )
        title = represent(record.id)

        # Retrieve other details for the rheader
        data = resource.select(["organisation_organisation_type.organisation_type_id",
                                "website",
                                ],
                               represent = True,
                               )
        row = data.rows[0]
        subtitle = row["org_organisation_organisation_type.organisation_type_id"]
        website = row["org_organisation.website"]

        # Compile the rheader
        rheader = DIV(DIV(H1(title),
                          H2(subtitle),
                          website if record.website else "",
                          _class="rheader-details",
                          ),
                      )

    if tabs:
        rheader_tabs = s3_rheader_tabs(r, tabs)
        rheader.append(rheader_tabs)

    return rheader
    def __call__(self, field, value):

        mylogger.debug(message='current.request.vars:%s' %
                       current.request.vars)
        mylogger.debug(message='field._tablename:%s' % (str(field._tablename)))
        mylogger.debug(message='field:%s' % (str(field)))
        mylogger.debug(message='field.name:%s' % (str(field.name)))
        mylogger.debug(message='field.type:%s' % (str(field.type)))
        mylogger.debug(message='field.requires:%s' % (str(field.requires)))
        mylogger.debug(message='type(value):%s' % (str(type(value))))
        mylogger.debug(message='value:%s' % (str(value)))

        if current.request and current.request['function']:
            function = current.request['function']
        function_configuration = self.configuration[
            '*'] if self.configuration.keys().count(
                '*') > 0 else self.configuration[
                    function] if function in self.configuration.keys() else ''

        # query parameter not used yet...
        if 'query' in function_configuration:
            query = function_configuration['query'].as_json()
        else:
            query = None
        if 'disable_validate' in function_configuration:
            disable_validate = function_configuration['disable_validate']
        else:
            disable_validate = False
        if 'add_in_db' in function_configuration:
            add_in_db = function_configuration['add_in_db']
        else:
            add_in_db = False
        if 'multiple' in function_configuration:
            multiple = function_configuration['multiple']
        else:
            multiple = False
        if 'submit_on_select' in function_configuration:
            submit_on_select = function_configuration['submit_on_select']
        else:
            submit_on_select = False
        max_nb_item = 20
        if 'max_nb_item' in function_configuration:
            max_nb_item = function_configuration['max_nb_item']
        func_lambda = ''
        if 'func_lambda' in function_configuration:
            func_lambda = function_configuration['func_lambda']
        # use this option for no required fields only, to force the user to confirm that the field is empty
        if 'confirm_empty' in function_configuration:
            confirm_empty = function_configuration['confirm_empty']
        else:
            confirm_empty = current.request.vars[
                'confirm_empty_%s' % field.
                name] == 'on' if 'confirm_empty_%s' % field.name in current.request.vars else False

        is_not_a_reference = (field._tablename == self.ref_field._tablename)

        disabled = '_disabled' in self.attributes.keys()
        mylogger.debug(message='add_in_db:%s' % (str(add_in_db)))
        mylogger.debug(message='multiple:%s' % (str(multiple)))
        mylogger.debug(message='disabled:%s' % (str(disabled)))
        mylogger.debug(message='max_nb_item:%s' % (str(max_nb_item)))
        mylogger.debug(message='is_not_a_reference:%s' %
                       (str(is_not_a_reference)))

        if (value) and (type(value) is StringType) and (value == '0'):
            nb_item = 0
        elif (value) and (type(value) is StringType) and (value == '|0|'):
            nb_item = 0
        elif (value) and (type(value) is ListType) and (value[0] == 0):
            nb_item = 0
        elif (value) and (type(value) is ListType) and (value[0] == '|0|'):
            nb_item = 0
        elif (value) and (type(value) is ListType):
            nb_item = len(value)
        elif value and value != '':
            nb_item = 1
        else:
            nb_item = 0

        if value and not type(value) is ListType and value != '':
            value = [value]

        mylogger.debug(message='nb_item:%s' % (str(nb_item)))

        #
        # basic widget structure
        #
        checkboxes_form = DIV()
        suggestions_form = DIV(
            _id='%s_suggestions' % (self.uid),
            _class='CHIMITHEQUE_MULTIPLE_widget_suggestions')
        message_form = DIV(_id='%s_message' % (self.uid),
                           _class='CHIMITHEQUE_MULTIPLE_widget_message',
                           _style='display: none;')

        search_input_form = DIV(INPUT(_name='%s_search' % self.uid,
                                      _type='text',
                                      _title='%s_search' % self.uid),
                                suggestions_form,
                                _id='%s_search' % (self.uid),
                                _class='search_input_form')

        #
        # adding a confirm empty checkbox if needed
        #
        if confirm_empty:

            confirm_empty_form = DIV(
                INPUT(_name='confirm_empty_%s' % field.name,
                      _id='confirm_empty_%s' % field.name,
                      _type='checkbox',
                      _title=self.text_confirm_empty_form_field,
                      _class='CHIMITHEQUE_MULTIPLE_widget_confirm_empty',
                      _onclick='''$('div[id=%(uid)s]').empty();

                                         if ($('input[type=checkbox][name=confirm_empty_%(field_name)s]').is(':checked')) {
                                             $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected"></span>');
                                         }
                                         else {
                                             $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected">%(no_item_selected)s</span>');
                                         }
                             ''' % {
                          'uid': self.uid,
                          'field_name': field.name,
                          'no_item_selected': self.text_no_item_selected
                      }))

            confirm_empty_form.append(
                IMG(_src=self.image_disable_url,
                    _alt='disable',
                    _id='%s_disable' % self.uid,
                    _title=self.text_confirm_empty_form_field))
        else:
            confirm_empty_form = DIV()

        #
        # building the AJAX query parameters
        #
        _ajax_parameters = {
            'uid': self.uid,
            'multiple': multiple,
            'disable_validate': disable_validate,
            'add_in_db': add_in_db,
            'field_tablename': field._tablename,
            'ref_field_tablename': self.ref_field._tablename,
            'ref_field_name': self.ref_field.name,
            'max_nb_item': max_nb_item,
            'max_item_length': self.max_item_length,
            'lambda': func_lambda,
            'query': query,
            'text_close_list': str(self.text_close_list),
            'text_submit': str(self.text_submit),
            'image_select_url': self.image_select_url,
            'submit_on_select': submit_on_select
        }
        ajax_parameters = json.dumps(_ajax_parameters)

        #
        # adding the "add" image
        #
        if not disabled and add_in_db:

            search_input_form.append(
                IMG(_src=self.image_insert_url,
                    _alt='submit',
                    _id='%s_add' % self.uid,
                    _title=self.text_submit,
                    _style='visibility: hidden;',
                    _class='CHIMITHEQUE_MULTIPLE_widget_addindb',
                    _onclick='''
                                            // adding the search parameter to the JSON object
                                            ajax_parameters = %(ajax_parameters)s;
                                            ajax_parameters["search"] = $('input[name=%(uid)s_search]').val();
                                            var ret = $.ajax({
                                                       type: "POST",
                                                       url: "/%(application)s/chimitheque_multiple_widget/item_add",
                                                       data: JSON.stringify(ajax_parameters),
                                                       dataType: "json",
                                                       contentType: "application/json; charset=utf-8",
                                                       async: false
                                                     }).done(function(data) {
                                                            var _action = data['action'];
                                                            var _id = data['id'];
                                                            var _val = data['val'];
                                                            var _encval = data['encval'];

                                                            var funcCall = "addReplaceCheckBox%(uid)s" + "('" + _action + "','" + _id + "','" + _val + "','" + _encval + "')";
                                                            eval(funcCall);

                                                            $('img#%(uid)s_add').attr('style', 'visibility: hidden;');
                                                        });
                                                    ''' % {
                        'uid': self.uid,
                        'application': current.request.application,
                        'ajax_parameters': ajax_parameters
                    }))

        #
        # adding the selected items DIV
        #
        if nb_item == 0:

            if 'confirm_empty_%s' % field.name in current.request.vars:
                checkboxes_form.append(SPAN())
            else:
                checkboxes_form.append(
                    SPAN(XML(self.text_no_item_selected),
                         _id='%s_span_no_selected' % field.name))
            hidden_box_form = DIV(
                INPUT(_name='%s' % field.name,
                      _id='%s_hidden' % field.name,
                      _type='checkbox',
                      _value='',
                      _style='visibility: hidden; height: 0px;',
                      _checked='checked',
                      requires=field.requires))
        else:
            hidden_box_form = DIV()

            #
            # prepopulating the form
            #
            for i in range(0, nb_item):

                mylogger.debug(message='i:%i' % (i))

                prepop_value_id = None
                prepop_value_label = None

                if is_not_a_reference:
                    # just populating with the value passed in parameter
                    mylogger.debug(message='case 1')
                    prepop_value_id = value[i]
                    prepop_value_label = value[i]
                else:
                    # the parameter value is an id in the reference table, then querying the table
                    mylogger.debug(message='case 2')
                    prepop_value = current.db(
                        current.db['%s' % self.ref_field._tablename]['id'] == (
                            value[i])).select().first()
                    if prepop_value is not None:
                        prepop_value_label = current.db[
                            '%s' %
                            self.ref_field._tablename]._format(prepop_value)
                        prepop_value_id = value[i]

                mylogger.debug(message='prepop_value_id:%s' % prepop_value_id)
                mylogger.debug(message='prepop_value_label:%s' %
                               prepop_value_label)

                if prepop_value_id:
                    #
                    # adding the checkboxes or radio for the selected items
                    #
                    if multiple:
                        _input = INPUT(
                            _name='%s' % field.name,
                            _id='%s' % field.name,
                            _type='checkbox',
                            _class='CHIMITHEQUE_MULTIPLE_widget_selected',
                            _encvalue=self.uid,
                            _value=prepop_value_id,
                            value=True,
                            requires=field.requires)
                    else:
                        if is_not_a_reference:
                            _input = INPUT(
                                _name='%s' % field.name,
                                _id='%s' % field.name,
                                _type='radio',
                                _class='CHIMITHEQUE_MULTIPLE_widget_selected',
                                _encvalue=self.uid,
                                _value=
                                prepop_value_label,  # or prepop_value_id, don't mind...
                                value=
                                prepop_value_label,  # or prepop_value_id, don't mind...
                                requires=field.requires)
                        else:
                            _input = INPUT(
                                _name='%s' % field.name,
                                _id='%s' % field.name,
                                _type='radio',
                                _class='CHIMITHEQUE_MULTIPLE_widget_selected',
                                _encvalue=self.uid,
                                _value=prepop_value_id,
                                value=prepop_value_id,
                                requires=field.requires)
                    #
                    # then the delete selected item image
                    #
                    if not disabled and not multiple:

                        img_del = IMG(_src=self.image_delete_url,
                                      _alt=self.text_delete,
                                      _title=self.text_delete,
                                      _onclick='deleteItem%s();' % self.uid,
                                      _style='float: left;')

                    else:

                        img_del = SPAN()

                    #
                    # then the label
                    #
                    checkboxes_form.append(
                        DIV(_input,
                            img_del,
                            XML('%s' % prepop_value_label),
                            _class='CHIMITHEQUE_MULTIPLE_widget_selected'))

                else:
                    # TODO: code identical to line 232...

                    if 'confirm_empty_%s' % field.name in current.request.vars:
                        checkboxes_form.append(SPAN())
                    else:
                        checkboxes_form.append(
                            SPAN(XML(self.text_no_item_selected),
                                 _id='%s_span_no_selected' % field.name))
                    hidden_box_form = DIV(
                        INPUT(_name='%s' % field.name,
                              _id='%s_hidden' % field.name,
                              _type='checkbox',
                              _value='',
                              _style='visibility: hidden; height: 0px;',
                              _checked='checked',
                              requires=field.requires))

        #
        # building the final form
        #
        final_form = DIV(
            DIV(
                DIV(checkboxes_form,
                    _id='%s' % self.uid,
                    _class='%s_%s' %
                    (self.ref_field._tablename, self.ref_field.name)),
                **self.attributes))

        if not disabled:
            final_form.insert(0, confirm_empty_form)
            final_form.insert(0, search_input_form)

        # hidden field to export the uid for the pages
        uid_field = INPUT(_name='uid_%s' % field.name,
                          _type='hidden',
                          value='%s' % self.uid,
                          style='visibility: hidden; height: 0px;')

        return DIV(final_form,
                   uid_field,
                   hidden_box_form,
                   message_form,
                   SCRIPT(
                       """
                            function disableAddButton%(uid)s() {
                                $('#%(uid)s_add').attr('style', 'visibility: hidden;');

                            }

                            function displayMessage%(uid)s(message) {
                                $('#%(uid)s_message span').remove();
                                $('#%(uid)s_message').append('<span class="error">' + message + '</span>');

                            }

                            function deleteItem%(uid)s() {
                                $('#%(uid)s').find('div[class=CHIMITHEQUE_MULTIPLE_widget_selected]').remove();

                                console.log($('input[name=%(field_name)s]').length);
                                /* enabling the hidden field if needed */
                                if ($('input[name=%(field_name)s]').length <= 1) {
                                    console.log("input name '%(field_name)s' was the last element");
                                    $('input[id=%(field_name)s_hidden]').removeAttr('disabled');
                                    $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected">%(no_item_selected)s</span>');
                                }
                                else {
                                    console.log("input name '%(field_name)s' was not the last element");
                                }
                            }

                            function addReplaceCheckBox%(uid)s(action, id, val, encval) {
                                    console.log(arguments.callee.name);
                                    console.log('action:' + action);
                                    console.log('id:' + id);
                                    console.log('val:' + val);
                                    console.log('encval:' + encval);

                                    /* base64 decoding the string */
                                    val = Base64.decode(val);

                                    /* disabling the hidden field */
                                    $('input[id=%(field_name)s_hidden]').attr('disabled','true');
                                    $('span[id=%(field_name)s_span_no_selected]').remove();

                                    if ($('#%(uid)s').find('input[value="'+id+'"][encvalue='+encval+']').length != 0) {
                                        alert('%(text_item_already_selected)s');
                                    }
                                    else {
                                        var newDiv = $('<div class="CHIMITHEQUE_MULTIPLE_widget_selected"/>');
                                        var newDel = $('<img/>').attr({
                                            'src': '%(image_delete_url)s',
                                            'alt': '%(image_delete_alt)s',
                                            'title': '%(image_delete_title)s',
                                            'onclick': 'deleteItem%(uid)s();'
                                        });
                                        var newElem = $('<input/>').attr({
                                            'id': '%(field_name)s',
                                            'type': '%(type)s',
                                            'checked': 'checked',
                                            'name': '%(field_name)s',
                                            'value': id,
                                            'class': 'CHIMITHEQUE_MULTIPLE_widget_selected',
                                            'encvalue': encval,
                                        });
                                        if (action == 'replace') {
                                            newDiv.append(newDel);
                                        }
                                        newDiv.append(newElem);
                                        newDiv.append(val);
                                        if (action == 'replace') {
                                            $('#%(uid)s div').remove();
                                        }
                                        $('#%(uid)s').append(newDiv);
                                    }
                                    $('input[name=%(uid)s_search]').val('');

                                    $('#' + encval + '_suggestions div').remove();

                            }

                            function autocomplete%(uid)s() {
                                   $elem = $('input[type=text][name=%(uid)s_search]')
                                   var inputLength = $elem.val().length;
                                   if (inputLength >= %(minchar)s) {
                                        // adding the search parameter to the JSON object
                                        ajax_parameters = %(ajax_parameters)s;
                                        ajax_parameters["search"] = $elem.val();
                                        var ret = $.ajax({
                                                   type: "POST",
                                                   url: "/%(application)s/chimitheque_multiple_widget/item_selector",
                                                   data: JSON.stringify(ajax_parameters),
                                                   dataType: "json",
                                                   contentType: "application/json; charset=utf-8",
                                                   async: false
                                                 }).responseText;

                                        $('#%(uid)s_suggestions > *').remove();
                                        $('#%(uid)s_message').show();
                                        $('#%(uid)s_message').text('');
                                        if (ret.substr(0, 5) == 'ERROR') {
                                            $('#%(uid)s_message').text(ret);
                                            $('#%(uid)s_add').attr('style', 'visibility: hidden;');
                                        }else if (ret.substr(0, 4) == 'INDB'){
                                            $('#%(uid)s_add').attr('style', 'visibility: hidden;');
                                            $('#%(uid)s_suggestions').append(ret);
                                        }else if (ret.substr(0, 4) == 'NONE'){
                                            $('#%(uid)s_add').attr('style', 'visibility: visible;');
                                        }
                                        else {
                                            $('#%(uid)s_add').attr('style', 'visibility: visible;');
                                            $('#%(uid)s_suggestions').append(ret);
                                        }
                                   }
                            }

                            $(document).ready(function() {

                                jQuery('input[type=text][name=%(uid)s_search]').bind('paste', function(e) {
                                    setTimeout(function() {
                                        autocomplete%(uid)s();
                                    }, 0);
                                });

                                timer = 0;
                                jQuery('input[type=text][name=%(uid)s_search]').bind('keypress click paste input',function() {
                                        if (timer) {
                                            clearTimeout(timer);
                                        }
                                        timer = setTimeout(autocomplete%(uid)s, 400);                                  
                                });

                            });
                          """ % {
                           'disable_validate': disable_validate,
                           'add_in_db': add_in_db,
                           'multiple': multiple,
                           'uid': self.uid,
                           'field_tablename': field._tablename,
                           'field_name': field.name,
                           'field_label': field.label,
                           'ref_field_tablename': self.ref_field._tablename,
                           'ref_field_name': self.ref_field.name,
                           'minchar': self.minchar,
                           'image_delete_url': self.image_delete_url,
                           'image_delete_alt': self.text_delete,
                           'image_delete_title': self.text_delete,
                           'type': 'checkbox' if multiple else 'radio',
                           'max_nb_item': max_nb_item,
                           'max_item_length': self.max_item_length,
                           'lambda': func_lambda,
                           'image_delete_small': self.image_delete_url,
                           'text_item_already_selected':
                           self.text_item_already_selected,
                           'no_item_selected': self.text_no_item_selected,
                           'application': current.request.application,
                           'ajax_parameters': ajax_parameters
                       }),
                   _class='CHIMITHEQUE_MULTIPLE_widget')
Ejemplo n.º 13
0
    def customise_org_organisation_resource(r, tablename):

        s3db = current.s3db

        # Use comments field for org description
        table = s3db.org_organisation
        field = table.comments
        from gluon import DIV
        field.comment = DIV(
            _class="tooltip",
            _title="%s|%s" %
            (T("About"),
             T("Describe the organisation, e.g. mission, history and other relevant details"
               )))

        if not current.auth.is_logged_in():
            field = table.logo
            field.readable = field.writable = False
            # User can create records since we need this during registration,
            # but we don't want to let the user do this from the list view
            s3db.configure(
                "org_organisation",
                listadd=False,
            )

        # Custom filters to match the information provided
        from s3 import S3LocationFilter, \
                       S3OptionsFilter, \
                       S3TextFilter, \
                       s3_get_filter_opts

        filter_widgets = [
            S3TextFilter(
                [
                    "name",
                    "acronym",
                    #"website",
                    #"comments",
                ],
                label=T("Search"),
                comment=
                T("Search by organization name or acronym. You can use * as wildcard."
                  ),
            ),
            S3OptionsFilter(
                "organisation_organisation_type.organisation_type_id",
                label=T("Type"),
            ),
            S3OptionsFilter(
                "service_location.service_location_service.service_id",
                options=s3_get_filter_opts(
                    "org_service",
                    translate=True,
                ),
            ),
            S3OptionsFilter(
                "sector_organisation.sector_id",
                options=s3_get_filter_opts(
                    "org_sector",
                    translate=True,
                ),
                hidden=True,
            ),
        ]

        # CRUD Form
        from s3 import S3SQLCustomForm, \
                       S3SQLInlineComponent, \
                       S3SQLInlineLink, \
                       S3SQLVerticalSubFormLayout
        multitype = settings.get_org_organisation_types_multiple()
        crud_form = S3SQLCustomForm(
            "name",
            "acronym",
            S3SQLInlineLink(
                "organisation_type",
                field="organisation_type_id",
                filter=False,
                label=T("Type"),
                multiple=multitype,
            ),
            "country",
            S3SQLInlineLink(
                "sector",
                cols=3,
                label=T("Sectors"),
                field="sector_id",
                #required = True,
            ),
            (T("About"), "comments"),
            "website",
            S3SQLInlineComponent(
                "contact",
                name="email",
                label=T("Email"),
                #multiple = False,
                fields=[
                    ("", "value"),
                ],
                filterby=[
                    {
                        "field": "contact_method",
                        "options": "EMAIL",
                    },
                ],
            ),
            S3SQLInlineComponent(
                "facility",
                label=T("Main Office"),
                fields=[
                    "name",
                    "phone1",
                    "phone2",
                    #"email",
                    "location_id",
                ],
                layout=S3SQLVerticalSubFormLayout,
                filterby={
                    "field": "main_facility",
                    "options": True,
                },
                multiple=False,
            ),
            S3SQLInlineComponent(
                "document",
                fields=[
                    (T("Title"), "name"),
                    "file",
                ],
                filterby={
                    "field": "file",
                    "options": "",
                    "invert": True,
                },
                label=T("Files"),
                name="file",
            ),
            S3SQLInlineComponent(
                "document",
                fields=[
                    (T("Title"), "name"),
                    "url",
                ],
                filterby={
                    "field": "url",
                    "options": None,
                    "invert": True,
                },
                label=T("Links"),
                name="url",
            ),
        )

        s3db.configure(
            "org_organisation",
            filter_widgets=filter_widgets,
            crud_form=crud_form,
        )
Ejemplo n.º 14
0
def mavc_rheader(r, tabs=None):
    """ Custom rheaders """

    if r.representation != "html":
        return None

    from s3 import s3_rheader_resource, s3_rheader_tabs
    from gluon import A, DIV, H1, H2, TAG

    tablename, record = s3_rheader_resource(r)
    if record is None:
        return None

    T = current.T
    s3db = current.s3db

    if tablename != r.tablename:
        resource = s3db.resource(
            tablename,
            id=record.id if record else None,
        )
    else:
        resource = r.resource

    rheader = ""

    if tablename == "org_organisation":

        # Tabs
        if not tabs:
            INDIVIDUALS = current.deployment_settings.get_hrm_staff_label()

            tabs = [
                (T("About"), None),
                (INDIVIDUALS, "human_resource"),
                (T("Services"), "service_location"),
                (T("Facilities"), "facility"),
                (T("Projects"), "project"),
                (T("Attachments"), "document"),
            ]

        # Use OrganisationRepresent for title to get L10n name if available
        represent = s3db.org_OrganisationRepresent(
            acronym=False,
            parent=False,
        )
        title = represent(record.id)

        # Retrieve details for the rheader
        data = resource.select(
            [
                "organisation_organisation_type.organisation_type_id",
                "country",
                "website",
            ],
            raw_data=True,
            represent=True,
        )
        row = data.rows[0]
        raw = row["_row"]

        # Construct subtitle
        subtitle_fields = (
            "org_organisation_organisation_type.organisation_type_id",
            "org_organisation.country",
        )
        items = []
        for fname in subtitle_fields:
            if raw[fname]:
                items.append(s3_unicode(row[fname]))
        subtitle = ", ".join(items)

        # Website
        website = row["org_organisation.website"]

        # Compose the rheader
        rheader = DIV(
            DIV(
                H1(title),
                H2(subtitle),
                website if record.website else "",
                _class="rheader-details",
            ), )

    elif tablename == "project_project":

        if not tabs:
            tabs = [
                (T("About"), None),
                (T("Locations"), "location"),
                (T("Attachments"), "document"),
            ]

        # Retrieve details for the rheader
        data = resource.select(
            [
                "name",
                "organisation_id",
            ],
            represent=True,
        )
        row = data.rows[0]

        # Title and Subtitle
        title = row["project_project.name"]
        subtitle = row["project_project.organisation_id"]

        # Compose the rheader
        rheader = DIV(DIV(
            H1(title),
            H2(subtitle),
            _class="rheader-details",
        ), )

    elif tablename == "pr_person":

        if not tabs:
            tabs = [
                (T("Person Details"), None),
            ]

        from s3 import s3_fullname
        title = s3_fullname(record)

        # Link organisation_id representation to staff tab
        linkto = URL(
            c="org",
            f="organisation",
            args=["[id]", "human_resource"],
        )
        htable = s3db.hrm_human_resource
        field = htable.organisation_id
        field.represent = s3db.org_OrganisationRepresent(
            show_link=True,
            linkto=linkto,
        )

        # Retrieve details for the rheader
        data = resource.select(
            [
                "human_resource.job_title_id",
                "human_resource.organisation_id",
            ],
            raw_data=True,
            represent=True,
        )
        row = data.rows[0]
        raw = row["_row"]

        # Construct subtitle
        organisation_id = raw["hrm_human_resource.organisation_id"]
        if organisation_id:
            subtitle = row["hrm_human_resource.organisation_id"]
            job_title_id = raw["hrm_human_resource.job_title_id"]
            if job_title_id:
                subtitle = TAG[""](
                    "%s, " % row["hrm_human_resource.job_title_id"],
                    subtitle,
                )

        # Compose the rheader
        rheader = DIV(DIV(
            H1(title),
            H2(subtitle),
            _class="rheader-details",
        ), )

    if tabs:
        rheader_tabs = s3_rheader_tabs(r, tabs)
        rheader.append(rheader_tabs)

    return rheader
Ejemplo n.º 15
0
  def grid(query,
           fields=None,
           field_id=None,
           left=None,
           join=None, #!
           orderby=None,
           groupby=None,
           groupfields=None, #!
           having=None, #!
           headers={},
           searchable=False, #True,
           sortable=True,
           paginate=20,
           pagename="page", #!
           deletable=False, #! True,
           editable=True,
           details=False, #! True,
           selectable=None,
           create=False, #!True,
           csv=False, #!True,
           links=None,
           links_in_grid=True,
           upload = '<default>',
           args=[],
           user_signature = False, #!True,
           maxtextlengths={},
           maxtextlength=20,
           onvalidation=None,
           oncreate=None,
           onupdate=None,
           ondelete=None,
           sorter_icons=(XML('&#x2191;'),XML('&#x2193;')),
           ui = 'web2py',
           showbuttontext=True,
           _class="web2py_grid",
           formname='web2py_grid',
           search_widget='default',
           ignore_rw = False,
           formstyle = 'table3cols',
           exportclasses = None,
           formargs={},
           createargs={},
           editargs={},
           viewargs={},
          ):

      # jQuery UI ThemeRoller classes (empty if ui is disabled)
      if ui == 'jquery-ui':
          ui = dict(widget='ui-widget',
                    header='ui-widget-header',
                    content='ui-widget-content',
                    default='ui-state-default',
                    cornerall='ui-corner-all',
                    cornertop='ui-corner-top',
                    cornerbottom='ui-corner-bottom',
                    button='ui-button-text-icon-primary',
                    buttontext='ui-button-text',
                    buttonadd='ui-icon ui-icon-plusthick',
                    buttonback='ui-icon ui-icon-arrowreturnthick-1-w',
                    buttonexport='ui-icon ui-icon-transferthick-e-w',
                    buttondelete='ui-icon ui-icon-trash',
                    buttonedit='ui-icon ui-icon-pencil',
                    buttontable='ui-icon ui-icon-triangle-1-e',
                    buttonview='ui-icon ui-icon-zoomin',
                    )
      elif ui == 'web2py':
          ui = dict(widget='',
                    header='',
                    content='',
                    default='',
                    cornerall='',
                    cornertop='',
                    cornerbottom='',
                    button='button btn',
                    buttontext='buttontext button',
                    buttonadd='icon plus icon-plus',
                    buttonback='icon leftarrow icon-arrow-left',
                    buttonexport='icon downarrow icon-download',
                    buttondelete='icon trash icon-trash',
                    buttonedit='icon pen icon-pencil',
                    buttontable='icon rightarrow icon-arrow-right',
                    buttonview='icon magnifier icon-zoom-in',
                    )
      elif not isinstance(ui,dict):
          raise RuntimeError,'SQLFORM.grid ui argument must be a dictionary'
      
      db = query._db
      T = current.T
      request = current.request
      session = current.session
      response = current.response
      wenabled = (not user_signature or (session.auth and session.auth.user))
      create = wenabled and create
      editable = wenabled and editable
      deletable = wenabled and deletable

      def url(**b):
          b['args'] = args+b.get('args',[])
          b['hash_vars']=False
          b['user_signature'] = user_signature
          return URL(**b)

      def url2(**b):
          b['args'] = request.args+b.get('args',[])
          b['hash_vars']=False
          b['user_signature'] = user_signature
          return URL(**b)

      referrer = session.get('_web2py_grid_referrer_'+formname, url())
      # if not user_signature every action is accessible
      # else forbid access unless
      # - url is based url
      # - url has valid signature (vars are not signed, only path_info)
      # = url does not contain 'create','delete','edit' (readonly)
      if user_signature:
          if not(
              '/'.join(str(a) for a in args) == '/'.join(request.args) 
#              or
#              URL.verify(request,user_signature=user_signature,
#                         hash_vars=False) 
                  or not (
                  'create' in request.args or
                  'delete' in request.args or
                  'edit' in request.args)):
              session.flash = T('not authorized')                
              redirect(referrer)

      def gridbutton(buttonclass='buttonadd', buttontext='Add',
                     buttonurl=url(args=[]), callback=None,
                     delete=None, trap=True):
          if showbuttontext:
              if callback:
                  return A(SPAN(_class=ui.get(buttonclass)),
                           SPAN(T(buttontext),_title=buttontext,
                                _class=ui.get('buttontext')),
                           callback=callback,delete=delete,
                           _class=trap_class(ui.get('button'),trap))
              else:
                  return A(SPAN(_class=ui.get(buttonclass)),
                           SPAN(T(buttontext),_title=buttontext,
                                _class=ui.get('buttontext')),
                           _href=buttonurl,
                           _class=trap_class(ui.get('button'),trap))
          else:
              if callback:
                  return A(SPAN(_class=ui.get(buttonclass)),
                           callback=callback,delete=delete,
                           _title=buttontext,
                           _class=trap_class(ui.get('buttontext'),trap))
              else:
                  return A(SPAN(_class=ui.get(buttonclass)),
                           _href=buttonurl,_title=buttontext,
                           _class=trap_class(ui.get('buttontext'),trap))
      dbset = db(query)
      tablenames = db._adapter.tables(dbset.query)
      #if left!=None: tablenames+=db._adapter.tables(left)
      
      if left!=None:
        if isinstance(left,list):
          for _left in left:
            tablenames=tablenames+db._adapter.tables(_left)
        else:
          tablenames=tablenames+db._adapter.tables(left)
      if join!=None:
        if isinstance(join,list):
          for _join in join:
            tablenames=tablenames+db._adapter.tables(_join)
        else:
          tablenames=tablenames+db._adapter.tables(join)
      
      tables = [db[tablename] for tablename in tablenames]
      if not fields:
          fields = reduce(lambda a,b:a+b,
                          [[field for field in table] for table in tables])
      if not field_id:
          field_id = tables[0]._id
      columns = [str(field) for field in fields \
                     if field._tablename in tablenames]

      if not str(field_id) in [str(f) for f in fields]:
          fields.append(field_id)
      table = field_id.table
      tablename = table._tablename
      if upload=='<default>':
          upload = lambda filename: url(args=['download',filename])
          if len(request.args)>1 and request.args[-2]=='download':
              stream = response.download(request,db)
              raise HTTP(200,stream,**response.headers)

      def buttons(edit=False,view=False,record=None):
          buttons = DIV(gridbutton('buttonback', 'Back', referrer),
                        _class='form_header row_buttons %(header)s %(cornertop)s' % ui)
          if edit and (not callable(edit) or edit(record)):
              args = ['edit',table._tablename,request.args[-1]]
              buttons.append(gridbutton('buttonedit', 'Edit',
                                        url(args=args)))
          if view:
              args = ['view',table._tablename,request.args[-1]]
              buttons.append(gridbutton('buttonview', 'View',
                                        url(args=args)))
          if record and links:
              for link in links:
                  if isinstance(link,dict):
                      buttons.append(link['body'](record))
                  elif link(record):
                      buttons.append(link(record))
          return buttons

      formfooter = DIV(
          _class='form_footer row_buttons %(header)s %(cornerbottom)s' % ui)

      create_form = update_form = view_form = search_form = None
      sqlformargs = dict(formargs)

      if create and len(request.args)>1 and request.args[-2] == 'new':
          table = db[request.args[-1]]
          sqlformargs.update(createargs)
          create_form = SQLFORM(
              table, ignore_rw=ignore_rw, formstyle=formstyle,
              _class='web2py_form',
              **sqlformargs)
          create_form.process(formname=formname,
                  next=referrer,
                  onvalidation=onvalidation,
                  onsuccess=oncreate)
          res = DIV(buttons(), create_form, formfooter, _class=_class)
          res.create_form = create_form
          res.update_form = update_form
          res.view_form = view_form
          res.search_form = search_form
          return res

      elif details and len(request.args)>2 and request.args[-3]=='view':
          table = db[request.args[-2]]
          record = table(request.args[-1]) or redirect(URL('error'))
          sqlformargs.update(viewargs)
          view_form = SQLFORM(table, record, upload=upload, ignore_rw=ignore_rw,
                         formstyle=formstyle, readonly=True, _class='web2py_form',
                         **sqlformargs)
          res = DIV(buttons(edit=editable, record=record), view_form,
                    formfooter, _class=_class)
          res.create_form = create_form
          res.update_form = update_form
          res.view_form = view_form
          res.search_form = search_form
          return res
#      elif editable and len(request.args)>2 and request.args[-3]=='edit':
#          table = db[request.args[-2]]
#          record = table(request.args[-1]) or redirect(URL('error'))
#          sqlformargs.update(editargs)
#          update_form = SQLFORM(table, record, upload=upload, ignore_rw=ignore_rw,
#                              formstyle=formstyle, deletable=deletable,
#                              _class='web2py_form',
#                              submit_button=T('Submit'),
#                              delete_label=T('Check to delete'),
#                              **sqlformargs)
#          update_form.process(formname=formname,
#                            onvalidation=onvalidation,
#                            onsuccess=onupdate,
#                            next=referrer)
#          res = DIV(buttons(view=details, record=record),
#                    update_form, formfooter, _class=_class)
#          res.create_form = create_form
#          res.update_form = update_form
#          res.view_form = view_form
#          res.search_form = search_form
#          return res
      elif deletable and len(request.args)>2 and request.args[-3]=='delete':
          table = db[request.args[-2]]
          if ondelete:
              ondelete(table,request.args[-1])
          ret = db(table[table._id.name]==request.args[-1]).delete()
          return ret

      exportManager = dict(
          csv_with_hidden_cols=(ExporterCSV,'CSV (hidden cols)'),
          csv=(ExporterCSV,'CSV'),
          xml=(ExporterXML, 'XML'),
          html=(ExporterHTML, 'HTML'),
          tsv_with_hidden_cols=\
              (ExporterTSV,'TSV (Excel compatible, hidden cols)'),
          tsv=(ExporterTSV, 'TSV (Excel compatible)'))
      if not exportclasses is None:
          exportManager.update(exportclasses)

      export_type = request.vars._export_type
      if export_type:
          order = request.vars.order or ''
          if sortable:
              if order and not order=='None':
                  if order[:1]=='~':
                      sign, rorder = '~', order[1:]
                  else:
                      sign, rorder = '', order
                  tablename,fieldname = rorder.split('.',1)
                  orderby=db[tablename][fieldname]
                  if sign=='~':
                      orderby=~orderby

          table_fields = [f for f in fields if f._tablename in tablenames]
          if export_type in ('csv_with_hidden_cols','tsv_with_hidden_cols'):
              if request.vars.keywords:
                  try:
                      dbset = dbset(SQLFORM.build_query(
                              fields,request.vars.get('keywords','')))
                      rows = dbset.select(cacheable=True)
                  except Exception:
                      response.flash = T('Internal Error')
                      rows = []
              else:
                  rows = dbset.select(cacheable=True)
          else:
              rows = dbset.select(left=left,orderby=orderby,
                                  cacheable=True*columns)

          if export_type in exportManager:
              value = exportManager[export_type]
              clazz = value[0] if hasattr(value, '__getitem__') else value
              oExp = clazz(rows)
              filename = '.'.join(('rows', oExp.file_ext))
              response.headers['Content-Type'] = oExp.content_type
              response.headers['Content-Disposition'] = \
                  'attachment;filename='+filename+';'
              raise HTTP(200, oExp.export(),**response.headers)

      elif request.vars.records and not isinstance(
          request.vars.records,list):
          request.vars.records=[request.vars.records]
      elif not request.vars.records:
          request.vars.records=[]

      session['_web2py_grid_referrer_'+formname] = url2(vars=request.vars)
      console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
      error = None
      
      search_actions = DIV(_class='web2py_search_actions')
      if create:
        search_actions.append(gridbutton(buttonclass='buttonadd',
                    buttontext=T('Add'), buttonurl=url(args=['new',tablename])))
        console.append(search_actions)

#      if create:
#          add = gridbutton(
#                  buttonclass='buttonadd',
#                  buttontext='Add',
#                  buttonurl=url(args=['new',tablename]))
#          if not searchable:
#              console.append(add)
      else:
          add = ''

      if searchable:
          sfields = reduce(lambda a,b:a+b,
                           [[f for f in t if f.readable] for t in tables])
          if isinstance(search_widget,dict):
              search_widget = search_widget[tablename]
          if search_widget=='default':
              search_menu = SQLFORM.search_menu(sfields)
              search_widget = lambda sfield, url: CAT(add,FORM(
                  INPUT(_name='keywords',_value=request.vars.keywords,
                        _id='web2py_keywords',_onfocus="jQuery('#w2p_query_fields').change();jQuery('#w2p_query_panel').slideDown();"),
                  INPUT(_type='submit',_value=T('Search'),_class="btn"),
                  INPUT(_type='submit',_value=T('Clear'),_class="btn",
                        _onclick="jQuery('#web2py_keywords').val('');"),
                  _method="GET",_action=url),search_menu)
          form = search_widget and search_widget(sfields,url()) or ''
          console.append(form)
          keywords = request.vars.get('keywords','')
          try:
              if callable(searchable):
                  subquery = searchable(sfields, keywords)
              else:
                  subquery = SQLFORM.build_query(sfields, keywords)
          except RuntimeError:
              subquery = None
              error = T('Invalid query')
      else:
          subquery = None

      if subquery:
          dbset = dbset(subquery)
      try:
          if groupby:
            nrows = len(dbset.select(*groupfields, join=join, left=left, groupby=groupby, having=having, cacheable=True))
          elif left or join:
            nrows = dbset.select('count(*)',join=join,left=left, cacheable=True).first()['count(*)']
          
#          if left or groupby:
#              c = 'count(*)'
#              nrows = dbset.select(c,left=left,cacheable=True,
#                                   groupby=groupby).first()[c]
          else:
              nrows = dbset.count()
      except:
          nrows = 0
          error = T('Unsupported query')

      order = request.vars.order or ''
      if sortable:
        if order and not order=='None':
          if groupby:
            if str(groupby[0]).find(order)>-1:
              tablename,fieldname = order.split('~')[-1].split('.',1)
              sort_field = db[tablename][fieldname]
              exception = sort_field.type in ('date','datetime','time')
              if exception:
                  orderby = (order[:1]=='~' and sort_field) or ~sort_field
              else:
                  orderby = (order[:1]=='~' and ~sort_field) or sort_field
            else:
              tablename,fieldname = order.split('~')[-1].split('.',1)
              gfields = str(groupfields[0]).split(",")
              for gfield in gfields:
                if len(gfield.split(" AS "))>1:
                  if gfield.split(" AS ")[1]==fieldname:
                    if str(gfield.split(" AS ")[0]).find("SUM")>-1:
                      sort_field = db[tablename][fieldname].sum()
                    elif str(gfield.split(" AS ")[0]).find("COUNT")>-1:
                      sort_field = db[tablename][fieldname].count()
                    elif str(gfield.split(" AS ")[0]).find("MIN")>-1:
                      sort_field = db[tablename][fieldname].min()
                    elif str(gfield.split(" AS ")[0]).find("MAX")>-1:
                      sort_field = db[tablename][fieldname].max()
                    elif str(gfield.split(" AS ")[0]).find("LENGTH")>-1:
                      sort_field = db[tablename][fieldname].len()
                    else:
                      break
                    orderby = (order[:1]=='~' and ~sort_field) or sort_field
                    break
          else:
            tablename,fieldname = order.split('~')[-1].split('.',1)
            sort_field = db[tablename][fieldname]
            exception = sort_field.type in ('date','datetime','time')
            if exception:
              orderby = (order[:1]=='~' and sort_field) or ~sort_field
            else:
              orderby = (order[:1]=='~' and ~sort_field) or sort_field

      head = TR(_class=ui.get('header'))
      if selectable:
          head.append(TH(_class=ui.get('default')))
      for field in fields:
          if columns and not str(field) in columns: continue
          if not field.readable: continue
          key = str(field)
          header = headers.get(str(field),
                               hasattr(field,'label') and field.label or key)
          if sortable:
              if key == order:
                  key, marker = '~'+order, sorter_icons[0]
              elif key == order[1:]:
                  marker = sorter_icons[1]
              else:
                  marker = ''
              header = A(header,marker,_href=url(vars=dict(
                          keywords=request.vars.keywords or '',
                          order=key)),_class=trap_class())
          head.append(TH(header, _class=ui.get('default')))

      if links and links_in_grid:
          for link in links:
              if isinstance(link,dict):
                  head.append(TH(link['header'], _class=ui.get('default')))

      # Include extra column for buttons if needed.
      include_buttons_column = (details or editable or deletable or
          (links and links_in_grid and
           not all([isinstance(link, dict) for link in links])))
      if include_buttons_column:
        head.insert(0,TH(_class=ui.get('default','')))
        #  head.append(TH(_class=ui.get('default')))

      paginator = UL()
      if paginate and paginate<nrows:
          npages,reminder = divmod(nrows,paginate)
          if reminder: npages+=1
          try: page = int(request.vars.page or 1)-1
          except ValueError: page = 0
          limitby = (paginate*page,paginate*(page+1))
          def self_link(name,p):
              d = dict(page=p+1)
              if order: d['order']=order
              if request.vars.keywords: d['keywords']=request.vars.keywords
              return A(name,_href=url(vars=d),_class=trap_class())
          NPAGES = 5 # window is 2*NPAGES
          if page>NPAGES+1:
              paginator.append(LI(self_link('<<',0)))
          if page>NPAGES:
              paginator.append(LI(self_link('<',page-1)))
          pages = range(max(0,page-NPAGES),min(page+NPAGES,npages))
          for p in pages:
              if p == page:
                  paginator.append(LI(A(p+1,_onclick='return false'),
                                      _class=trap_class('current')))
              else:
                  paginator.append(LI(self_link(p+1,p)))
          if page<npages-NPAGES:
              paginator.append(LI(self_link('>',page+1)))
          if page<npages-NPAGES-1:
              paginator.append(LI(self_link('>>',npages-1)))
      else:
          limitby = None

      try:
          table_fields = [f for f in fields if f._tablename in tablenames]
          if groupby:
            rows = dbset.select(*groupfields,join=join,left=left,groupby=groupby,having=having,orderby=orderby,limitby=limitby,cacheable=True)
          else:
            rows = dbset.select(join=join,left=left,orderby=orderby,limitby=limitby,cacheable=True,*table_fields)
            
#          rows = dbset.select(left=left,orderby=orderby,
#                              groupby=groupby,limitby=limitby,
#                              cacheable=True,*table_fields)

      except SyntaxError:
          rows = None
          error = T("Query Not Supported")
      if nrows:
          message = error or T('%(nrows)s records found') % dict(nrows=nrows)
          console.append(DIV(message,_class='web2py_counter'))

      if rows:
          htmltable = TABLE(THEAD(head))
          tbody = TBODY()
          numrec=0
          for row in rows:
              if numrec % 2 == 0:
                  classtr = 'even'
              else:
                  classtr = 'odd'
              numrec+=1
              id = row[field_id] #@ReservedAssignment
              if id:
                  rid = id
                  if callable(rid): ### can this ever be callable?
                      rid = rid(row)
                  tr = TR(_id=rid, _class='%s %s' % (classtr, 'with_id'))
              else:
                  tr = TR(_class=classtr)
              if selectable:
                  tr.append(INPUT(_type="checkbox",_name="records",_value=id,
                                  value=request.vars.records))
              for field in fields:
                  if not str(field) in columns: continue
                  if not field.readable: continue
                  if field.type=='blob': continue
                  value = row[field]
                  maxlength = maxtextlengths.get(str(field),maxtextlength)
                  if field.represent:
                      try:
                          value=field.represent(value,row)
                      except Exception:
                          try:
                              value=field.represent(value,row[field._tablename])
                          except Exception:
                              pass
                  elif field.type=='boolean':
                      value = INPUT(_type="checkbox",_checked = value,
                                    _disabled=True)
                  elif field.type=='upload':
                      if value:
                          if callable(upload):
                              value = A(current.T('file'), _href=upload(value))
                          elif upload:
                              value = A(current.T('file'),
                                        _href='%s/%s' % (upload, value))
                      else:
                          value = ''
                  if isinstance(value,str):
                      value = truncate_string(value,maxlength)
                  elif not isinstance(value,DIV):
                      value = field.formatter(value)
                  if not include_buttons_column:
                      tr.append(TD(value,_style="padding:10px;"))
                  else:
                      tr.append(TD(value))
              row_buttons = TD(_class='row_buttons')
              if links and links_in_grid:
                  for link in links:
                      if isinstance(link, dict):
                          tr.append(TD(link['body'](row)))
                      else:
                          if link(row):
                              row_buttons.append(link(row))
              if include_buttons_column:
                  if details and (not callable(details) or details(row)):
                      row_buttons.append(gridbutton(
                              'buttonview', 'View',
                              url(args=['view',tablename,id])))
                  if editable and (not callable(editable) or editable(row)):
                      row_buttons.append(gridbutton(
                              'buttonedit', 'Edit',
                              url(args=['edit',tablename,id])))
                  if deletable and (not callable(deletable) or deletable(row)):
                      row_buttons.append(gridbutton(
                              'buttondelete', 'Delete',
                              callback=url(args=['delete',tablename,id]),
                              delete='tr'))
                  #tr.append(row_buttons)
                  tr.insert(0,row_buttons)
              tbody.append(tr)
          htmltable.append(tbody)
          htmltable = DIV(htmltable,_style='width:100%;overflow-x:auto')
          if selectable:
              htmltable = FORM(htmltable,INPUT(_type="submit"))
              if htmltable.process(formname=formname).accepted:#
                  htmltable.vars.records = htmltable.vars.records or []
                  htmltable.vars.records = htmltable.vars.records if type(htmltable.vars.records) == list else [htmltable.vars.records]
                  records = [int(r) for r in htmltable.vars.records]
                  selectable(records)
                  redirect(referrer)
      else:
          htmltable = DIV(current.T('No records found'))

      if csv and nrows:
          export_links =[]
          for k,v in sorted(exportManager.items()):
              label = v[1] if hasattr(v, "__getitem__") else k
              link = url2(vars=dict(
                      order=request.vars.order or '',
                      _export_type=k,
                      keywords=request.vars.keywords or ''))
              export_links.append(A(T(label),_href=link))
          export_menu = \
              DIV(T('Export:'),_class="w2p_export_menu",*export_links)
      else:
          export_menu = None

      res = DIV(console,DIV(htmltable,_class="web2py_table"),
                _class='%s %s' % (_class, ui.get('widget')))
      if paginator.components:
          res.append(
              DIV(paginator,
                  _class="web2py_paginator %(header)s %(cornerbottom)s"%ui))
      if export_menu: res.append(export_menu)
      res.create_form = create_form
      res.update_form = update_form
      res.view_form = view_form
      res.search_form = search_form
      return res
Ejemplo n.º 16
0
    def __call__(self):

        output = {}

        T = current.T
        request = current.request
        response = current.response
        s3 = response.s3

        # Check logged in and permissions
        auth = current.auth
        settings = current.deployment_settings
        roles = current.session.s3.roles
        system_roles = auth.get_system_roles()
        AUTHENTICATED = system_roles.AUTHENTICATED

        # Login/Registration forms
        self_registration = current.deployment_settings.get_security_registration_visible()
        registered = False
        login_form = None
        login_div = None
        register_form = None
        register_div = None

        if AUTHENTICATED not in roles:

            #login_buttons = DIV(A(T("Login"),
            #                      _id = "show-login",
            #                      _class = "tiny secondary button",
            #                      ),
            #                    _id = "login-buttons"
            #                    )
            script = '''
$('#show-mailform').click(function(e){
 e.preventDefault()
 $('#intro').slideDown(400, function() {
   $('#login_box').hide()
 });
})
$('#show-login').click(function(e){
 e.preventDefault()
 $('#login_form').show()
 $('#register_form').hide()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
            s3.jquery_ready.append(script)

            # This user isn't yet logged-in
            if "registered" in request.cookies:
                # This browser has logged-in before
                registered = True

            if self_registration is True:
                # Provide a Registration box on front page
                #login_buttons.append(A(T("Register"),
                #                       _id = "show-register",
                #                       _class = "tiny secondary button",
                #                       _style = "margin-left:5px",
                #                       ))
                #script = '''
#$('#show-register').click(function(e){
# e.preventDefault()
# $('#login_form').hide()
# $('#register_form').show()
# $('#login_box').show()
# $('#intro').slideUp()
#})'''
                #s3.jquery_ready.append(script)

                register_form = auth.register()
                register_div = DIV(H3(T("Register")),
                                   P(XML(T("If you would like to help, then please <b>sign up now</b>"))))
                register_script = '''
$('#register-btn').click(function(e){
 e.preventDefault()
 $('#register_form').show()
 $('#login_form').hide()
})
$('#login-btn').click(function(e){
 e.preventDefault()
 $('#register_form').hide()
 $('#login_form').show()
})'''
                s3.jquery_ready.append(register_script)

            # Provide a login box on front page
            auth.messages.submit_button = T("Login")
            login_form = auth.login(inline=True)
            login_div = DIV(H3(T("Login")),
                            P(XML(T("Registered users can <b>login</b> to access the system"))))
        #else:
        #    login_buttons = ""

        #output["login_buttons"] = login_buttons
        output["self_registration"] = self_registration
        output["registered"] = registered
        output["login_div"] = login_div
        output["login_form"] = login_form
        output["register_div"] = register_div
        output["register_form"] = register_form

        # Slick slider
        if s3.debug:
            s3.scripts.append("/%s/static/scripts/slick.js" % request.application)
        else:
            s3.scripts.append("/%s/static/scripts/slick.min.js" % request.application)
        script = '''
$(document).ready(function(){
 $('#title-image').slick({
  autoplay:true,
  autoplaySpeed:5000,
  speed:1000,
  fade:true,
  cssEase:'linear'
 });
});'''
        s3.jquery_ready.append(script)

        s3.stylesheets.append("../themes/%s/homepage.css" % THEME)
        self._view(THEME, "index.html")

        return output
Ejemplo n.º 17
0
    def customise_org_organisation_resource(r, tablename):

        s3db = current.s3db

        # Simplify form
        table = s3db.org_organisation
        field = table.comments
        from gluon import DIV
        field.comment = DIV(
            _class="tooltip",
            _title="%s|%s" %
            (T("About"),
             T("Describe the organisation, e.g. mission, history and other relevant details"
               )))

        if not current.auth.is_logged_in():
            field = table.logo
            field.readable = field.writable = False
            # User can create records since we need this during registration,
            # but we don't want to let the user do this from the list view
            s3db.configure(
                "org_organisation",
                listadd=False,
            )

        # Custom filters to match the information provided
        from s3 import S3LocationFilter, S3OptionsFilter, S3TextFilter
        filter_widgets = [
            S3TextFilter(
                [
                    "name",
                    "acronym",
                    #"website",
                    #"comments",
                ],
                label=T("Search"),
                comment=
                T("Search by organization name or acronym. You can use * as wildcard."
                  ),
            ),
            #S3OptionsFilter("sector_organisation.sector_id",
            #                ),
            S3OptionsFilter(
                "organisation_organisation_type.organisation_type_id",
                label=T("Type"),
            ),
            #S3LocationFilter("organisation_location.location_id",
            #                 label = T("Areas Served"),
            #                 levels = ("L1", "L2", "L3", "L4"),
            #                 #hidden = True,
            #                 ),
        ]

        # CRUD Form
        from s3 import S3SQLCustomForm, \
                       S3SQLInlineComponent, \
                       S3SQLInlineLink, \
                       S3SQLVerticalSubFormLayout
        multitype = settings.get_org_organisation_types_multiple()
        crud_form = S3SQLCustomForm(
            "name",
            "acronym",
            S3SQLInlineLink(
                "organisation_type",
                field="organisation_type_id",
                filter=False,
                label=T("Type"),
                multiple=multitype,
            ),
            "country",
            S3SQLInlineLink(
                "sector",
                cols=3,
                label=T("Sectors"),
                field="sector_id",
                #required = True,
            ),
            (T("About"), "comments"),
            "website",
            S3SQLInlineComponent(
                "facility",
                label=T("Main Facility"),
                fields=[
                    "name",
                    "phone1",
                    "phone2",
                    "email",
                    "location_id",
                ],
                layout=S3SQLVerticalSubFormLayout,
                filterby={
                    "field": "main_facility",
                    "options": True,
                },
                multiple=False,
            ),
        )

        s3db.configure(
            "org_organisation",
            filter_widgets=filter_widgets,
            crud_form=crud_form,
        )
Ejemplo n.º 18
0
def mavc_rheader(r, tabs=None):
    """ Custom rheaders """

    if r.representation != "html":
        return None

    from s3 import s3_rheader_resource, s3_rheader_tabs
    from gluon import A, DIV, H1, H2, TAG

    tablename, record = s3_rheader_resource(r)
    if record is None:
        return None

    T = current.T
    s3db = current.s3db

    if tablename != r.tablename:
        resource = s3db.resource(
            tablename,
            id=record.id if record else None,
        )
    else:
        resource = r.resource

    rheader = ""

    if tablename == "org_organisation":

        # Tabs
        if not tabs:
            INDIVIDUALS = current.deployment_settings.get_hrm_staff_label()

            tabs = [
                (T("About"), None),
                (INDIVIDUALS, "human_resource"),
                (T("Services"), "service_location"),
                (T("Facilities"), "facility"),
                (T("Projects"), "project"),
            ]

        # Use OrganisationRepresent for title to get L10n name if available
        represent = s3db.org_OrganisationRepresent(
            acronym=False,
            parent=False,
        )
        title = represent(record.id)

        # Retrieve details for the rheader
        data = resource.select(
            [
                "organisation_organisation_type.organisation_type_id",
                "country",
                "website",
            ],
            raw_data=True,
            represent=True,
        )
        row = data.rows[0]
        raw = row["_row"]

        # Construct subtitle
        subtitle_fields = (
            "org_organisation_organisation_type.organisation_type_id",
            "org_organisation.country",
        )
        items = []
        for fname in subtitle_fields:
            if raw[fname]:
                items.append(s3_unicode(row[fname]))
        subtitle = ", ".join(items)

        # Website
        website = row["org_organisation.website"]

        # Compile the rheader
        rheader = DIV(
            DIV(
                H1(title),
                H2(subtitle),
                website if record.website else "",
                _class="rheader-details",
            ), )

    if tabs:
        rheader_tabs = s3_rheader_tabs(r, tabs)
        rheader.append(rheader_tabs)

    return rheader
Ejemplo n.º 19
0
 def toolbar(self):
     from gluon.html import DIV, SCRIPT, BEAUTIFY, TAG, A
     BUTTON = TAG.button
     admin = URL("admin",
                 "default",
                 "design",
                 extension='html',
                 args=current.request.application)
     from gluon.dal import DAL
     dbstats = []
     dbtables = {}
     infos = DAL.get_instances()
     for k, v in iteritems(infos):
         dbstats.append(
             TABLE(*[
                 TR(PRE(row[0]), '%.2fms' % (row[1] * 1000))
                 for row in v['dbstats']
             ]))
         dbtables[k] = dict(defined=v['dbtables']['defined']
                            or '[no defined tables]',
                            lazy=v['dbtables']['lazy']
                            or '[no lazy tables]')
     u = web2py_uuid()
     backtotop = A('Back to top', _href="#totop-%s" % u)
     # Convert lazy request.vars from property to Storage so they
     # will be displayed in the toolbar.
     request = copy.copy(current.request)
     request.update(vars=current.request.vars,
                    get_vars=current.request.get_vars,
                    post_vars=current.request.post_vars)
     return DIV(BUTTON('design', _onclick="document.location='%s'" % admin),
                BUTTON('request',
                       _onclick="jQuery('#request-%s').slideToggle()" % u),
                BUTTON('response',
                       _onclick="jQuery('#response-%s').slideToggle()" % u),
                BUTTON('session',
                       _onclick="jQuery('#session-%s').slideToggle()" % u),
                BUTTON('db tables',
                       _onclick="jQuery('#db-tables-%s').slideToggle()" %
                       u),
                BUTTON('db stats',
                       _onclick="jQuery('#db-stats-%s').slideToggle()" % u),
                DIV(BEAUTIFY(request),
                    backtotop,
                    _class="w2p-toolbar-hidden",
                    _id="request-%s" % u),
                DIV(BEAUTIFY(current.session),
                    backtotop,
                    _class="w2p-toolbar-hidden",
                    _id="session-%s" % u),
                DIV(BEAUTIFY(current.response),
                    backtotop,
                    _class="w2p-toolbar-hidden",
                    _id="response-%s" % u),
                DIV(BEAUTIFY(dbtables),
                    backtotop,
                    _class="w2p-toolbar-hidden",
                    _id="db-tables-%s" % u),
                DIV(BEAUTIFY(dbstats),
                    backtotop,
                    _class="w2p-toolbar-hidden",
                    _id="db-stats-%s" % u),
                SCRIPT("jQuery('.w2p-toolbar-hidden').hide()"),
                _id="totop-%s" % u)
Ejemplo n.º 20
0
    def test_DIV(self):
        # Empty DIV()
        self.assertEqual(DIV().xml(), b'<div></div>')
        self.assertEqual(DIV('<>', _a='1', _b='2').xml(),
                         b'<div a="1" b="2">&lt;&gt;</div>')
        # attributes can be updated like in a dict
        div = DIV('<>', _a='1')
        div['_b'] = '2'
        self.assertEqual(div.xml(),
                         b'<div a="1" b="2">&lt;&gt;</div>')
        # also with a mapping
        div.update(_b=2, _c=3)
        self.assertEqual(div.xml(),
                         b'<div a="1" b="2" c="3">&lt;&gt;</div>')
        # length of the DIV is the number of components
        self.assertEqual(len(DIV('a', 'bc')), 2)
        # also if empty, DIV is True in a boolean evaluation
        self.assertTrue(True if DIV() else False)
        # parent and siblings
        a = DIV(SPAN('a'), DIV('b'))
        s = a.element('span')
        d = s.parent
        d['_class'] = 'abc'
        self.assertEqual(a.xml(), b'<div class="abc"><span>a</span><div>b</div></div>')
        self.assertEqual([el.xml() for el in s.siblings()], [b'<div>b</div>'])
        self.assertEqual(s.sibling().xml(), b'<div>b</div>')
        # siblings with wrong args
        self.assertEqual(s.siblings('a'), [])
        # siblings with good args
        self.assertEqual(s.siblings('div')[0].xml(), b'<div>b</div>')
        # Check for siblings with wrong kargs and value
        self.assertEqual(s.siblings(a='d'), [])
        # Check for siblings with good kargs and value
        # Can't figure this one out what is a right value here??
        # Commented for now...
        # self.assertEqual(s.siblings(div='<div>b</div>'), ???)
        # No other sibling should return None
        self.assertEqual(DIV(P('First element')).element('p').sibling(), None)
        # --------------------------------------------------------------------------------------------------------------
        # This use unicode to hit xmlescape() line :
        #     """
        #     elif isinstance(data, unicode):
        #         data = data.encode('utf8', 'xmlcharrefreplace')
        #     """
        self.assertEqual(DIV(u'Texte en français avec des caractères accentués...').xml(),
                         b'<div>Texte en fran\xc3\xa7ais avec des caract\xc3\xa8res accentu\xc3\xa9s...</div>')
        # --------------------------------------------------------------------------------------------------------------
        self.assertEqual(DIV('Test with an ID', _id='id-of-the-element').xml(),
                         b'<div id="id-of-the-element">Test with an ID</div>')
        self.assertEqual(DIV().element('p'), None)

        # Corner case for raise coverage of one line
        # I think such assert fail cause of python 2.6
        # Work under python 2.7
        # with self.assertRaises(SyntaxError) as cm:
        #     DIV(BR('<>')).xml()
        # self.assertEqual(cm.exception[0], '<br/> tags cannot have components')

        # test .get('attrib')
        self.assertEqual(DIV('<p>Test</p>', _class="class_test").get('_class'), 'class_test')
Ejemplo n.º 21
0
    def rdrt_member_profile_header(r):
        """ Custom profile header to allow update of RDRT roster status """

        record = r.record
        if not record:
            return ""

        person_id = record.person_id
        from s3 import s3_fullname, s3_avatar_represent
        name = s3_fullname(person_id)

        table = r.table

        # Organisation
        comments = table.organisation_id.represent(record.organisation_id)

        from s3 import s3_unicode
        from gluon.html import A, DIV, H2, LABEL, P, SPAN

        # Add job title if present
        job_title_id = record.job_title_id
        if job_title_id:
            comments = (SPAN("%s, " % \
                             s3_unicode(table.job_title_id.represent(job_title_id))),
                             comments)

        # Determine the current roster membership status (active/inactive)
        atable = current.s3db.deploy_application
        status = atable.active
        query = atable.human_resource_id == r.id
        row = current.db(query).select(atable.id,
                                       atable.active,
                                       limitby=(0, 1)).first()
        if row:
            active = 1 if row.active else 0
            status_id = row.id
            roster_status = status.represent(row.active)
        else:
            active = None
            status_id = None
            roster_status = current.messages.UNKNOWN_OPT

        if status_id and \
           current.auth.s3_has_permission("update",
                                          "deploy_application",
                                          record_id=status_id):
            # Make inline-editable
            roster_status = A(roster_status,
                              data = {"status": active},
                              _id = "rdrt-roster-status",
                              _title = T("Click to edit"),
                              )
            s3 = current.response.s3
            script = "/%s/static/themes/IFRC/js/rdrt.js" % r.application
            if script not in s3.scripts:
                s3.scripts.append(script)
            script = '''$.rdrtStatus('%(url)s','%(active)s','%(inactive)s','%(submit)s')'''
            from gluon import URL
            options = {"url": URL(c="deploy", f="application",
                                  args=["%s.s3json" % status_id]),
                       "active": status.represent(True),
                       "inactive": status.represent(False),
                       "submit": T("Save"),
                       }
            s3.jquery_ready.append(script % options)
        else:
            # Read-only
            roster_status = SPAN(roster_status)

        # Render profile header
        return DIV(A(s3_avatar_represent(person_id,
                                         tablename="pr_person",
                                         _class="media-object",
                                         ),
                     _class="pull-left",
                     ),
                   H2(name),
                   P(comments),
                   DIV(LABEL(status.label + ": "), roster_status),
                   _class="profile-header",
                   )
Ejemplo n.º 22
0
    def __call__(self):

        output = {}

        T = current.T
        s3 = current.response.s3

        auth = current.auth
        settings = current.deployment_settings
        roles = current.session.s3.roles
        system_roles = auth.get_system_roles()

        # Allow editing of page content from browser using CMS module
        if settings.has_module("cms"):
            ADMIN = system_roles.ADMIN in roles
            s3db = current.s3db
            table = s3db.cms_post
            ltable = s3db.cms_post_module
            module = "default"
            resource = "index"
            query = (ltable.module == module) & \
                    ((ltable.resource == None) | \
                     (ltable.resource == resource)) & \
                    (ltable.post_id == table.id) & \
                    (table.deleted != True)
            item = current.db(query).select(table.id,
                                            table.body,
                                            limitby=(0, 1)).first()
            if item:
                if ADMIN:
                    item = DIV(
                        XML(item.body), BR(),
                        A(current.T("Edit"),
                          _href=URL(c="cms",
                                    f="post",
                                    args=[item.id, "update"]),
                          _class="action-btn"))
                else:
                    item = DIV(XML(item.body))
            elif ADMIN:
                if s3.crud.formstyle == "bootstrap":
                    _class = "btn"
                else:
                    _class = "action-btn"
                item = A(T("Edit"),
                         _href=URL(c="cms",
                                   f="post",
                                   args="create",
                                   vars={
                                       "module": module,
                                       "resource": resource
                                   }),
                         _class="%s cms-edit" % _class)
            else:
                item = ""
        else:
            item = ""
        output["item"] = item

        # Login/Registration forms
        self_registration = settings.get_security_self_registration()
        registered = False
        login_form = None
        login_div = None
        register_form = None
        register_div = None

        # Check logged in and permissions
        if system_roles.AUTHENTICATED not in roles:

            login_buttons = DIV(A(T("Login"),
                                  _id="show-login",
                                  _class="tiny secondary button"),
                                _id="login-buttons")
            # @ToDo: Move JS to static
            script = '''
$('#show-intro').click(function(e){
 e.preventDefault()
 $('#intro').slideDown(400, function() {
   $('#login_box').hide()
 });
})
$('#show-login').click(function(e){
 e.preventDefault()
 $('#login_form').show()
 $('#register_form').hide()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
            s3.jquery_ready.append(script)

            # This user isn't yet logged-in
            if current.request.cookies.has_key("registered"):
                # This browser has logged-in before
                registered = True

            if self_registration is True:
                # Provide a Registration box on front page
                login_buttons.append(
                    A(
                        T("Register"),
                        _id="show-register",
                        _class="tiny secondary button",
                        # @ToDo: Move to CSS
                        _style="margin-left:5px"))
                script = '''
$('#show-register').click(function(e){
 e.preventDefault()
 $('#login_form').hide()
 $('#register_form').show()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
                s3.jquery_ready.append(script)

                register_form = auth.register()
                register_div = DIV(H3(T("Register")),
                                   P(XML(T("If you would like to help, then please %(sign_up_now)s") % \
                                            dict(sign_up_now=B(T("sign-up now"))))))

                register_script = '''
$('#register-btn').click(function(e){
 e.preventDefault()
 $('#register_form').show()
 $('#login_form').hide()
})
$('#login-btn').click(function(e){
 e.preventDefault()
 $('#register_form').hide()
 $('#login_form').show()
})'''
                s3.jquery_ready.append(register_script)

            # Provide a login box on front page
            auth.messages.submit_button = T("Login")
            login_form = auth.login(inline=True)
            login_div = DIV(H3(T("Login")),
                            P(XML(T("Registered users can %(login)s to access the system") % \
                                  dict(login=B(T("login"))))))

        else:
            login_buttons = ""

        output["login_buttons"] = login_buttons
        output["self_registration"] = self_registration
        output["registered"] = registered
        output["login_div"] = login_div
        output["login_form"] = login_form
        output["register_div"] = register_div
        output["register_form"] = register_form

        output["items"] = network()()

        self._view(THEME, "index.html")
        return output
Ejemplo n.º 23
0
def LOAD(c=None,
         f='index',
         args=None,
         vars=None,
         extension=None,
         target=None,
         ajax=False,
         ajax_trap=False,
         url=None,
         user_signature=False,
         timeout=None,
         times=1,
         content='loading...',
         post_vars=Storage(),
         **attr):
    """  LOADs a component into the action's document

    Args:
        c(str): controller
        f(str): function
        args(tuple or list): arguments
        vars(dict): vars
        extension(str): extension
        target(str): id of the target
        ajax(bool): True to enable AJAX bahaviour
        ajax_trap(bool): True if `ajax` is set to `True`, traps
            both links and forms "inside" the target
        url(str): overrides `c`,`f`,`args` and `vars`
        user_signature(bool): adds hmac signature to all links
            with a key that is different for every user
        timeout(int): in milliseconds, specifies the time to wait before
            starting the request or the frequency if times is greater than
            1 or "infinity"
        times(integer or str): how many times the component will be requested
            "infinity" or "continuous" are accepted to reload indefinitely the
            component
    """
    from gluon.html import TAG, DIV, URL, SCRIPT, XML
    if args is None:
        args = []
    vars = Storage(vars or {})
    target = target or 'c' + str(random.random())[2:]
    attr['_id'] = target
    request = current.request
    if '.' in f:
        f, extension = f.rsplit('.', 1)
    if url or ajax:
        url = url or URL(request.application,
                         c,
                         f,
                         r=request,
                         args=args,
                         vars=vars,
                         extension=extension,
                         user_signature=user_signature)
        # timing options
        if isinstance(times, basestring):
            if times.upper() in ("INFINITY", "CONTINUOUS"):
                times = "Infinity"
            else:
                raise TypeError("Unsupported times argument %s" % times)
        elif isinstance(times, int):
            if times <= 0:
                raise ValueError(
                    "Times argument must be greater than zero, 'Infinity' or None"
                )
        else:
            raise TypeError("Unsupported times argument type %s" % type(times))
        if timeout is not None:
            if not isinstance(timeout, (int, long)):
                raise ValueError("Timeout argument must be an integer or None")
            elif timeout <= 0:
                raise ValueError(
                    "Timeout argument must be greater than zero or None")
            statement = "$.web2py.component('%s','%s', %s, %s);" \
                % (url, target, timeout, times)
            attr['_data-w2p_timeout'] = timeout
            attr['_data-w2p_times'] = times
        else:
            statement = "$.web2py.component('%s','%s');" % (url, target)
        attr['_data-w2p_remote'] = url
        if target is not None:
            return DIV(content, **attr)

    else:
        if not isinstance(args, (list, tuple)):
            args = [args]
        c = c or request.controller
        other_request = Storage(request)
        other_request['env'] = Storage(request.env)
        other_request.controller = c
        other_request.function = f
        other_request.extension = extension or request.extension
        other_request.args = List(args)
        other_request.vars = vars
        other_request.get_vars = vars
        other_request.post_vars = post_vars
        other_response = Response()
        other_request.env.path_info = '/' + \
            '/'.join([request.application, c, f] +
                     [str(a) for a in other_request.args])
        other_request.env.query_string = \
            vars and URL(vars=vars).split('?')[1] or ''
        other_request.env.http_web2py_component_location = \
            request.env.path_info
        other_request.cid = target
        other_request.env.http_web2py_component_element = target
        other_request.restful = types.MethodType(request.restful.__func__,
                                                 other_request)
        # A bit nasty but needed to use LOAD on action decorates with @request.restful()
        other_response.view = '%s/%s.%s' % (c, f, other_request.extension)

        other_environment = copy.copy(current.globalenv)  # NASTY

        other_response._view_environment = other_environment
        other_response.generic_patterns = \
            copy.copy(current.response.generic_patterns)
        other_environment['request'] = other_request
        other_environment['response'] = other_response

        ## some magic here because current are thread-locals

        original_request, current.request = current.request, other_request
        original_response, current.response = current.response, other_response
        page = run_controller_in(c, f, other_environment)
        if isinstance(page, dict):
            other_response._vars = page
            other_response._view_environment.update(page)
            page = run_view_in(other_response._view_environment)

        current.request, current.response = original_request, original_response
        js = None
        if ajax_trap:
            link = URL(request.application,
                       c,
                       f,
                       r=request,
                       args=args,
                       vars=vars,
                       extension=extension,
                       user_signature=user_signature)
            js = "$.web2py.trap_form('%s','%s');" % (link, target)
        script = js and SCRIPT(js, _type="text/javascript") or ''
        return TAG[''](DIV(XML(page), **attr), script)
Ejemplo n.º 24
0
    def __call__(self):

        request = current.request
        response = current.response
        s3 = response.s3
        settings = current.deployment_settings

        if request.env.request_method == "POST":
            # Processs Form
            vars = request.post_vars
            result = current.msg.send_email(
                to=settings.get_mail_approver(),
                subject=vars.subject,
                message=vars.message,
                reply_to=vars.address,
            )
            if result:
                response.confirmation = "Thankyou for your message - we'll be in touch shortly"

        T = current.T

        # Allow editing of page content from browser using CMS module
        if settings.has_module("cms"):
            ADMIN = current.auth.get_system_roles().ADMIN in \
                    current.session.s3.roles
            s3db = current.s3db
            table = s3db.cms_post
            ltable = s3db.cms_post_module
            module = "default"
            resource = "contact"
            query = (ltable.module == module) & \
                    ((ltable.resource == None) | \
                     (ltable.resource == resource)) & \
                    (ltable.post_id == table.id) & \
                    (table.deleted != True)
            item = current.db(query).select(table.id,
                                            table.body,
                                            limitby=(0, 1)).first()
            if item:
                if ADMIN:
                    item = DIV(
                        XML(item.body), BR(),
                        A(T("Edit"),
                          _href=URL(c="cms",
                                    f="post",
                                    args=[item.id, "update"]),
                          _class="action-btn"))
                else:
                    item = DIV(XML(item.body))
            elif ADMIN:
                if s3.crud.formstyle == "bootstrap":
                    _class = "btn"
                else:
                    _class = "action-btn"
                item = A(T("Edit"),
                         _href=URL(c="cms",
                                   f="post",
                                   args="create",
                                   vars={
                                       "module": module,
                                       "resource": resource
                                   }),
                         _class="%s cms-edit" % _class)
            else:
                item = ""
        else:
            item = ""

        form = FORM(TABLE(
            TR(LABEL("Your name:", SPAN(" *", _class="req"), _for="name")),
            TR(INPUT(_name="name", _type="text", _size=62, _maxlength="255")),
            TR(
                LABEL("Your e-mail address:",
                      SPAN(" *", _class="req"),
                      _for="address")),
            TR(INPUT(_name="address", _type="text", _size=62,
                     _maxlength="255")),
            TR(LABEL("Subject:", SPAN(" *", _class="req"), _for="subject")),
            TR(INPUT(_name="subject", _type="text", _size=62,
                     _maxlength="255")),
            TR(LABEL("Message:", SPAN(" *", _class="req"), _for="name")),
            TR(TEXTAREA(_name="message", _class="resizable", _rows=5,
                        _cols=62)),
            TR(INPUT(_type="submit", _value="Send e-mail")),
        ),
                    _id="mailform")

        if s3.cdn:
            if s3.debug:
                s3.scripts.append(
                    "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js"
                )
            else:
                s3.scripts.append(
                    "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"
                )

        else:
            if s3.debug:
                s3.scripts.append("/%s/static/scripts/jquery.validate.js" %
                                  request.application)
            else:
                s3.scripts.append("/%s/static/scripts/jquery.validate.min.js" %
                                  request.application)

        # @ToDo: Move to static with i18n
        s3.jquery_ready.append('''$('#mailform').validate({
 errorClass:'req',
 rules:{
  name:{
   required:true
  },
  subject:{
   required:true
  },
  message:{
   required:true
  },
  name:{
   required:true
  },
  address: {
   required:true,
   email:true
  }
 },
 messages:{
  name:"Enter your name",
  subject:"Enter a subject",
  message:"Enter a message",
  address:{
   required:"Please enter a valid email address",
   email:"Please enter a valid email address"
  }
 },
 errorPlacement:function(error,element){
  error.appendTo(element.parents('tr').prev().children())
 },
 submitHandler:function(form){
  form.submit()
 }
})''')
        # @ToDo: Move to static
        s3.jquery_ready.append(
            '''$('textarea.resizable:not(.textarea-processed)').each(function() {
    // Avoid non-processed teasers.
    if ($(this).is(('textarea.teaser:not(.teaser-processed)'))) {
        return false;
    }
    var textarea = $(this).addClass('textarea-processed'), staticOffset = null;
    // When wrapping the text area, work around an IE margin bug. See:
    // http://jaspan.com/ie-inherited-margin-bug-form-elements-and-haslayout
    $(this).wrap('<div class="resizable-textarea"><span></span></div>')
    .parent().append($('<div class="grippie"></div>').mousedown(startDrag));
    var grippie = $('div.grippie', $(this).parent())[0];
    grippie.style.marginRight = (grippie.offsetWidth - $(this)[0].offsetWidth) +'px';
    function startDrag(e) {
        staticOffset = textarea.height() - e.pageY;
        textarea.css('opacity', 0.25);
        $(document).mousemove(performDrag).mouseup(endDrag);
        return false;
    }
    function performDrag(e) {
        textarea.height(Math.max(32, staticOffset + e.pageY) + 'px');
        return false;
    }
    function endDrag(e) {
        $(document).unbind("mousemove", performDrag).unbind("mouseup", endDrag);
        textarea.css('opacity', 1);
    }
});''')

        response.title = "Contact | NYC:Prepared"
        self._view(THEME, "contact.html")
        return dict(
            form=form,
            item=item,
        )
Ejemplo n.º 25
0
def fmt_impressions_by_usrid(question, f=None, c=None, T=None):
    """Used for actions where we need identify SINGLE physically presented impression: review or loans.
    Args:
        question: rik, ean, isxn (title?) of the book which we want find for review or loan
        f: action if clicked; if None you can set jQuery .click() later to call ajax (based on <a data_id="nnn">)
        c: controller for the action (if it is different as the current one)
    Returns: tuple (imp_id, candidates)
        imp_id:  provided only if we have SINGLE impression found (to allow make the action without offering the list), otherwise this is None
        candidates: formatted output for possible candidates (empty in case of SINGLE impression)
    """

    if T is None:
        T = current.T

    def imp_info(imp):
        iorder = imp[1]
        lbl = SPAN('%s-%s' % (rik, iorder))
        if uses_iid:
            lbl.append(' ')
            lbl.append(B(imp[2]))
        if uses_sgn:
            lbl.append(' ')
            lbl.append(imp[3])
        imp_id = "%s" % imp[0]
        return A(lbl, _href=(URL(c, f, args=imp_id) if c else URL(f, args=imp_id)) if f else "#", _data_id=imp_id, _class='btn btn-warning')

    libstyle = get_libstyle()
    rik_short_pos = get_rik_short_pos(libstyle)
    uses_iid = libstyle['id'][0] == 'I'
    uses_sgn = libstyle['sg'][0] == 'G'
    books, overflow, imp_id = impressions_by_usrid(question, stop_if_single=True)
    if imp_id:
        return imp_id, ''
    '''boooks is list of dictionaries, one dict for one publication, keys are:
          'owned_book_id', 'answer_id', 'rik', 'fastinfo' and 'imp', where 'imp' is list of impressions (of single book)
          each item in 'imp' is tuple: (id, iorder, iid)
    imp_id will be set if we have exactly SINGLE impression - this terminates the formatting immediately
    '''

    fmt = []
    if books:
        for book in books:
            rik = book['rik']
            rik = rik[rik_short_pos::-1] if rik else ''
            impressions = book['imp']
            cnt_imp = len(impressions)
            tit, aut, pub, puy = parse_fastinfo(book['fastinfo'])
            book_div = DIV(*get_book_line(tit, aut), _class='btn btn-default btn-sm')
            if cnt_imp > 1:
                # summary as visible
                fmt.append(DIV(DIV('%s x' % cnt_imp, _class='btn btn-info btn-sm'), book_div))
                # detail rows as hidden
                imps = DIV(_style="overflow: auto;")
                for imp in impressions:
                    imps.append(imp_info(imp))
                fmt.append(imps)
            else:  # single impression
                # summary=detail as visible
                fmt.append(DIV(imp_info(impressions[0]), book_div))
        result = DIV()
        if overflow:
            result.append(DIV(T("Je zobrazen omezený počet - méně výtisků než odpovídá zadání. Použij přesnější zadání.")))
        result.append(DIV(*fmt))
    else:
        result = DIV(T("Zadání neodpovídá žádný výtisk."))
    return None, result
Ejemplo n.º 26
0
    def __call__(self):

        output = {}

        T = current.T
        request = current.request
        response = current.response
        s3 = response.s3

        # Check logged in and permissions
        auth = current.auth
        settings = current.deployment_settings
        roles = current.session.s3.roles
        system_roles = auth.get_system_roles()
        AUTHENTICATED = system_roles.AUTHENTICATED

        # Login/Registration forms
        self_registration = current.deployment_settings.get_security_registration_visible(
        )
        registered = False
        login_form = None
        login_div = None
        register_form = None
        register_div = None

        # Contact Form
        request_email = settings.get_frontpage("request_email")
        if request_email:
            from s3dal import Field
            from gluon.validators import IS_NOT_EMPTY
            from gluon.sqlhtml import SQLFORM
            fields = [
                Field(
                    "name",
                    label="Your name",
                    requires=IS_NOT_EMPTY(),
                ),
                Field(
                    "address",
                    label="Your e-mail address",
                    requires=IS_NOT_EMPTY(),
                ),
                Field(
                    "subject",
                    label="Subject",
                    requires=IS_NOT_EMPTY(),
                ),
                Field(
                    "message",
                    "text",
                    label="Message",
                    requires=IS_NOT_EMPTY(),
                ),
            ]
            from s3 import s3_mark_required
            labels, required = s3_mark_required(fields)
            s3.has_required = required

            response.form_label_separator = ""
            contact_form = SQLFORM.factory(
                formstyle=settings.get_ui_formstyle(),
                submit_button=T("Submit"),
                labels=labels,
                separator="",
                table_name="contact",  # Dummy table name
                _id="mailform",
                *fields)

            if contact_form.accepts(request.post_vars,
                                    current.session,
                                    formname="contact_form",
                                    keepvalues=False,
                                    hideerror=False):
                # Processs Contact Form
                form_vars = contact_form.vars
                sender = "%s <%s>" % (form_vars.name, form_vars.address)
                result = current.msg.send_email(
                    to=request_email,
                    sender=sender,
                    subject=form_vars.subject,
                    message=form_vars.message,
                    reply_to=form_vars.address,
                )
                if result:
                    response.confirmation = "Thank you for your message - we'll be in touch shortly"
            if s3.cdn:
                if s3.debug:
                    s3.scripts.append(
                        "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.js"
                    )
                else:
                    s3.scripts.append(
                        "http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"
                    )
            else:
                if s3.debug:
                    s3.scripts.append("/%s/static/scripts/jquery.validate.js" %
                                      request.application)
                else:
                    s3.scripts.append(
                        "/%s/static/scripts/jquery.validate.min.js" %
                        request.application)
            validation_script = '''
$('#mailform').validate({
 errorClass:'req',
 rules:{
  name:{
   required:true
  },
  address: {
   required:true,
   email:true
  },
  subject:{
   required:true
  },
  message:{
   required:true
  }
 },
 messages:{
  name:"Enter your name",
  subject:"Enter a subject",
  message:"Enter a message",
  address:{
   required:"Please enter a valid email address",
   email:"Please enter a valid email address"
  }
 },
 errorPlacement:function(error,element){
  error.appendTo(element.parents('div.controls'))
 },
 submitHandler:function(form){
  form.submit()
 }
})'''
            s3.jquery_ready.append(validation_script)

        else:
            contact_form = ""

        if AUTHENTICATED not in roles:

            login_buttons = DIV(A(T("Login"),
                                  _id="show-login",
                                  _class="tiny secondary button"),
                                _id="login-buttons")
            script = '''
$('#show-mailform').click(function(e){
 e.preventDefault()
 $('#intro').slideDown(400, function() {
   $('#login_box').hide()
 });
})
$('#show-login').click(function(e){
 e.preventDefault()
 $('#login_form').show()
 $('#register_form').hide()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
            s3.jquery_ready.append(script)

            # This user isn't yet logged-in
            if "registered" in request.cookies:
                # This browser has logged-in before
                registered = True

            if self_registration is True:
                # Provide a Registration box on front page
                login_buttons.append(
                    A(T("Register"),
                      _id="show-register",
                      _class="tiny secondary button",
                      _style="margin-left:5px"))
                script = '''
$('#show-register').click(function(e){
 e.preventDefault()
 $('#login_form').hide()
 $('#register_form').show()
 $('#login_box').show()
 $('#intro').slideUp()
})'''
                s3.jquery_ready.append(script)

                register_form = auth.register()
                register_div = DIV(
                    H3(T("Register")),
                    P(
                        XML(
                            T("If you would like to help, then please <b>sign up now</b>"
                              ))))
                register_script = '''
$('#register-btn').click(function(e){
 e.preventDefault()
 $('#register_form').show()
 $('#login_form').hide()
})
$('#login-btn').click(function(e){
 e.preventDefault()
 $('#register_form').hide()
 $('#login_form').show()
})'''
                s3.jquery_ready.append(register_script)

            # Provide a login box on front page
            auth.messages.submit_button = T("Login")
            login_form = auth.login(inline=True)
            login_div = DIV(
                H3(T("Login")),
                P(
                    XML(
                        T("Registered users can <b>login</b> to access the system"
                          ))))
        else:
            login_buttons = ""

        output["login_buttons"] = login_buttons
        output["self_registration"] = self_registration
        output["registered"] = registered
        output["login_div"] = login_div
        output["login_form"] = login_form
        output["register_div"] = register_div
        output["register_form"] = register_form
        output["contact_form"] = contact_form

        # Slick slider
        if s3.debug:
            s3.scripts.append("/%s/static/scripts/slick.js" %
                              request.application)
        else:
            s3.scripts.append("/%s/static/scripts/slick.min.js" %
                              request.application)
        script = '''
$(document).ready(function(){
 $('#title-image').slick({
  autoplay:true,
  autoplaySpeed:5000,
  speed:1000,
  fade:true,
  cssEase:'linear'
 });
});'''
        s3.jquery_ready.append(script)

        s3.stylesheets.append("../themes/%s/homepage.css" % THEME)
        self._view(THEME, "index.html")

        return output