14.2.119. camcops_server.cc_modules.webview

camcops_server/cc_modules/webview.py


Copyright (C) 2012-2019 Rudolf Cardinal (rudolf@pobox.com).

This file is part of CamCOPS.

CamCOPS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

CamCOPS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with CamCOPS. If not, see <http://www.gnu.org/licenses/>.


Implements the CamCOPS web front end.

Quick tutorial on Pyramid views:

  • The configurator registers routes, and routes have URLs associated with them. Those URLs can be templatized, e.g. to accept numerical parameters. The configurator associates view callables (“views” for short) with routes, and one method for doing that is an automatic scan via Venusian for views decorated with @view_config().

  • All views take a Request object and return a Response or raise an exception that Pyramid will translate into a Response.

  • Having matched a route, Pyramid uses its “view lookup” process to choose one from potentially several views. For example, a single route might be associated with:

    @view_config(route_name="myroute")
    def myroute_default(req: Request) -> Response:
        pass
    
    @view_config(route_name="myroute", method="POST")
    def myroute_post(req: Request) -> Response:
        pass
    

    In this example, POST requests will go to the second; everything else will go to the first. Pyramid’s view lookup rule is essentially: if multiple views match, choose the one with the most specifiers.

  • Specifiers include:

    route_name=ROUTENAME
    
        the route
    
    request_method="POST"
    
        requires HTTP GET, POST, etc.
    
    request_param="XXX"
    
        ... requires the presence of a GET/POST variable with this name in
        the request.params dictionary
    
    request_param="XXX=YYY"
    
        ... requires the presence of a GET/POST variable called XXX whose
        value is YYY, in the request.params dictionary
    
    match_param="XXX=YYY"
    
        .. requires the presence of this key/value pair in
        request.matchdict, which contains parameters from the URL
    

    https://docs.pylonsproject.org/projects/pyramid/en/latest/api/config.html#pyramid.config.Configurator.add_view # noqa

  • Getting parameters

    request.params
    
        ... parameters from HTTP GET or POST, including both the query
        string (as in http://somewhere/path?key=value) and the body (e.g.
        POST).
    
    request.matchdict
    
        ... parameters from the URL, via URL dispatch; see
        https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#urldispatch-chapter  # noqa
    
  • Regarding rendering:

    There might be some simplicity benefits from converting to a template system like Mako. On the downside, that would entail a bit more work; likely a minor performance hit (relative to plain Python string rendering); and a loss of type checking. The type checking is also why we prefer:

    html = " ... {param_blah} ...".format(param_blah=PARAM.BLAH)
    

    to

    html = " ... {PARAM.BLAH} ...".format(PARAM=PARAM)
    

    as in the first situation, PyCharm will check that “BLAH” is present in “PARAM”, and in the second it won’t. Automatic checking is worth a lot.

camcops_server.cc_modules.webview.account_locked(req: CamcopsRequest, locked_until: pendulum.datetime.DateTime) → pyramid.response.Response[source]

Response given when account locked out. Returned by login_view() only.

camcops_server.cc_modules.webview.add_group(req: CamcopsRequest) → Dict[str, Any][source]

View to add a group. Superusers only.

camcops_server.cc_modules.webview.add_id_definition(req: CamcopsRequest) → Dict[str, Any][source]

View to add an ID number definition. Superusers only.

camcops_server.cc_modules.webview.add_special_note(req: CamcopsRequest) → Dict[str, Any][source]

View to add a special note to a task (after confirmation).

camcops_server.cc_modules.webview.add_user(req: CamcopsRequest) → Dict[str, Any][source]

View to add a user.

camcops_server.cc_modules.webview.any_records_use_group(req: CamcopsRequest, group: camcops_server.cc_modules.cc_group.Group) → bool[source]

Do any records in the database refer to the specified group?

(Used when we’re thinking about deleting a group; would it leave broken references? If so, we will prevent deletion; see delete_group().)

camcops_server.cc_modules.webview.any_records_use_iddef(req: CamcopsRequest, iddef: camcops_server.cc_modules.cc_idnumdef.IdNumDefinition) → bool[source]

Do any records in the database refer to the specified ID number definition?

(Used when we’re thinking about deleting one; would it leave broken references? If so, we will prevent deletion; see delete_id_definition().)

camcops_server.cc_modules.webview.any_records_use_user(req: CamcopsRequest, user: camcops_server.cc_modules.cc_user.User) → bool[source]

Do any records in the database refer to the specified user?

(Used when we’re thinking about deleting a user; would it leave broken references? If so, we will prevent deletion; see delete_user().)

camcops_server.cc_modules.webview.assert_may_administer_group(req: CamcopsRequest, group_id: int) → None[source]

Checks that the requesting user (req.user) is allowed to adminster the specified group (specified by group_id). Raises HTTPBadRequest otherwise.

camcops_server.cc_modules.webview.assert_may_edit_user(req: CamcopsRequest, user: camcops_server.cc_modules.cc_user.User) → None[source]

Checks that the requesting user (req.user) is allowed to edit the other user (user). Raises HTTPBadRequest otherwise.

camcops_server.cc_modules.webview.audit_menu(req: CamcopsRequest) → Dict[str, Any][source]

Shows the auditing menu.

camcops_server.cc_modules.webview.bad_request(req: CamcopsRequest) → Dict[str, Any][source]

“Bad request” view.

NOTE that this view only gets used from

raise HTTPBadRequest("message")

and not

return HTTPBadRequest("message")

… so always raise it.

camcops_server.cc_modules.webview.change_other_password(req: CamcopsRequest) → pyramid.response.Response[source]

For administrators, to change another’s password.

  • GET: offer “change another’s password” view (except that if you’re changing your own password, return change_own_password().
  • POST/submit: change the password and return password_changed().
camcops_server.cc_modules.webview.change_own_password(req: CamcopsRequest) → pyramid.response.Response[source]

For any user: to change their own password.

  • GET: offer “change own password” view
  • POST/submit: change the password and return password_changed().
camcops_server.cc_modules.webview.choose_ctv(req: CamcopsRequest) → Dict[str, Any][source]

View to choose/configure a camcops_server.cc_modules.cc_tracker.ClinicalTextView.

camcops_server.cc_modules.webview.choose_tracker(req: CamcopsRequest) → Dict[str, Any][source]

View to choose/configure a camcops_server.cc_modules.cc_tracker.Tracker.

camcops_server.cc_modules.webview.choose_tracker_or_ctv(req: CamcopsRequest, as_ctv: bool) → Dict[str, Any][source]

Returns a dictionary for a Mako template to configure a camcops_server.cc_modules.cc_tracker.Tracker or camcops_server.cc_modules.cc_tracker.ClinicalTextView.

Upon success, it redirects to the tracker or CTV view itself, with the tracker’s parameters embedded as URL parameters.

Parameters:
camcops_server.cc_modules.webview.crash(req: CamcopsRequest) → pyramid.response.Response[source]

A view that deliberately raises an exception.

camcops_server.cc_modules.webview.delete_group(req: CamcopsRequest) → Dict[str, Any][source]

View to delete a group. Superusers only.

camcops_server.cc_modules.webview.delete_id_definition(req: CamcopsRequest) → Dict[str, Any][source]

View to delete an ID number definition. Superusers only.

camcops_server.cc_modules.webview.delete_patient(req: CamcopsRequest) → pyramid.response.Response[source]

View to cdelete ompletely all data from a patient (after confirmation), within a specific group.

camcops_server.cc_modules.webview.delete_special_note(req: CamcopsRequest) → Dict[str, Any][source]

View to delete a special note (after confirmation).

camcops_server.cc_modules.webview.delete_user(req: CamcopsRequest) → Dict[str, Any][source]

View to delete a user (and make it hard work).

camcops_server.cc_modules.webview.developer_page(req: CamcopsRequest) → Dict[str, Any][source]

Shows the developer menu.

camcops_server.cc_modules.webview.edit_filter(req: CamcopsRequest, task_filter: camcops_server.cc_modules.cc_taskfilter.TaskFilter, redirect_url: str) → pyramid.response.Response[source]

Edit the task filter for the current user.

Parameters:
camcops_server.cc_modules.webview.edit_group(req: CamcopsRequest) → Dict[str, Any][source]

View to edit a group. Superusers only.

camcops_server.cc_modules.webview.edit_id_definition(req: CamcopsRequest) → Dict[str, Any][source]

View to edit an ID number definition. Superusers only.

camcops_server.cc_modules.webview.edit_patient(req: CamcopsRequest) → pyramid.response.Response[source]

View to edit details for a patient.

camcops_server.cc_modules.webview.edit_server_settings(req: CamcopsRequest) → Dict[str, Any][source]

View to edit server settings (like the database title).

camcops_server.cc_modules.webview.edit_user(req: CamcopsRequest) → Dict[str, Any][source]

View to edit a user (for administrators).

camcops_server.cc_modules.webview.edit_user_group_membership(req: CamcopsRequest) → Dict[str, Any][source]

View to edit the group memberships of a user (for administrators).

camcops_server.cc_modules.webview.erase_task(req: CamcopsRequest) → pyramid.response.Response[source]

View to wipe all data from a task (after confirmation).

Leaves the task record as a placeholder.

camcops_server.cc_modules.webview.forbidden(req: CamcopsRequest) → pyramid.response.Response[source]

Generic place that Pyramid comes when permission is denied for a view.

We will offer one of these:

  • Must change password? Redirect to “change own password” view.
  • Must agree terms? Redirect to “offer terms” view.
  • Otherwise: a generic “forbidden” view.
camcops_server.cc_modules.webview.forcibly_finalize(req: CamcopsRequest) → pyramid.response.Response[source]

View to force-finalize all live (_era == ERA_NOW) records from a device. Available to group administrators if all those records are within their groups (otherwise, it’s a superuser operation).

camcops_server.cc_modules.webview.get_dump_collection(req: CamcopsRequest) → camcops_server.cc_modules.cc_taskcollection.TaskCollection[source]

Returns the collection of tasks being requested for a dump operation. Raises an error if the request is bad.

camcops_server.cc_modules.webview.get_group_from_request_group_id_or_raise(req: CamcopsRequest) → camcops_server.cc_modules.cc_group.Group[source]

Returns the camcops_server.cc_modules.cc_group.Group represented by the request’s ViewParam.GROUP_ID parameter, or raise HTTPBadRequest.

camcops_server.cc_modules.webview.get_iddef_from_request_which_idnum_or_raise(req: CamcopsRequest) → camcops_server.cc_modules.cc_idnumdef.IdNumDefinition[source]

Returns the camcops_server.cc_modules.cc_idnumdef.IdNumDefinition represented by the request’s ViewParam.WHICH_IDNUM parameter, or raise HTTPBadRequest.

camcops_server.cc_modules.webview.get_user_from_request_user_id_or_raise(req: CamcopsRequest) → camcops_server.cc_modules.cc_user.User[source]

Returns the camcops_server.cc_modules.cc_user.User represented by the request’s ViewParam.USER_ID parameter, or raise HTTPBadRequest.

camcops_server.cc_modules.webview.login_failed(req: CamcopsRequest) → pyramid.response.Response[source]

Response given after login failure. Returned by login_view() only.

camcops_server.cc_modules.webview.login_view(req: CamcopsRequest) → pyramid.response.Response[source]

Login view.

  • GET: presents the login screen
  • POST/submit: attempts to log in;
    • failure: returns a login failure view or an account lockout view
    • success:
      • redirects to the redirection view if one was specified;
      • redirects to the home view if not.
camcops_server.cc_modules.webview.logout(req: CamcopsRequest) → Dict[str, Any][source]

Logs a session out, and returns the “logged out” view.

camcops_server.cc_modules.webview.main_menu(req: CamcopsRequest) → Dict[str, Any][source]

Main CamCOPS menu view.

camcops_server.cc_modules.webview.not_found(req: CamcopsRequest) → Dict[str, Any][source]

“Page not found” view.

camcops_server.cc_modules.webview.offer_audit_trail(req: CamcopsRequest) → pyramid.response.Response[source]

View to configure how we’ll view the audit trail. Once configured, it redirects to a view that shows the audit trail (with query parameters in the URL).

camcops_server.cc_modules.webview.offer_basic_dump(req: CamcopsRequest) → pyramid.response.Response[source]

View to configure a basic research dump. Following submission success, it redirects to a view serving a TSV/ZIP dump.

camcops_server.cc_modules.webview.offer_exported_task_list(req: CamcopsRequest) → pyramid.response.Response[source]

View to choose how we’ll view the exported task log.

camcops_server.cc_modules.webview.offer_report(req: CamcopsRequest) → pyramid.response.Response[source]

Offer configuration options for a single report, or (following submission) redirect to serve that report (with configuration parameters in the URL).

camcops_server.cc_modules.webview.offer_sql_dump(req: CamcopsRequest) → pyramid.response.Response[source]

View to configure a SQL research dump. Following submission success, it redirects to a view serving the SQL dump.

camcops_server.cc_modules.webview.offer_terms(req: CamcopsRequest) → pyramid.response.Response[source]
  • GET: show terms/conditions and request acknowledgement
  • POST/submit: note the user’s agreement; redirect to the home view.
camcops_server.cc_modules.webview.password_changed(req: CamcopsRequest, username: str, own_password: bool) → pyramid.response.Response[source]

Generic “the password has been changed” view (whether changing your own or another’s password).

Parameters:
camcops_server.cc_modules.webview.reports_menu(req: CamcopsRequest) → Dict[str, Any][source]

Offer a menu of reports.

Note: Reports are not group-specific. If you’re authorized to see any, you’ll see the whole menu. (The data you get will be restricted to the group’s you’re authorized to run reports for.)

camcops_server.cc_modules.webview.serve_basic_dump(req: CamcopsRequest) → pyramid.response.Response[source]

View serving a TSV/ZIP basic research dump.

camcops_server.cc_modules.webview.serve_ctv(req: CamcopsRequest) → pyramid.response.Response[source]

View to serve a camcops_server.cc_modules.cc_tracker.ClinicalTextView; see serve_tracker_or_ctv().

camcops_server.cc_modules.webview.serve_report(req: CamcopsRequest) → pyramid.response.Response[source]

Serve a configured report.

camcops_server.cc_modules.webview.serve_task(req: CamcopsRequest) → pyramid.response.Response[source]

View that serves an individual task, in a variety of possible formats (e.g. HTML, PDF, XML).

camcops_server.cc_modules.webview.serve_tracker(req: CamcopsRequest) → pyramid.response.Response[source]

View to serve a camcops_server.cc_modules.cc_tracker.Tracker; see serve_tracker_or_ctv().

camcops_server.cc_modules.webview.serve_tracker_or_ctv(req: CamcopsRequest, as_ctv: bool) → pyramid.response.Response[source]

Returns a response to show a camcops_server.cc_modules.cc_tracker.Tracker or camcops_server.cc_modules.cc_tracker.ClinicalTextView, in a variety of formats (e.g. HTML, PDF, XML).

Parameters:
camcops_server.cc_modules.webview.set_filters(req: CamcopsRequest) → pyramid.response.Response[source]

View to set the task filters for the current user.

camcops_server.cc_modules.webview.set_other_user_upload_group(req: CamcopsRequest) → pyramid.response.Response[source]

View to set the upload group for another user.

camcops_server.cc_modules.webview.set_own_user_upload_group(req: CamcopsRequest) → pyramid.response.Response[source]

View to set the upload group for your own user.

camcops_server.cc_modules.webview.set_user_upload_group(req: CamcopsRequest, user: camcops_server.cc_modules.cc_user.User, by_another: bool) → pyramid.response.Response[source]

Provides a view to choose which group a user uploads into.

TRUSTS ITS CALLER that this is permitted.

Parameters:
camcops_server.cc_modules.webview.simple_failure(req: CamcopsRequest, msg: str, extra_html: str = '') → pyramid.response.Response[source]

Simple failure response.

camcops_server.cc_modules.webview.simple_success(req: CamcopsRequest, msg: str, extra_html: str = '') → pyramid.response.Response[source]

Simple success response.

camcops_server.cc_modules.webview.sql_dump(req: CamcopsRequest) → pyramid.response.Response[source]

View serving an SQL dump in the chosen format (e.g. SQLite binary, SQL).

camcops_server.cc_modules.webview.static_bugfix_deform_missing_glyphs(req: CamcopsRequest) → pyramid.response.Response[source]

Hack for a missing-file bug in deform==2.0.4.

camcops_server.cc_modules.webview.test_page_1(req: CamcopsRequest) → pyramid.response.Response[source]

A public test page with no content.

camcops_server.cc_modules.webview.test_page_2(req: CamcopsRequest) → Dict[str, Any][source]

A private test page containing POTENTIALLY SENSITIVE test information, including environment variables, that should only be accessible to superusers.

camcops_server.cc_modules.webview.test_page_3(req: CamcopsRequest) → Dict[str, Any][source]

A private test page that tests template inheritance.

camcops_server.cc_modules.webview.test_page_private_1(req: CamcopsRequest) → pyramid.response.Response[source]

A private test page with no informative content, but which should only be accessible to authenticated users.

camcops_server.cc_modules.webview.unlock_user(req: CamcopsRequest) → pyramid.response.Response[source]

View to unlock a locked user account.

camcops_server.cc_modules.webview.view_all_users(req: CamcopsRequest) → Dict[str, Any][source]

View all users that the current user administers. The view has hyperlinks to edit those users too.

camcops_server.cc_modules.webview.view_audit_trail(req: CamcopsRequest) → pyramid.response.Response[source]

View to serve the audit trail.

camcops_server.cc_modules.webview.view_ddl(req: CamcopsRequest) → pyramid.response.Response[source]

Inspect table definitions (data definition language, DDL) with field comments.

camcops_server.cc_modules.webview.view_email(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_email.Email.

camcops_server.cc_modules.webview.view_export_recipient(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_exportmodels.ExportedTask.

camcops_server.cc_modules.webview.view_exported_task(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_exportmodels.ExportedTask.

camcops_server.cc_modules.webview.view_exported_task_email(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_exportmodels.ExportedTaskEmail.

camcops_server.cc_modules.webview.view_exported_task_file_group(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_exportmodels.ExportedTaskFileGroup.

camcops_server.cc_modules.webview.view_exported_task_hl7_message(req: CamcopsRequest) → pyramid.response.Response[source]

View on an individual camcops_server.cc_modules.cc_exportmodels.ExportedTaskHL7Message.

camcops_server.cc_modules.webview.view_exported_task_list(req: CamcopsRequest) → pyramid.response.Response[source]

View to serve the exported task log.

camcops_server.cc_modules.webview.view_groups(req: CamcopsRequest) → Dict[str, Any][source]

View to show all groups (with hyperlinks to edit them). Superusers only.

camcops_server.cc_modules.webview.view_id_definitions(req: CamcopsRequest) → Dict[str, Any][source]

View to show all ID number definitions (with hyperlinks to edit them). Superusers only.

camcops_server.cc_modules.webview.view_own_user_info(req: CamcopsRequest) → Dict[str, Any][source]

View to provide information about your own user.

camcops_server.cc_modules.webview.view_server_info(req: CamcopsRequest) → Dict[str, Any][source]

View to show the server’s ID policies, etc.

camcops_server.cc_modules.webview.view_tasks(req: CamcopsRequest) → Dict[str, Any][source]

Main view displaying tasks and applicable filters.

camcops_server.cc_modules.webview.view_user(req: CamcopsRequest) → Dict[str, Any][source]

View to show details of another user, for administrators.

camcops_server.cc_modules.webview.view_user_email_addresses(req: CamcopsRequest) → Dict[str, Any][source]

View e-mail addresses of all users that the requesting user is authorized to manage.