WuttaWeb 0.14.2__tar.gz → 0.16.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/CHANGELOG.md +24 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/PKG-INFO +4 -3
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/pyproject.toml +4 -3
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/forms/base.py +1 -1
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/grids/base.py +10 -1
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/menus.py +44 -28
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/appinfo/index.mako +2 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/base.mako +7 -5
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/auth.py +3 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/master.py +29 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/upgrades.py +1 -1
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/users.py +9 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/grids/test_base.py +19 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_menus.py +11 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_auth.py +9 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_master.py +35 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_upgrades.py +2 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_users.py +20 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/.gitignore +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/COPYING.txt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/README.md +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/Makefile +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/_static/.keepme +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.app.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.auth.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.conf.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.db.continuum.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.db.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.db.sess.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.forms.base.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.forms.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.forms.schema.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.forms.widgets.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.grids.base.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.grids.filters.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.grids.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.handler.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.helpers.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.menus.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.progress.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.static.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.subscribers.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.util.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.auth.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.base.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.common.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.essential.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.master.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.people.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.progress.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.roles.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.settings.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.upgrades.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/api/wuttaweb.views.users.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/conf.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/glossary.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/index.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/make.bat +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/narr/templates/base.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/narr/templates/index.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/narr/templates/lookup.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/docs/narr/templates/overview.rst +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/app.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/auth.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/conf.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/db/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/db/continuum.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/db/sess.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/email/templates/feedback.html.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/email/templates/feedback.txt.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/forms/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/forms/schema.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/forms/widgets.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/grids/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/grids/filters.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/handler.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/progress.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/static/img/favicon.ico +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/static/img/logo.png +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/subscribers.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/auth/login.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/base_meta.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/configure.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/password.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/select.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/textarea.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/deform/textinput.pt +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/forbidden.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/form.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/grids/table_element.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/home.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/configure.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/create.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/delete.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/edit.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/form.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/index.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/master/view.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/notfound.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/page.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/progress.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/setup.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/upgrade.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/upgrades/view.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/templates/wutta-components.mako +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/util.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/base.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/common.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/essential.py +2 -2
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/people.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/progress.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/roles.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/src/wuttaweb/views/settings.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tasks.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/db/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/db/test_continuum.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/forms/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/forms/test_base.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/forms/test_schema.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/forms/test_widgets.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/grids/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/grids/test_filters.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_oruga.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_oruga_bulma.css +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_oruga_bulma.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_vue.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/buefy.css +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/buefy.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/fontawesome.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/vue.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/libcache/vue_resource.js +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_app.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_auth.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_handler.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_helpers.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_progress.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_static.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_subscribers.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/test_util.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/util.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/__init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test___init__.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_base.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_common.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_people.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_progress.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_roles.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tests/views/test_settings.py +0 -0
- {wuttaweb-0.14.2 → wuttaweb-0.16.0}/tox.ini +0 -0
|
@@ -5,6 +5,30 @@ All notable changes to wuttaweb will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## v0.16.0 (2024-12-05)
|
|
9
|
+
|
|
10
|
+
### Feat
|
|
11
|
+
|
|
12
|
+
- add `get_template_context()` method for master view
|
|
13
|
+
|
|
14
|
+
### Fix
|
|
15
|
+
|
|
16
|
+
- add option for People entry in the Admin menu
|
|
17
|
+
- fix handling of `Upgrade.uuid`
|
|
18
|
+
- improve support for random objects with grid, master view
|
|
19
|
+
- hide CRUD header buttons if master view does not allow
|
|
20
|
+
|
|
21
|
+
## v0.15.0 (2024-11-24)
|
|
22
|
+
|
|
23
|
+
### Feat
|
|
24
|
+
|
|
25
|
+
- add logic to prevent edit for some user accounts
|
|
26
|
+
|
|
27
|
+
### Fix
|
|
28
|
+
|
|
29
|
+
- fix default form value logic for bool checkbox fields
|
|
30
|
+
- always use configured app dist for appinfo/index page
|
|
31
|
+
|
|
8
32
|
## v0.14.2 (2024-11-24)
|
|
9
33
|
|
|
10
34
|
### Fix
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Summary: Web App for Wutta Framework
|
|
5
5
|
Project-URL: Homepage, https://wuttaproject.org/
|
|
6
6
|
Project-URL: Repository, https://forgejo.wuttaproject.org/wutta/wuttaweb
|
|
7
|
+
Project-URL: Issues, https://forgejo.wuttaproject.org/wutta/wuttaweb/issues
|
|
7
8
|
Project-URL: Changelog, https://forgejo.wuttaproject.org/wutta/wuttaweb/src/branch/master/CHANGELOG.md
|
|
8
|
-
Author-email: Lance Edgar <lance@
|
|
9
|
+
Author-email: Lance Edgar <lance@wuttaproject.org>
|
|
9
10
|
License: GNU GPL v3+
|
|
10
11
|
Classifier: Development Status :: 4 - Beta
|
|
11
12
|
Classifier: Environment :: Web Environment
|
|
@@ -35,7 +36,7 @@ Requires-Dist: pyramid-tm
|
|
|
35
36
|
Requires-Dist: pyramid>=2
|
|
36
37
|
Requires-Dist: waitress
|
|
37
38
|
Requires-Dist: webhelpers2
|
|
38
|
-
Requires-Dist: wuttjamaican[db]>=0.
|
|
39
|
+
Requires-Dist: wuttjamaican[db]>=0.16.1
|
|
39
40
|
Requires-Dist: zope-sqlalchemy>=1.5
|
|
40
41
|
Provides-Extra: continuum
|
|
41
42
|
Requires-Dist: wutta-continuum; extra == 'continuum'
|
|
@@ -6,10 +6,10 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "WuttaWeb"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.16.0"
|
|
10
10
|
description = "Web App for Wutta Framework"
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
authors = [{name = "Lance Edgar", email = "lance@
|
|
12
|
+
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
|
13
13
|
license = {text = "GNU GPL v3+"}
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 4 - Beta",
|
|
@@ -42,7 +42,7 @@ dependencies = [
|
|
|
42
42
|
"pyramid_tm",
|
|
43
43
|
"waitress",
|
|
44
44
|
"WebHelpers2",
|
|
45
|
-
"WuttJamaican[db]>=0.
|
|
45
|
+
"WuttJamaican[db]>=0.16.1",
|
|
46
46
|
"zope.sqlalchemy>=1.5",
|
|
47
47
|
]
|
|
48
48
|
|
|
@@ -68,6 +68,7 @@ wuttaweb = "wuttaweb.conf:WuttaWebConfigExtension"
|
|
|
68
68
|
[project.urls]
|
|
69
69
|
Homepage = "https://wuttaproject.org/"
|
|
70
70
|
Repository = "https://forgejo.wuttaproject.org/wutta/wuttaweb"
|
|
71
|
+
Issues = "https://forgejo.wuttaproject.org/wutta/wuttaweb/issues"
|
|
71
72
|
Changelog = "https://forgejo.wuttaproject.org/wutta/wuttaweb/src/branch/master/CHANGELOG.md"
|
|
72
73
|
|
|
73
74
|
|
|
@@ -1002,7 +1002,7 @@ class Form:
|
|
|
1002
1002
|
# for now we explicitly translate here, ugh. also
|
|
1003
1003
|
# note this does not yet allow for null values.. :(
|
|
1004
1004
|
if isinstance(field.typ, colander.Boolean):
|
|
1005
|
-
value = True if field.typ.true_val else False
|
|
1005
|
+
value = True if value == field.typ.true_val else False
|
|
1006
1006
|
|
|
1007
1007
|
model_data[field.oid] = make_json_safe(value)
|
|
1008
1008
|
|
|
@@ -1940,6 +1940,15 @@ class Grid:
|
|
|
1940
1940
|
})
|
|
1941
1941
|
return filters
|
|
1942
1942
|
|
|
1943
|
+
def object_to_dict(self, obj):
|
|
1944
|
+
""" """
|
|
1945
|
+
try:
|
|
1946
|
+
dct = dict(obj)
|
|
1947
|
+
except TypeError:
|
|
1948
|
+
dct = dict(obj.__dict__)
|
|
1949
|
+
dct.pop('_sa_instance_state', None)
|
|
1950
|
+
return dct
|
|
1951
|
+
|
|
1943
1952
|
def get_vue_context(self):
|
|
1944
1953
|
"""
|
|
1945
1954
|
Returns a dict of context for the grid, for use with the Vue
|
|
@@ -1976,7 +1985,7 @@ class Grid:
|
|
|
1976
1985
|
original_record = record
|
|
1977
1986
|
|
|
1978
1987
|
# convert record to new dict
|
|
1979
|
-
record =
|
|
1988
|
+
record = self.object_to_dict(record)
|
|
1980
1989
|
|
|
1981
1990
|
# make all values safe for json
|
|
1982
1991
|
record = make_json_safe(record, warn=False)
|
|
@@ -142,38 +142,54 @@ class MenuHandler(GenericHandler):
|
|
|
142
142
|
The return value for this method should be a *single* dict,
|
|
143
143
|
which will ultimately be one element of the final list of
|
|
144
144
|
dicts as described in :class:`MenuHandler`.
|
|
145
|
+
|
|
146
|
+
:param include_people: You can pass this flag to indicate the
|
|
147
|
+
admin menu should contain an entry for the "People" view.
|
|
145
148
|
"""
|
|
149
|
+
items = []
|
|
150
|
+
|
|
151
|
+
if kwargs.get('include_people'):
|
|
152
|
+
items.extend([
|
|
153
|
+
{
|
|
154
|
+
'title': "All People",
|
|
155
|
+
'route': 'people',
|
|
156
|
+
'perm': 'people.list',
|
|
157
|
+
},
|
|
158
|
+
])
|
|
159
|
+
|
|
160
|
+
items.extend([
|
|
161
|
+
{
|
|
162
|
+
'title': "Users",
|
|
163
|
+
'route': 'users',
|
|
164
|
+
'perm': 'users.list',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
'title': "Roles",
|
|
168
|
+
'route': 'roles',
|
|
169
|
+
'perm': 'roles.list',
|
|
170
|
+
},
|
|
171
|
+
{'type': 'sep'},
|
|
172
|
+
{
|
|
173
|
+
'title': "App Info",
|
|
174
|
+
'route': 'appinfo',
|
|
175
|
+
'perm': 'appinfo.list',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
'title': "Raw Settings",
|
|
179
|
+
'route': 'settings',
|
|
180
|
+
'perm': 'settings.list',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
'title': "Upgrades",
|
|
184
|
+
'route': 'upgrades',
|
|
185
|
+
'perm': 'upgrades.list',
|
|
186
|
+
},
|
|
187
|
+
])
|
|
188
|
+
|
|
146
189
|
return {
|
|
147
190
|
'title': "Admin",
|
|
148
191
|
'type': 'menu',
|
|
149
|
-
'items':
|
|
150
|
-
{
|
|
151
|
-
'title': "Users",
|
|
152
|
-
'route': 'users',
|
|
153
|
-
'perm': 'users.list',
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
'title': "Roles",
|
|
157
|
-
'route': 'roles',
|
|
158
|
-
'perm': 'roles.list',
|
|
159
|
-
},
|
|
160
|
-
{'type': 'sep'},
|
|
161
|
-
{
|
|
162
|
-
'title': "App Info",
|
|
163
|
-
'route': 'appinfo',
|
|
164
|
-
'perm': 'appinfo.list',
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
'title': "Raw Settings",
|
|
168
|
-
'route': 'settings',
|
|
169
|
-
'perm': 'settings.list',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
'title': "Upgrades",
|
|
173
|
-
'route': 'upgrades',
|
|
174
|
-
'perm': 'upgrades.list',
|
|
175
|
-
},
|
|
176
|
-
],
|
|
192
|
+
'items': items,
|
|
177
193
|
}
|
|
178
194
|
|
|
179
195
|
##############################
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
<div class="panel-block">
|
|
9
9
|
<div style="width: 100%;">
|
|
10
10
|
<b-field horizontal label="Distribution">
|
|
11
|
-
<span>${app.get_distribution(
|
|
11
|
+
<span>${app.get_distribution() or f'?? - set config for `{app.appname}.app_dist`'}</span>
|
|
12
12
|
</b-field>
|
|
13
13
|
<b-field horizontal label="Version">
|
|
14
|
-
<span>${app.get_version(
|
|
14
|
+
<span>${app.get_version() or f'?? - set config for `{app.appname}.app_dist`'}</span>
|
|
15
15
|
</b-field>
|
|
16
16
|
<b-field horizontal label="App Title">
|
|
17
17
|
<span>${app.get_title()}</span>
|
|
@@ -661,7 +661,9 @@
|
|
|
661
661
|
</a>
|
|
662
662
|
${h.end_form()}
|
|
663
663
|
% endif
|
|
664
|
-
|
|
664
|
+
% if request.is_root or not request.user.prevent_edit:
|
|
665
|
+
${h.link_to("Change Password", url('change_password'), class_='navbar-item')}
|
|
666
|
+
% endif
|
|
665
667
|
${h.link_to("Logout", url('logout'), class_='navbar-item')}
|
|
666
668
|
</div>
|
|
667
669
|
</div>
|
|
@@ -680,13 +682,13 @@
|
|
|
680
682
|
<%def name="render_crud_header_buttons()">
|
|
681
683
|
% if master:
|
|
682
684
|
% if master.viewing:
|
|
683
|
-
% if instance_editable and master.has_perm('edit'):
|
|
685
|
+
% if master.editable and instance_editable and master.has_perm('edit'):
|
|
684
686
|
<wutta-button once
|
|
685
687
|
tag="a" href="${master.get_action_url('edit', instance)}"
|
|
686
688
|
icon-left="edit"
|
|
687
689
|
label="Edit This" />
|
|
688
690
|
% endif
|
|
689
|
-
% if instance_deletable and master.has_perm('delete'):
|
|
691
|
+
% if master.deletable and instance_deletable and master.has_perm('delete'):
|
|
690
692
|
<wutta-button once type="is-danger"
|
|
691
693
|
tag="a" href="${master.get_action_url('delete', instance)}"
|
|
692
694
|
icon-left="trash"
|
|
@@ -699,7 +701,7 @@
|
|
|
699
701
|
icon-left="eye"
|
|
700
702
|
label="View This" />
|
|
701
703
|
% endif
|
|
702
|
-
% if instance_deletable and master.has_perm('delete'):
|
|
704
|
+
% if master.deletable and instance_deletable and master.has_perm('delete'):
|
|
703
705
|
<wutta-button once type="is-danger"
|
|
704
706
|
tag="a" href="${master.get_action_url('delete', instance)}"
|
|
705
707
|
icon-left="trash"
|
|
@@ -712,7 +714,7 @@
|
|
|
712
714
|
icon-left="eye"
|
|
713
715
|
label="View This" />
|
|
714
716
|
% endif
|
|
715
|
-
% if instance_editable and master.has_perm('edit'):
|
|
717
|
+
% if master.editable and instance_editable and master.has_perm('edit'):
|
|
716
718
|
<wutta-button once
|
|
717
719
|
tag="a" href="${master.get_action_url('edit', instance)}"
|
|
718
720
|
icon-left="edit"
|
|
@@ -157,6 +157,9 @@ class AuthView(View):
|
|
|
157
157
|
if not self.request.user:
|
|
158
158
|
return self.redirect(self.request.route_url('home'))
|
|
159
159
|
|
|
160
|
+
if self.request.user.prevent_edit:
|
|
161
|
+
raise self.forbidden()
|
|
162
|
+
|
|
160
163
|
form = self.make_form(schema=self.change_password_make_schema(),
|
|
161
164
|
show_button_cancel=False,
|
|
162
165
|
show_button_reset=True)
|
|
@@ -1629,6 +1629,9 @@ class MasterView(View):
|
|
|
1629
1629
|
if 'instance_deletable' not in context:
|
|
1630
1630
|
context['instance_deletable'] = self.is_deletable(instance)
|
|
1631
1631
|
|
|
1632
|
+
# supplement context further if needed
|
|
1633
|
+
context = self.get_template_context(context)
|
|
1634
|
+
|
|
1632
1635
|
# first try the template path most specific to this view
|
|
1633
1636
|
template_prefix = self.get_template_prefix()
|
|
1634
1637
|
mako_path = f'{template_prefix}/{template}.mako'
|
|
@@ -1648,6 +1651,26 @@ class MasterView(View):
|
|
|
1648
1651
|
# let that error raise on up
|
|
1649
1652
|
return render_to_response(mako_path, context, request=self.request)
|
|
1650
1653
|
|
|
1654
|
+
def get_template_context(self, context):
|
|
1655
|
+
"""
|
|
1656
|
+
This method should return the "complete" context for rendering
|
|
1657
|
+
the current view template.
|
|
1658
|
+
|
|
1659
|
+
Default logic for this method returns the given context
|
|
1660
|
+
unchanged.
|
|
1661
|
+
|
|
1662
|
+
You may wish to override to pass extra context to the view
|
|
1663
|
+
template. Check :attr:`viewing` and similar, or
|
|
1664
|
+
``request.current_route_name`` etc. in order to add extra
|
|
1665
|
+
context only for certain view templates.
|
|
1666
|
+
|
|
1667
|
+
:params: context: The context dict we have so far,
|
|
1668
|
+
auto-provided by the master view logic.
|
|
1669
|
+
|
|
1670
|
+
:returns: Final context dict for the template.
|
|
1671
|
+
"""
|
|
1672
|
+
return context
|
|
1673
|
+
|
|
1651
1674
|
def get_fallback_templates(self, template):
|
|
1652
1675
|
"""
|
|
1653
1676
|
Returns a list of "fallback" template paths which may be
|
|
@@ -1995,8 +2018,12 @@ class MasterView(View):
|
|
|
1995
2018
|
:param obj: Model instance object.
|
|
1996
2019
|
"""
|
|
1997
2020
|
route_prefix = self.get_route_prefix()
|
|
1998
|
-
|
|
1999
|
-
|
|
2021
|
+
try:
|
|
2022
|
+
kw = dict([(key, obj[key])
|
|
2023
|
+
for key in self.get_model_key()])
|
|
2024
|
+
except TypeError:
|
|
2025
|
+
kw = dict([(key, getattr(obj, key))
|
|
2026
|
+
for key in self.get_model_key()])
|
|
2000
2027
|
kw.update(kwargs)
|
|
2001
2028
|
return self.request.route_url(f'{route_prefix}.{action}', **kw)
|
|
2002
2029
|
|
|
@@ -217,7 +217,7 @@ class UpgradeView(MasterView):
|
|
|
217
217
|
|
|
218
218
|
def get_upgrade_filepath(self, upgrade, filename=None, create=True):
|
|
219
219
|
""" """
|
|
220
|
-
uuid = upgrade.uuid
|
|
220
|
+
uuid = str(upgrade.uuid)
|
|
221
221
|
path = self.app.get_appdir('data', 'upgrades', uuid[:2], uuid[2:],
|
|
222
222
|
create=create)
|
|
223
223
|
if filename:
|
|
@@ -95,6 +95,15 @@ class UserView(MasterView):
|
|
|
95
95
|
if not user.active:
|
|
96
96
|
return 'has-background-warning'
|
|
97
97
|
|
|
98
|
+
def is_editable(self, user):
|
|
99
|
+
""" """
|
|
100
|
+
|
|
101
|
+
# only root can edit certain users
|
|
102
|
+
if user.prevent_edit and not self.request.is_root:
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
return True
|
|
106
|
+
|
|
98
107
|
def configure_form(self, f):
|
|
99
108
|
""" """
|
|
100
109
|
super().configure_form(f)
|
|
@@ -1373,6 +1373,25 @@ class TestGrid(WebTestCase):
|
|
|
1373
1373
|
filters = grid.get_vue_filters()
|
|
1374
1374
|
self.assertEqual(len(filters), 2)
|
|
1375
1375
|
|
|
1376
|
+
def test_object_to_dict(self):
|
|
1377
|
+
grid = self.make_grid()
|
|
1378
|
+
setting = {'name': 'foo', 'value': 'bar'}
|
|
1379
|
+
|
|
1380
|
+
# new dict but with same values
|
|
1381
|
+
dct = grid.object_to_dict(setting)
|
|
1382
|
+
self.assertIsInstance(dct, dict)
|
|
1383
|
+
self.assertIsNot(dct, setting)
|
|
1384
|
+
self.assertEqual(dct, setting)
|
|
1385
|
+
|
|
1386
|
+
# random object, not iterable
|
|
1387
|
+
class MockSetting:
|
|
1388
|
+
def __init__(self, **kw):
|
|
1389
|
+
self.__dict__.update(kw)
|
|
1390
|
+
mock = MockSetting(**setting)
|
|
1391
|
+
dct = grid.object_to_dict(mock)
|
|
1392
|
+
self.assertIsInstance(dct, dict)
|
|
1393
|
+
self.assertEqual(dct, setting)
|
|
1394
|
+
|
|
1376
1395
|
def test_get_vue_context(self):
|
|
1377
1396
|
|
|
1378
1397
|
# empty if no columns defined
|
|
@@ -14,8 +14,17 @@ class TestMenuHandler(WebTestCase):
|
|
|
14
14
|
self.handler = mod.MenuHandler(self.config)
|
|
15
15
|
|
|
16
16
|
def test_make_admin_menu(self):
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
# no people entry by default
|
|
19
|
+
menu = self.handler.make_admin_menu(self.request)
|
|
20
|
+
self.assertIsInstance(menu, dict)
|
|
21
|
+
routes = [item.get('route') for item in menu['items']]
|
|
22
|
+
self.assertNotIn('people', routes)
|
|
23
|
+
|
|
24
|
+
# but we can request it
|
|
25
|
+
menu = self.handler.make_admin_menu(self.request, include_people=True)
|
|
26
|
+
routes = [item.get('route') for item in menu['items']]
|
|
27
|
+
self.assertIn('people', routes)
|
|
19
28
|
|
|
20
29
|
def test_make_menus(self):
|
|
21
30
|
menus = self.handler.make_menus(self.request)
|
|
@@ -80,11 +80,18 @@ class TestAuthView(WebTestCase):
|
|
|
80
80
|
redirect = view.change_password()
|
|
81
81
|
self.assertIsInstance(redirect, HTTPFound)
|
|
82
82
|
|
|
83
|
-
#
|
|
84
|
-
self.request.user = barney
|
|
83
|
+
# set initial password
|
|
85
84
|
auth.set_user_password(barney, 'foo')
|
|
86
85
|
self.session.commit()
|
|
87
86
|
|
|
87
|
+
# forbidden if prevent_edit is set for user
|
|
88
|
+
self.request.user = barney
|
|
89
|
+
barney.prevent_edit = True
|
|
90
|
+
self.assertRaises(HTTPForbidden, view.change_password)
|
|
91
|
+
|
|
92
|
+
# okay let's test with edit allowed
|
|
93
|
+
barney.prevent_edit = False
|
|
94
|
+
|
|
88
95
|
# view should now return context w/ form
|
|
89
96
|
context = view.change_password()
|
|
90
97
|
self.assertIn('form', context)
|
|
@@ -734,6 +734,41 @@ class TestMasterView(WebTestCase):
|
|
|
734
734
|
self.request.matchdict = {'name': 'blarg'}
|
|
735
735
|
self.assertRaises(HTTPNotFound, view.get_instance, session=self.session)
|
|
736
736
|
|
|
737
|
+
def test_get_action_url_for_dict(self):
|
|
738
|
+
model = self.app.model
|
|
739
|
+
setting = {'name': 'foo', 'value': 'bar'}
|
|
740
|
+
with patch.multiple(mod.MasterView, create=True,
|
|
741
|
+
model_class=model.Setting):
|
|
742
|
+
mod.MasterView.defaults(self.pyramid_config)
|
|
743
|
+
view = self.make_view()
|
|
744
|
+
url = view.get_action_url_view(setting, 0)
|
|
745
|
+
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
|
746
|
+
|
|
747
|
+
def test_get_action_url_for_orm_object(self):
|
|
748
|
+
model = self.app.model
|
|
749
|
+
setting = model.Setting(name='foo', value='bar')
|
|
750
|
+
self.session.add(setting)
|
|
751
|
+
self.session.commit()
|
|
752
|
+
with patch.multiple(mod.MasterView, create=True,
|
|
753
|
+
model_class=model.Setting):
|
|
754
|
+
mod.MasterView.defaults(self.pyramid_config)
|
|
755
|
+
view = self.make_view()
|
|
756
|
+
url = view.get_action_url_view(setting, 0)
|
|
757
|
+
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
|
758
|
+
|
|
759
|
+
def test_get_action_url_for_adhoc_object(self):
|
|
760
|
+
model = self.app.model
|
|
761
|
+
class MockSetting:
|
|
762
|
+
def __init__(self, **kw):
|
|
763
|
+
self.__dict__.update(kw)
|
|
764
|
+
setting = MockSetting(name='foo', value='bar')
|
|
765
|
+
with patch.multiple(mod.MasterView, create=True,
|
|
766
|
+
model_class=model.Setting):
|
|
767
|
+
mod.MasterView.defaults(self.pyramid_config)
|
|
768
|
+
view = self.make_view()
|
|
769
|
+
url = view.get_action_url_view(setting, 0)
|
|
770
|
+
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
|
771
|
+
|
|
737
772
|
def test_get_action_url_view(self):
|
|
738
773
|
model = self.app.model
|
|
739
774
|
setting = model.Setting(name='foo', value='bar')
|
|
@@ -127,7 +127,7 @@ class TestUpgradeView(WebTestCase):
|
|
|
127
127
|
self.session.commit()
|
|
128
128
|
|
|
129
129
|
view = self.make_view()
|
|
130
|
-
uuid = upgrade.uuid
|
|
130
|
+
uuid = str(upgrade.uuid)
|
|
131
131
|
|
|
132
132
|
# no filename
|
|
133
133
|
path = view.download_path(upgrade, None)
|
|
@@ -153,7 +153,7 @@ class TestUpgradeView(WebTestCase):
|
|
|
153
153
|
self.session.commit()
|
|
154
154
|
|
|
155
155
|
view = self.make_view()
|
|
156
|
-
uuid = upgrade.uuid
|
|
156
|
+
uuid = str(upgrade.uuid)
|
|
157
157
|
|
|
158
158
|
# no filename
|
|
159
159
|
path = view.get_upgrade_filepath(upgrade)
|
|
@@ -42,6 +42,26 @@ class TestUserView(WebTestCase):
|
|
|
42
42
|
user.active = False
|
|
43
43
|
self.assertEqual(view.grid_row_class(user, data, 1), 'has-background-warning')
|
|
44
44
|
|
|
45
|
+
def test_is_editable(self):
|
|
46
|
+
model = self.app.model
|
|
47
|
+
view = self.make_view()
|
|
48
|
+
|
|
49
|
+
# active user is editable
|
|
50
|
+
user = model.User(username='barney', active=True)
|
|
51
|
+
self.assertTrue(view.is_editable(user))
|
|
52
|
+
|
|
53
|
+
# inactive also editable
|
|
54
|
+
user = model.User(username='barney', active=False)
|
|
55
|
+
self.assertTrue(view.is_editable(user))
|
|
56
|
+
|
|
57
|
+
# but not if prevent_edit flag is set
|
|
58
|
+
user = model.User(username='barney', prevent_edit=True)
|
|
59
|
+
self.assertFalse(view.is_editable(user))
|
|
60
|
+
|
|
61
|
+
# unless request user is root
|
|
62
|
+
self.request.is_root = True
|
|
63
|
+
self.assertTrue(view.is_editable(user))
|
|
64
|
+
|
|
45
65
|
def test_configure_form(self):
|
|
46
66
|
model = self.app.model
|
|
47
67
|
barney = model.User(username='barney')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -29,8 +29,8 @@ Most apps should include this module::
|
|
|
29
29
|
|
|
30
30
|
That will in turn include the following modules:
|
|
31
31
|
|
|
32
|
-
* :mod:`wuttaweb.views.auth`
|
|
33
32
|
* :mod:`wuttaweb.views.common`
|
|
33
|
+
* :mod:`wuttaweb.views.auth`
|
|
34
34
|
* :mod:`wuttaweb.views.settings`
|
|
35
35
|
* :mod:`wuttaweb.views.progress`
|
|
36
36
|
* :mod:`wuttaweb.views.people`
|
|
@@ -43,8 +43,8 @@ That will in turn include the following modules:
|
|
|
43
43
|
def defaults(config, **kwargs):
|
|
44
44
|
mod = lambda spec: kwargs.get(spec, spec)
|
|
45
45
|
|
|
46
|
-
config.include(mod('wuttaweb.views.auth'))
|
|
47
46
|
config.include(mod('wuttaweb.views.common'))
|
|
47
|
+
config.include(mod('wuttaweb.views.auth'))
|
|
48
48
|
config.include(mod('wuttaweb.views.settings'))
|
|
49
49
|
config.include(mod('wuttaweb.views.progress'))
|
|
50
50
|
config.include(mod('wuttaweb.views.people'))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|