Beispiel #1
0
 def register(self):
     self.auth.db.auth_user.password.writable = True
     fields = [field for field in self.auth.db.auth_user if field.writable]
     for k, field in enumerate(fields):
         if field.type == "password":
             fields.insert(k + 1, Field("password_again", "password"))
             break
     form = Form(fields, submit_value="Sign Up", formstyle=self.formstyle)
     user = None
     if form.submitted:
         res = self.auth.register(form.vars)
         form.accepted = not res.get("errors")
         form.errors = res.get("errors")
         if not form.errors:
             self.auth.flash.set("User registered succesfully")
             self._postprocessing("register", form, user)
     form.param.sidecar.append(
         A("Sign In", _href="../auth/login", _class="info", _role="button"))
     form.param.sidecar.append(
         A(
             "Lost Password",
             _href="../auth/request_reset_password",
             _class="info",
             _role="button",
         ))
     return form
Beispiel #2
0
    def render_action_button(self,
                             url,
                             button_text,
                             icon,
                             size='small',
                             row_id=None,
                             user_signature=None,
                             page=None):
        separator = '?'
        if row_id:
            url += '/%s' % (row_id)
        if user_signature:
            url += '%suser_signature=%s' % (separator, user_signature)
            separator = '&'
        if page:
            url += '%spage=%s' % (separator, page)

        if self.include_action_button_text:
            _a = A(_href=url, _class='button is-%s' % size, _title=button_text)
            _span = SPAN(_class='icon is-%s' % size)
            _span.append(I(_class='fas %s' % icon))
            _a.append(_span)
            _a.append(SPAN(button_text))
        else:
            _a = A(I(_class='fas %s' % icon),
                   _href=url,
                   _class='button is-%s' % size,
                   _title=button_text)

        return _a
Beispiel #3
0
    def script(self):
        js = (
            '<script type="text/javascript">'
            '    $(document).ready(function() {'
            '        $(\'#datatables_table\').DataTable( {'
            '            dom: "lfrtip", '
            '            processing: true, '
            '            serverSide: true, '
            '            lengthMenu: [  [10, 15, 20, -1], [10, 15, 20, \'All\']  ], '
            '            pageLength: %s, '
            '            pagingType: "numbers", '
            '            ajax: "%s", '
            '            columns: [' % (self.page_length, self.data_url))
        #  add the field values
        for field in self.fields:
            js += (
                '{'
                '    "data": "%s", '
                '    "name": "%s", '
                '    "visible": %s, '
                '},' %
                (field.name, field.name, 'true' if field.visible else 'false'))
        #  add the row buttons
        js += (
            '{'
            '    data: null,'
            '    render: function ( data, type, row ) {'
            '      var edit_url=\'%s\'; '
            '      edit_url = edit_url.replace("record_id", row.DT_RowId); '
            '      var delete_url=\'%s\'; '
            '      delete_url = delete_url.replace("record_id", row.DT_RowId); '
            '      return edit_url + "&nbsp;" + delete_url '
            '    }, '
            '    orderable: false, '
            '}' % (A(I(_class='fas fa-edit'),
                     _href=self.edit_url if self.edit_url else '#',
                     _class='button is-small'),
                   A(I(_class='fas fa-trash'),
                     _href=self.delete_url if self.delete_url else '#',
                     _class='button is-small',
                     _message='Delete Record')))
        js += '], columnDefs: ['
        for index, field in enumerate(self.fields):
            if not field.visible:
                js += '{"visible": false, "targets": %s},' % index
        js += '{className: "has-text-centered", "targets": %s}' % (index + 1)

        js += ('],' 'order: ')
        for sort in self.sort_sequence:
            js += '[ %s, "%s" ]' % (sort[0], sort[1])

        js += (','
               '        stateSave: true, '
               '        select: true, '
               '    });'
               '    $(".dataTables_filter input").focus().select();'
               '});'
               '</script>')

        return str(js)
Beispiel #4
0
 def request_reset_password(self):
     form = Form(
         [
             Field(
                 "email",
                 label=self.auth.param.messages["labels"].get("username_or_email"),
                 requires=IS_NOT_EMPTY(),
             )
         ],
         submit_value=self.auth.param.messages["buttons"]["request"],
         formstyle=self.formstyle,
     )
     if form.accepted:
         email = form.vars.get("email", "")
         self.auth.request_reset_password(email, send=True, next="")
         self._set_flash("password-reset-link-sent")
         self._postprocessing("request_reset_password", form, None)
     form.param.sidecar.append(
         A(
             self.auth.param.messages["buttons"]["sign-in"],
             _href="../auth/login",
             _class=self.auth.param.button_classes["sign-in"],
             _role="button",
         )
     )
     if self.auth.allows("register"):
         form.param.sidecar.append(
             A(
                 self.auth.param.messages["buttons"]["sign-up"],
                 _href="../auth/register",
                 _class=self.auth.param.button_classes["sign-up"],
                 _role="button",
             )
         )
     return form
Beispiel #5
0
    def login(self):
        fields = [
            Field(
                "username",
            ),
            Field(
                "login_password",
                type="password",
                label=self.auth.param.messages["labels"].get("password"),
            ),
        ]
        if self.auth.use_username:
            fields[0].label = self.auth.db.auth_user.username.label
        else:
            fields[0].label = self.auth.db.auth_user.email.label
        fields[1].label = self.auth.db.auth_user.password.label

        button_name = self.auth.param.messages["buttons"]["sign-in"]
        form = Form(
            fields,
            submit_value=button_name,
            formstyle=self.formstyle,
        )
        user = None
        self.auth.next["login"] = request.query.get("next")
        if form.submitted:
            user, error = self.auth.login(
                form.vars.get("username"), form.vars.get("login_password")
            )
            form.accepted = not error
            form.errors["username"] = error
            if user:
                self.auth.store_user_in_session(user["id"])
                self._postprocessing("login", form, user)
        top_buttons = []
        for name, plugin in self.auth.plugins.items():
            url = "../auth/plugin/" + name + "/login"
            if self.auth.next["login"]:
                url = url + "?next=" + self.auth.next["login"]
            top_buttons.append(A(plugin.label + " Login", _href=url, _role="button"))

        if self.auth.allows("register"):
            form.param.sidecar.append(
                A(self.auth.param.messages["buttons"]["sign-up"],
                  _href="../auth/register",
                  _class=self.auth.param.button_classes["sign-up"],
                  _role="button")
            )
        if self.auth.allows("request_reset_password"):
            form.param.sidecar.append(
                A(
                    self.auth.param.messages["buttons"]["lost-password"],
                    _href="../auth/request_reset_password",
                    _class=self.auth.param.button_classes["lost-password"],
                    _role="button",
                )
            )
        form.structure.insert(0, DIV(DIV(*top_buttons)))
        return form
Beispiel #6
0
    def render_table_header(self):

        up = I(**self.param.grid_class_style.get("grid-sorter-icon-up"))
        dw = I(**self.param.grid_class_style.get("grid-sorter-icon-down"))
        columns = []
        sort_order = request.query.get("orderby", "")

        for index, field in enumerate(self.param.fields):
            if field.readable and (field.type != "id" or self.param.show_id):
                key = "%s.%s" % (field.tablename, field.name)
                heading = (
                    self.param.headings[index]
                    if index < len(self.param.headings)
                    else field.label
                )
                heading = title(heading)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)

                attrs = {}
                if isinstance(field, FieldVirtual):
                    col = DIV(heading)
                elif key == sort_order:
                    sort_query_parms["orderby"] = "~" + key
                    url = URL(self.endpoint, vars=sort_query_parms)
                    attrs = self.attributes_plugin.link(url=url)
                    col = A(heading, up, **attrs)
                else:
                    sort_query_parms["orderby"] = key
                    url = URL(self.endpoint, vars=sort_query_parms)
                    attrs = self.attributes_plugin.link(url=url)
                    col = A(heading, dw if "~" + key == sort_order else "", **attrs)
                columns.append((key, col))

        thead = THEAD(_class=self.param.grid_class_style.classes.get("grid-thead", ""))
        for key, col in columns:
            col_class = " grid-col-%s" % key
            thead.append(
                TH(
                    col,
                    _class=self.param.grid_class_style.classes.get("grid-th", "")
                    + col_class,
                    _style=self.param.grid_class_style.styles.get("grid-th"),
                )
            )

        if (
            self.param.details
            or self.param.editable
            or self.param.deletable
            or self.param.pre_action_buttons
            or self.param.post_action_buttons
        ):
            thead.append(
                TH("", **self.param.grid_class_style.get("grid-th-action-button"))
            )

        return thead
Beispiel #7
0
    def login(self):

        top_buttons = self.login_buttons()

        # if we do not allow we only display the plugin login buttons
        if not self.auth.param.default_login_enabled:
            return DIV(*top_buttons)

        fields = [
            Field("username", ),
            Field(
                "login_password",
                type="password",
                label=self.auth.param.messages["labels"].get("password"),
            ),
        ]
        if self.auth.use_username:
            fields[0].label = self.auth.db.auth_user.username.label
        else:
            fields[0].label = self.auth.db.auth_user.email.label
        fields[1].label = self.auth.db.auth_user.password.label

        button_name = self.auth.param.messages["buttons"]["sign-in"]
        form = Form(
            fields,
            submit_value=button_name,
            formstyle=self.formstyle,
        )
        user = None
        self.auth.next["login"] = request.query.get("next")
        if form.submitted:
            user, error = self.auth.login(form.vars.get("username", ""),
                                          form.vars.get("login_password", ""))
            form.accepted = not error
            form.errors["username"] = error
        if user:
            self.auth.store_user_in_session(user["id"])
            self._postprocessing("login", form, user)

        if self.auth.allows("register"):
            form.param.sidecar.append(
                A(
                    self.auth.param.messages["buttons"]["sign-up"],
                    _href="../auth/register",
                    _class=self.auth.param.button_classes["sign-up"],
                    _role="button",
                ))
        if self.auth.allows("request_reset_password"):
            form.param.sidecar.append(
                A(
                    self.auth.param.messages["buttons"]["lost-password"],
                    _href="../auth/request_reset_password",
                    _class=self.auth.param.button_classes["lost-password"],
                    _role="button",
                ))
        form.structure.insert(0, DIV(DIV(*top_buttons)))
        return form
Beispiel #8
0
 def api(self, id=None):
     """Returns data according to the API request."""
     # Builds the header.
     header = dict(
         is_header=True,
         cells=[
             dict(text="First Name", sortable=True),
             dict(text="Last Name", sortable=True),
             dict(text="Arrival Time", sortable=True),
             dict(text="", sortable=False),  # Icons
         ],
     )
     # Gets the request parameters, and copies the sort order in the header.
     req = self._get_request_params(header)
     timezone = request.query.get("timezone")
     q = request.query.get("q", "")  # Query string
     # Forms the query.
     if q:
         query = db(
             db.vue_form_table.first_name.contains(q)
             | db.vue_form_table.last_name.contains(q))
     else:
         query = db.vue_form_table
     # Forms the select.
     rows = db(query).select(**req.search_args)
     # Builds the result rows.
     result_rows = []
     for r in rows:
         cells = []
         cells.append(dict(text=r.first_name))
         cells.append(dict(text=r.last_name))
         cells.append(dict(text=r.arrival_time.isoformat(), type="date"))
         cells.append(
             dict(raw_html=SPAN(
                 A(
                     I(_class="fa fa-eye"),
                     _href=URL("vue_view_form", r.id, signer=self.signer),
                 ),
                 " ",
                 A(
                     I(_class="fa fa-pen"),
                     _href=URL("vue_edit_form", r.id, signer=self.signer),
                 ),
             ).xml()))
         result_rows.append(
             dict(cells=cells,
                  delete=URL("delete_row", r.id, signer=self.signer)))
     has_more, result_rows = self._has_more(result_rows)
     return dict(
         page=req.page,
         has_search=True,
         has_delete=True,
         search_placeholder="",
         has_more=has_more,
         rows=[header] + result_rows,
     )
Beispiel #9
0
 def register(self):
     self.auth.db.auth_user.password.writable = True
     fields = [field for field in self.auth.db.auth_user if field.writable]
     for k, field in enumerate(fields):
         if field.type == "password":
             fields.insert(
                 k + 1,
                 Field(
                     "password_again",
                     "password",
                     requires=IS_EQUAL_TO(request.forms.get("password")),
                     label=self.auth.param.messages["labels"].get("password_again"),
                 ),
             )
             break
     button_name = self.auth.param.messages["buttons"]["sign-up"]
     # if the form is submitted, before any validation
     # delete any unverified account with the same email
     if request.method == "POST":
         email = request.forms.get("email")
         if email:
             self.auth.get_or_delete_existing_unverified_account(email)
     form = Form(fields, submit_value=button_name, formstyle=self.formstyle)
     user = None
     if form.accepted:
         # notice that here the form is alrealdy validated
         res = self.auth.register(form.vars, validate=False)
         form.errors.update(**res.get("errors", {}))
         form.accepted = not form.errors
     if form.accepted:
         self._set_flash("user-registered")
         self._postprocessing("register", form, user)
         if self.auth.param.login_after_registration:
             redirect("login")
     form.param.sidecar.append(
         A(
             self.auth.param.messages["buttons"]["sign-in"],
             _href="../auth/login",
             _class=self.auth.param.button_classes["sign-in"],
             _role="button",
         )
     )
     if self.auth.allows("request_reset_password"):
         form.param.sidecar.append(
             A(
                 self.auth.param.messages["buttons"]["lost-password"],
                 _href="../auth/request_reset_password",
                 _class=self.auth.param.button_classes["lost-password"],
                 _role="button",
             )
         )
     return form
Beispiel #10
0
def edit_phone(contact_id=None, phone_id=None):
    assert contact_id is not None
    assert phone_id is not None
    # match the phone owner's id as well as the number's id
    row = db(
        (db.phone.contact_id == contact_id) &
        (db.phone.id == phone_id)
    ).select().first()
    if row is None:
        redirect(URL('edit_phones', contact_id))

    contact_inf = db(db.contact.id == contact_id).select().first()
    if contact_inf.user_email != get_user_email():
        abort(403)

    form = Form([Field('Phone', 'string'), Field('Kind', 'string')],
                record=dict(Phone=row.number, Kind=row.phone_type), deletable=False, csrf_session=session, formstyle=FormStyleBulma)
    form.param.sidecar.append(SPAN(" ", A("Back", _class="button", _href=URL('edit_phones', contact_id))))

    if form.accepted:
        # insert the number for that contact
        number = form.vars['Phone']
        phone_type = form.vars['Kind']
        db((db.phone.contact_id == contact_id) & (db.phone.id == phone_id)).update(
            number=number,
            phone_type=phone_type
        )
        redirect(URL('edit_phones', contact_id))

    contact_inf = db.contact[contact_id]
    first_name = contact_inf.first_name
    last_name = contact_inf.last_name
    name = f"{first_name} {last_name}"
    return dict(form=form, name=name)
Beispiel #11
0
 def render_table_pager(self):
     pager = DIV(**self.param.grid_class_style.get("grid-pagination"))
     previous_page_number = None
     for page_number in self.iter_pages(
         self.current_page_number, self.number_of_pages
     ):
         pager_query_parms = dict(self.query_parms)
         pager_query_parms["page"] = page_number
         # if there is a gat add a spacer
         if previous_page_number and page_number - previous_page_number > 1:
             pager.append(SPAN("...", _style="margin:0 10px;"))
         is_current = self.current_page_number == page_number
         page_name = (
             "grid-pagination-button-current"
             if is_current
             else "grid-pagination-button"
         )
         attrs = self.attributes_plugin.link(
             url=URL(self.endpoint, vars=pager_query_parms)
         )
         pager.append(
             A(
                 page_number,
                 **self.param.grid_class_style.get(page_name),
                 _role="button",
                 **attrs,
             )
         )
         previous_page_number = page_number
     return pager
Beispiel #12
0
def example_html_grid(path=None):
    #  controllers and used for all grids in the app
    grid_param = dict(rows_per_page=5,
                      include_action_button_text=True,
                      search_button_text="Filter",
                      formstyle=FormStyleDefault,
                      grid_class_style=GridClassStyle)

    search_queries = [
        ['By Name', lambda value: db.thing.name.contains(value)],
        ['By Color', lambda value: db.thing.color == value],
        [
            'By Name or Color', lambda value: db.thing.name.contains(value) |
            (db.thing.color == value)
        ],
    ]

    query = db.thing.id > 0
    orderby = [db.thing.name]
    columns = [field for field in db.thing if field.readable]
    columns.insert(0, Column("Custom", lambda row: A("click me")))
    grid = Grid(path,
                query,
                columns=columns,
                search_queries=search_queries,
                orderby=orderby,
                show_id=False,
                T=T,
                **grid_param)

    grid.formatters['thing.color'] = lambda color: I(_class="fa fa-circle",
                                                     _style="color:" + color)

    return dict(grid=grid)
Beispiel #13
0
    def make(self, field, value, error, title, placeholder="", readonly=False):
        field_id = to_id(field)
        control = DIV()
        if value and not error:
            download_div = DIV()

            if not readonly:
                download_div.append(LABEL("Currently:  ", ))
            url = getattr(field, "download_url", lambda value: "#")(value)
            download_div.append(A(" download ", _href=url))

            if not readonly:
                download_div.append(
                    INPUT(
                        _type="checkbox",
                        _value="ON",
                        _name="_delete_" + field.name,
                        _title=title,
                    ))
                download_div.append(" (check to remove)")

            control.append(download_div)

        control.append(LABEL("Change: "))
        control.append(INPUT(_type="file", _id=field_id, _name=field.name))
        return control
Beispiel #14
0
    def table(self):
        _html = DIV()
        if self.create_url and self.create_url != '':
            _a = A('',
                   _href=self.create_url,
                   _class='button',
                   _style='margin-bottom: 1rem;')
            _span = SPAN(_class='icon is-small')
            _span.append(I(_class='fas fa-plus'))
            _a.append(_span)
            _a.append(SPAN('New'))
            _html.append(_a)

        _table = TABLE(_id='datatables_table',
                       _class='compact stripe hover cell-border order-column',
                       _style='padding-top: 1rem;')
        _thead = THEAD()
        _tr = TR()
        for field in self.fields:
            _tr.append(TH(field.label, _class='datatables-header'))
        _tr.append(
            TH('ACTIONS',
               _class='datatables-header has-text-centered',
               _style='color: black; width: 1px; white-space: nowrap;'))
        _thead.append(_tr)
        _table.append(_thead)
        _table.append(TBODY())

        _html.append(_table)
        return str(_html)
 def render_table_pager(self):
     pager = DIV(**self.param.grid_class_style.get("grid-pagination"))
     previous_page_number = None
     for page_number in self.iter_pages(self.current_page_number,
                                        self.number_of_pages):
         pager_query_parms = dict(self.query_parms)
         pager_query_parms["page"] = page_number
         # if there is a gat add a spacer
         if previous_page_number and page_number - previous_page_number > 1:
             pager.append(SPAN("...", _style="margin:0 10px;"))
         is_current = self.current_page_number == page_number
         page_name = ("grid-pagination-button-current"
                      if is_current else "grid-pagination-button")
         attrs = ({
             "_hx-get": URL(self.endpoint, vars=pager_query_parms),
             "_hx-target": self.param.htmx_target,
             "_hx-swap": "innertHTML",
         } if self.param.htmx_target else {
             "_href": URL(self.endpoint, vars=pager_query_parms)
         })
         pager.append(
             A(
                 page_number,
                 **self.param.grid_class_style.get(page_name),
                 _role="button",
                 **attrs,
             ))
         previous_page_number = page_number
     return pager
Beispiel #16
0
    def render_action_button(
        self,
        url,
        button_text,
        icon,
        icon_size="small",
        additional_classes=None,
        additional_styles=None,
        override_classes=None,
        override_styles=None,
        message=None,
        onclick=None,
        row_id=None,
        name="grid-button",
        row=None,
        **attr,
    ):
        separator = "?"
        if row_id:
            url += "/%s" % row_id

        classes = self.param.grid_class_style.classes.get(name, "")
        styles = self.param.grid_class_style.styles.get(name, "")

        def join(items):
            return (
                " ".join(items) if isinstance(items, (list, tuple)) else " %s" % items
            )

        if override_classes:
            classes = join(override_classes)
        elif additional_classes:
            classes += join(additional_classes)
        if override_styles:
            styles = join(override_styles)
        elif additional_styles:
            styles += join(additional_styles)

        if callable(url):
            url = url(row)

        link = A(
            I(_class="fa %s" % icon),
            _href=url,
            _role="button",
            _class=classes,
            _message=message,
            _title=button_text,
            _style=styles,
            **attr,
        )
        if self.param.include_action_button_text:
            link.append(
                XML(
                    '<span class="grid-action-button-text">&nbsp;%s</span>'
                    % button_text
                )
            )

        return link
Beispiel #17
0
    def render_table_pager(self):
        _pager = DIV(_class='is-pulled-right')
        for page_number in self.iter_pages():
            if page_number:
                pager_query_parms = dict(self.query_parms)
                pager_query_parms['page'] = page_number
                pager_query_parms['user_signature'] = self.user_signature
                if self.current_page_number == page_number:
                    _pager.append(A(page_number, _class='button is-primary is-small',
                                    _href=URL(self.endpoint, vars=pager_query_parms)))
                else:
                    _pager.append(A(page_number, _class='button is-small',
                                    _href=URL(self.endpoint, vars=pager_query_parms)))
            else:
                _pager.append('...')

        return _pager
Beispiel #18
0
    def render_table_header(self):

        up = I(**self.param.grid_class_style.get("grid-sorter-icon-up"))
        dw = I(**self.param.grid_class_style.get("grid-sorter-icon-down"))
        columns = []
        sort_order = request.query.get("orderby", "")

        for index, field in enumerate(self.param.fields):
            if field.readable and (field.type != "id" or self.param.show_id):
                key = "%s.%s" % (field.tablename, field.name)
                heading = (self.param.headings[index] if
                           index < len(self.param.headings) else field.label)
                heading = title(heading)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)

                if key == sort_order:
                    sort_query_parms["orderby"] = "~" + key
                    href = URL(self.endpoint, vars=sort_query_parms)
                    col = A(heading, up, _href=href)
                else:
                    sort_query_parms["orderby"] = key
                    href = URL(self.endpoint, vars=sort_query_parms)
                    col = A(heading,
                            dw if "~" + key == sort_order else "",
                            _href=href)
                columns.append((key, col))

        thead = THEAD()
        for key, col in columns:
            col_class = "grid-col-%s" % key
            thead.append(
                TH(
                    col,
                    _class=self.param.grid_class_style.classes.get(
                        "grid-th", "") + col_class,
                    _style=self.param.grid_class_style.styles.get("grid-th"),
                ))

        if self.param.details or self.param.editable or self.param.deletable:
            thead.append(
                TH("",
                   **self.param.grid_class_style.get('grid-th-action-button')))

        return thead
Beispiel #19
0
    def render_table_header(self):
        _thead = THEAD()
        for index, field in enumerate(self.fields):
            if field.name not in [x.name for x in self.hidden_fields] and (
                    field.name != 'id' or (field.name == 'id' and self.show_id)):
                try:
                    heading = self.headings[index]
                except:
                    if field.table == self.tablename:
                        heading = field.label
                    else:
                        heading = str(field.table)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)
                sort_query_parms['sort'] = index
                current_sort_dir = 'asc'

                if '%s.%s' % (field.tablename, field.name) in self.storage_values['orderby']:
                    sort_query_parms['sort'] = -index
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))
                    _h.append(SPAN(I(_class='fas fa-sort-up'), _class='is-pulled-right'))
                elif '~%s.%s' % (field.tablename, field.name) in self.storage_values['orderby']:
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))
                    _h.append(SPAN(I(_class='fas fa-sort-down'), _class='is-pulled-right'))
                else:
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))

                if 'sort_dir' in sort_query_parms:
                    current_sort_dir = sort_query_parms['sort_dir']
                    del sort_query_parms['sort_dir']
                if index == int(request.query.get('sort', 0)) and current_sort_dir == 'asc':
                    sort_query_parms['sort_dir'] = 'desc'

                _th = TH()
                _th.append(_h)

                _thead.append(_th)

        if self.editable or self.deletable:
            _thead.append(TH('ACTIONS', _style='text-align: center; width: 1px; white-space: nowrap;'))

        return _thead
Beispiel #20
0
 def footer(self, count, offset, len_items):
     """generates the footer"""
     T = self.T
     page = int(offset / self.limit)
     last_page = math.floor(count / self.limit)
     return DIV(
         A("First", _href=self.url(0), _class="button") if page > 1 else "",
         A("Previous", _href=self.url(page - 1), _class="button")
         if page > 0 else "",
         SPAN(
             T("page %s/%s (%s/%s records)") %
             (page + 1, last_page + 1, len_items, count)),
         A("Next", _href=self.url(page + 1), _class="button")
         if page < last_page else "",
         A("Last", _href=self.url(last_page - 1), _class="button")
         if page < last_page - 1 else "",
         SCRIPT(Grid.script),
         _class="py4web-grid-footer",
     )
Beispiel #21
0
 def request_reset_password(self):
     form = Form(
         [Field("email", label="Username of Email")],
         submit_value="Request",
         formstyle=self.formstyle,
     )
     if form.submitted:
         email = form.vars.get("email")
         self.auth.request_reset_password(email, send=True, next="")
         self.auth.flash.set("Password reset link sent")
         self._postprocessing("request_reset_password", form, None)
     form.param.sidecar.append(
         A("Sign In", _href="../auth/login", _class="info", _role="button"))
     form.param.sidecar.append(
         A("Sign Up",
           _href="../auth/register",
           _class="info",
           _role="button"))
     return form
Beispiel #22
0
 def header(self, id, message=""):
     """generates the header"""
     T = self.T
     div = DIV(_class="py4web-grid-header")
     if message:
         div.append(DIV(message, _class="py4web-grid-message"))
     if self.create and id is None:
         div.append(
             A(
                 T("Create Record"),
                 _class="button",
                 _href=request.url.split("?")[0] + "?id=0",
             )
         )
     elif (self.create and id == 0) or (self.editable and id and id > 0):
         query = dict(request.query)
         query.pop("id", None)
         url = request.url.split("?")[0] + "?" + urllib.parse.urlencode(query)
         div.append(A(T("Back"), _class="button", _href=url))
         div.append(T("New Record") if id == 0 else T("Edit Record"))
     return div
Beispiel #23
0
    def login_buttons(self):

        top_buttons = []

        for name, plugin in self.auth.plugins.items():
            url = "../auth/plugin/" + name + "/login"
            if request.query.get("next"):
                url = url + "?next=" + request.query.get("next")
            if (name != "email_auth"
                ):  #  do not add the top button for the email auth plugin
                top_buttons.append(
                    A(plugin.label + " Login", _href=url, _role="button"))
        return top_buttons
Beispiel #24
0
 def sortlink(self, key):
     """returns the link to sort by key"""
     label = self.labels.get(key, key)
     if not self.is_sortable(key):
         return label
     order = request.query.get("@order")
     if order == key:
         new_order, caret = "~" + key, "▼"
     elif order == "~" + key:
         new_order, caret = key, "▲"
     else:
         new_order, caret = key, ""
     return A(label + caret, _href=self.url(page=0, order=new_order))
Beispiel #25
0
 def login(self):
     form = Form(
         [Field("username"),
          Field("login_password", type="password")],
         submit_value="Sign In",
         formstyle=self.formstyle,
     )
     user = None
     if form.submitted:
         user, error = self.auth.login(form.vars.get("username"),
                                       form.vars.get("login_password"))
         form.accepted = not error
         form.errors["username"] = error
         if user:
             self.auth.store_user_in_session(user["id"])
             self._postprocessing("login", form, user)
     top_buttons = []
     next = request.query.get("next")
     for name, plugin in self.auth.plugins.items():
         url = "../auth/plugin/" + name + "/login"
         if next:
             url = url + "?next=" + next
         top_buttons.append(
             A(plugin.name + " Login", _href=url, _role="button"))
     form.param.sidecar.append(
         A("Sign Up",
           _href="../auth/register",
           _class="info",
           _role="button"))
     form.param.sidecar.append(
         A(
             "Lost Password",
             _href="../auth/request_reset_password",
             _class="info",
             _role="button",
         ))
     return DIV(DIV(*top_buttons), form)
Beispiel #26
0
def add_phone(contact_id):
    assert contact_id is not None
    # contact_id is the id of the contact for which we are inserting an additional number

    form = Form([Field('Phone', 'string'), Field('Kind', 'string')], csrf_session=session, formstyle=FormStyleBulma)
    form.param.sidecar.append(SPAN(" ", A("Back", _class="button", _href=URL('edit_phones', contact_id))))

    if form.accepted:
        # insert the number for that contact
        number = form.vars['Phone']
        phone_type = form.vars['Kind']
        db.phone.insert(
            contact_id=contact_id,
            number=number,
            phone_type=phone_type
        )
        redirect(URL('edit_phones', contact_id))
    contact_inf = db.contact[contact_id]
    first_name = contact_inf.first_name
    last_name = contact_inf.last_name
    name = f"{first_name} {last_name}"
    return dict(form=form, name=name)
Beispiel #27
0
    def produce(self, table, vars, errors, readonly, deletable, classes=None):
        self.classes.update(classes or {})
        form = FORM(
            _method="POST", _action=request.url, _enctype="multipart/form-data"
        )
        controls = dict(
            widgets=dict(),
            hidden_widgets=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            end=XML("</form>"),
        )
        class_label = self.classes["label"]
        class_outer = self.classes["outer"]
        class_inner = self.classes["inner"]
        class_error = self.classes["error"]
        class_info = self.classes["info"]

        for field in table:

            input_id = "%s_%s" % (field.tablename, field.name)
            value = vars.get(field.name, field.default)
            error = errors.get(field.name)
            field_class = field.type.split()[0].replace(":", "-")

            if not field.readable and not field.writable:
                continue
            if not readonly and not field.writable:
                continue
            if field.type == "blob":  # never display blobs (mistake?)
                continue
            if field.type == "id" and value is None:
                field.writable = False
                continue
            if readonly or field.type == "id":
                control = DIV(field.represent and field.represent(value) or value or "")
            elif field.widget:
                control = field.widget(table, value)
            elif field.type == "text":
                control = TEXTAREA(value or "", _id=input_id, _name=field.name)
            elif field.type == "date":
                control = INPUT(
                    _value=value, _type="date", _id=input_id, _name=field.name
                )
            elif field.type == "datetime":
                if isinstance(value, str):
                    value = value.replace(" ", "T")
                control = INPUT(
                    _value=value, _type="datetime-local", _id=input_id, _name=field.name
                )
            elif field.type == "time":
                control = INPUT(
                    _value=value, _type="time", _id=input_id, _name=field.name
                )
            elif field.type == "boolean":
                control = INPUT(
                    _type="checkbox",
                    _id=input_id,
                    _name=field.name,
                    _value="ON",
                    _checked=value,
                )
            elif field.type == "upload":
                control = DIV(INPUT(_type="file", _id=input_id, _name=field.name))
                if value:
                    control.append(A("download", _href=field.download_url(value)))
                    control.append(
                        INPUT(
                            _type="checkbox", _value="ON", _name="_delete_" + field.name
                        )
                    )
                    control.append("(check to remove)")
            elif get_options(field.requires) is not None:
                multiple = field.type.startswith("list:")
                value = list(map(str, value if isinstance(value, list) else [value]))
                option_tags = [
                    OPTION(v, _value=k, _selected=(not k is None and k in value))
                    for k, v in get_options(field.requires)
                    ]
                control = SELECT(
                    *option_tags, _id=input_id, _name=field.name, _multiple=multiple
                     )
            else:
                field_type = "password" if field.type == "password" else "text"
                control = INPUT(
                    _type=field_type,
                    _id=input_id,
                    _name=field.name,
                    _value=value,
                    _class=field_class,
                )

            key = control.name.rstrip("/")
            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")
            control["_class"] = self.classes.get(key, "")

            controls["widgets"][field.name] = control
            if error:
                controls["errors"][field.name] = error

            form.append(
                DIV(
                    LABEL(field.label, _for=input_id, _class=class_label),
                    DIV(control, _class=class_inner),
                    P(error, _class=class_error) if error else "",
                    P(field.comment or "", _class=class_info),
                    _class=class_outer,
                )
            )
            if 'id' in vars:
                form.append(INPUT(_name='id',_value=vars['id'],_hidden=True))
        if deletable:
            controls["delete"] = INPUT(
                _type="checkbox",
                _value="ON",
                _name="_delete",
                _class=self.classes["input[type=checkbox]"],
            )
            form.append(
                DIV(
                    DIV(controls["delete"], _class=class_inner,),
                    P("check to delete", _class="help"),
                    _class=class_outer,
                )
            )
        controls["submit"] = INPUT(
            _type="submit", _value="Submit", _class=self.classes["input[type=submit]"],
        )
        submit = DIV(DIV(controls["submit"], _class=class_inner,), _class=class_outer,)
        form.append(submit)
        return dict(form=form, controls=controls)
Beispiel #28
0
    def produce(self, table, vars, errors, readonly, deletable, classes=None):
        self.classes.update(classes or {})
        form = FORM(_method="POST", _action=request.url, _enctype="multipart/form-data")
        controls = Param(
            labels=dict(),
            widgets=dict(),
            comments=dict(),
            hidden_widgets=dict(),
            placeholders=dict(),
            titles=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            submit="",
            delete="",
            end=XML("</form>"),
        )
        class_label = self.classes["label"]
        class_outer = self.classes["outer"]
        class_inner = self.classes["inner"]
        class_error = self.classes["error"]
        class_info = self.classes["info"]

        for field in table:

            input_id = "%s_%s" % (field.tablename, field.name)
            value = vars.get(field.name, field.default)
            error = errors.get(field.name)
            field_class = "type-" + field.type.split()[0].replace(":", "-")
            placeholder = (
                field._placeholder if "_placeholder" in field.__dict__ else None
            )
            title = field._title if "_title" in field.__dict__ else None
            # only diplay field if readable or writable
            if not field.readable and not field.writable:
                continue
            # if this is a reaonly field only show readable fields
            if readonly:
                if not field.readable:
                    continue
            # if this is an create form (unkown id) then only show writable fields
            elif not vars.get("id"):
                if not field.writable:
                    continue
            # ignore blob fields
            if field.type == "blob":  # never display blobs (mistake?)
                continue
            # ignore fields of type id its value is equal to None
            if field.type == "id" and value is None:
                field.writable = False
                continue
            # if the form is readonly or this is an id type field, display it as readonly
            if readonly or not field.writable or field.type == "id":
                if field.type == "boolean":
                    control = INPUT(
                        _type="checkbox",
                        _id=input_id,
                        _name=field.name,
                        _value="ON",
                        _disabled="",
                        _checked=value,
                        _title=title,
                    )
                else:
                    control = DIV(
                        field.represent and field.represent(value) or value or ""
                    )
            # if we have a widget for the field use it
            elif field.widget:
                control = field.widget(table, value)
            # else pick the proper default widget
            elif field.type == "text":
                control = TEXTAREA(
                    value or "",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "date":
                control = INPUT(
                    _value=value,
                    _type="date",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "datetime":
                if isinstance(value, str):
                    value = value.replace(" ", "T")
                control = INPUT(
                    _value=value,
                    _type="datetime-local",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "time":
                control = INPUT(
                    _value=value,
                    _type="time",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "boolean":
                control = INPUT(
                    _type="checkbox",
                    _id=input_id,
                    _name=field.name,
                    _value="ON",
                    _checked=value,
                    _title=title,
                )
            elif field.type == "upload":
                control = DIV()
                if value and field.download_url is not None and not error:
                    download_div = DIV()
                    download_div.append(
                        LABEL(
                            "Currently:  ",
                        )
                    )
                    download_div.append(
                        A(" download ", _href=field.download_url(value))
                    )
                    download_div.append(
                        INPUT(
                            _type="checkbox",
                            _value="ON",
                            _name="_delete_" + field.name,
                            _title=title,
                        )
                    )
                    download_div.append(" (check to remove)")
                    control.append(download_div)
                control.append(LABEL("Change: "))
                control.append(INPUT(_type="file", _id=input_id, _name=field.name))
            elif get_options(field.requires) is not None and field.writable == True:
                multiple = field.type.startswith("list:")
                value = list(map(str, value if isinstance(value, list) else [value]))
                option_tags = [
                    OPTION(v, _value=k, _selected=(not k is None and k in value))
                    for k, v in get_options(field.requires)
                ]
                control = SELECT(
                    *option_tags,
                    _id=input_id,
                    _name=field.name,
                    _multiple=multiple,
                    _title=title
                )
            else:
                field_type = "password" if field.type == "password" else "text"
                if field.type.startswith("list:"):
                    value = json.dumps(value or [])
                control = INPUT(
                    _type=field_type,
                    _id=input_id,
                    _name=field.name,
                    _value=None if field.type == "password" else value,
                    _class=field_class,
                    _placeholder=placeholder,
                    _title=title,
                    _autocomplete="off" if field_type == "password" else "on",
                )

            key = control.name.rstrip("/")
            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")
            control["_class"] = (
                control.attributes.get("_class", "") + " " + self.classes.get(key, "")
            ).strip()
            controls["labels"][field.name] = field.label
            controls["widgets"][field.name] = control
            controls["comments"][field.name] = field.comment if field.comment else ""
            controls["titles"][field.name] = title
            controls["placeholders"][field.name] = placeholder
            if error:
                controls["errors"][field.name] = error

            if field.type == "boolean":
                form.append(
                    DIV(
                        SPAN(control, _class=class_inner),
                        LABEL(
                            " " + field.label,
                            _for=input_id,
                            _class=class_label,
                            _style="display: inline !important",
                        ),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )
            else:
                form.append(
                    DIV(
                        LABEL(field.label, _for=input_id, _class=class_label),
                        DIV(control, _class=class_inner),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )

            if vars.get("id"):
                form.append(INPUT(_name="id", _value=vars["id"], _hidden=True))
        if deletable:
            controls["delete"] = INPUT(
                _type="checkbox",
                _value="ON",
                _name="_delete",
                _class=self.classes["input[type=checkbox]"],
            )
            form.append(
                DIV(
                    SPAN(
                        controls["delete"],
                        _class=class_inner,
                        _stye="vertical-align: middle;",
                    ),
                    P(
                        " check to delete",
                        _class="help",
                        _style="display: inline !important",
                    ),
                    _class=class_outer,
                )
            )
        controls["submit"] = INPUT(
            _type="submit",
            _value="Submit",
            _class=self.classes["input[type=submit]"],
        )
        submit = DIV(
            DIV(
                controls["submit"],
                _class=class_inner,
            ),
            _class=class_outer,
        )
        form.append(submit)
        return dict(form=form, controls=controls)
Beispiel #29
0
def count(number=1):
    message = T("Cat").format(n=number)
    link = A(T("more"), _href=URL("count/%s" % (number + 1)))
    return HTML(BODY(H1(message, " ", link))).xml()
Beispiel #30
0
def FormStyleDefault(table, vars, errors, readonly, deletable, classes=None):
    form = FORM(_method='POST',_action='#',_enctype='multipart/form-data')

    classes = classes or {}
    class_label = classes.get('label', '')
    class_outer = classes.get('outer', '')
    class_inner = classes.get('inner', '')
    class_error = classes.get('error', '')
    class_info = classes.get('info', '')

    for field in table:

        input_id = '%s_%s' % (field.tablename, field.name)
        value = field.formatter(vars.get(field.name))
        error = errors.get(field.name)
        field_class = field.type.split()[0].replace(':','-')

        if field.type == 'blob': # never display blobs (mistake?)
            continue
        elif readonly or field.type=='id':
            if not field.readable:
                continue
            else:
                control = DIV(field.represent and field.represent(value) or value or '')
        elif not field.writable:
            continue
        elif field.widget:
            control = field.widget(table, value)
        elif field.type == 'text':
            control = TEXTAREA(value or '', _id=input_id,_name=field.name)
        elif field.type == 'boolean':
            control = INPUT(_type='checkbox', _id=input_id, _name=field.name,
                            _value='ON', _checked = value)
        elif field.type == 'upload':
            control = DIV(INPUT(_type='file', _id=input_id, _name=field.name))
            if value:
                control.append(A('download', _href=donwload_url(value)))
                control.append(INPUT(_type='checkbox',_value='ON',
                                     _name='_delete_'+field.name))
                control.append('(check to remove)')
        elif hasattr(field.requires, 'options'):
            multiple = field.type.startswith('list:')
            value = list(map(str, value if isinstance(value, list) else [value]))
            options = [OPTION(v,_value=k,_selected=(k in value))
                       for k,v in field.requires.options()]
            control = SELECT(*options, _id=input_id, _name=field.name,
                              _multiple=multiple)
        else:
            field_type = 'password' if field.type == 'password' else 'text'
            control = INPUT(_type=field_type, _id=input_id, _name=field.name,
                            _value=value, _class=field_class)
        
        key = control.name.rstrip('/')
        if key == 'input':
            key += '[type=%s]' % (control['_type'] or 'text')
        control['_class'] = classes.get(key, '')

        form.append(DIV(
                LABEL(field.label, _for=input_id, _class=class_label),
                DIV(control, _class=class_inner),
                P(error, _class=class_error) if error else '',
                P(field.comment or '', _class=class_info),
                _class=class_outer))
        
    if deletable:
        form.append(DIV(DIV(INPUT(_type='checkbox',_value='ON',_name='_delete',
                                  _class=classes.get('input[type=checkbox]')),
                            _class=class_inner),
                        P('check to delete',_class="help"),
                        _class=class_outer))
    submit = DIV(DIV(INPUT(_type='submit',_value='Submit',
                           _class=classes.get('input[type=submit]')),
                     _class=class_inner),
                 _class=class_outer)
    form.append(submit)
    return form