WuttaWeb 0.13.1__tar.gz → 0.14.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.
Files changed (182) hide show
  1. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/CHANGELOG.md +6 -0
  2. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/PKG-INFO +4 -2
  3. wuttaweb-0.14.0/docs/api/wuttaweb.conf.rst +6 -0
  4. wuttaweb-0.14.0/docs/api/wuttaweb.db.continuum.rst +6 -0
  5. wuttaweb-0.14.0/docs/api/wuttaweb.db.sess.rst +6 -0
  6. wuttaweb-0.14.0/docs/api/wuttaweb.rst +6 -0
  7. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/conf.py +1 -0
  8. wuttaweb-0.14.0/docs/index.rst +68 -0
  9. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/pyproject.toml +7 -2
  10. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/auth.py +2 -1
  11. wuttaweb-0.14.0/src/wuttaweb/conf.py +43 -0
  12. wuttaweb-0.14.0/src/wuttaweb/db/__init__.py +31 -0
  13. wuttaweb-0.14.0/src/wuttaweb/db/continuum.py +56 -0
  14. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/forms/schema.py +1 -1
  15. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/forms/widgets.py +6 -3
  16. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/subscribers.py +1 -1
  17. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/util.py +10 -4
  18. wuttaweb-0.14.0/tests/db/test_continuum.py +38 -0
  19. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/forms/test_widgets.py +19 -3
  20. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_util.py +21 -0
  21. wuttaweb-0.14.0/tests/views/__init__.py +0 -0
  22. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tox.ini +5 -2
  23. wuttaweb-0.13.1/docs/api/index.rst +0 -10
  24. wuttaweb-0.13.1/docs/api/wuttaweb/index.rst +0 -38
  25. wuttaweb-0.13.1/docs/index.rst +0 -28
  26. wuttaweb-0.13.1/docs/narr/index.rst +0 -8
  27. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/.gitignore +0 -0
  28. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/COPYING.txt +0 -0
  29. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/README.md +0 -0
  30. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/Makefile +0 -0
  31. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/_static/.keepme +0 -0
  32. /wuttaweb-0.13.1/docs/api/wuttaweb/app.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.app.rst +0 -0
  33. /wuttaweb-0.13.1/docs/api/wuttaweb/auth.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.auth.rst +0 -0
  34. /wuttaweb-0.13.1/docs/api/wuttaweb/db.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.db.rst +0 -0
  35. /wuttaweb-0.13.1/docs/api/wuttaweb/forms.base.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.forms.base.rst +0 -0
  36. /wuttaweb-0.13.1/docs/api/wuttaweb/forms.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.forms.rst +0 -0
  37. /wuttaweb-0.13.1/docs/api/wuttaweb/forms.schema.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.forms.schema.rst +0 -0
  38. /wuttaweb-0.13.1/docs/api/wuttaweb/forms.widgets.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.forms.widgets.rst +0 -0
  39. /wuttaweb-0.13.1/docs/api/wuttaweb/grids.base.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.grids.base.rst +0 -0
  40. /wuttaweb-0.13.1/docs/api/wuttaweb/grids.filters.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.grids.filters.rst +0 -0
  41. /wuttaweb-0.13.1/docs/api/wuttaweb/grids.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.grids.rst +0 -0
  42. /wuttaweb-0.13.1/docs/api/wuttaweb/handler.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.handler.rst +0 -0
  43. /wuttaweb-0.13.1/docs/api/wuttaweb/helpers.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.helpers.rst +0 -0
  44. /wuttaweb-0.13.1/docs/api/wuttaweb/menus.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.menus.rst +0 -0
  45. /wuttaweb-0.13.1/docs/api/wuttaweb/progress.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.progress.rst +0 -0
  46. /wuttaweb-0.13.1/docs/api/wuttaweb/static.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.static.rst +0 -0
  47. /wuttaweb-0.13.1/docs/api/wuttaweb/subscribers.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.subscribers.rst +0 -0
  48. /wuttaweb-0.13.1/docs/api/wuttaweb/util.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.util.rst +0 -0
  49. /wuttaweb-0.13.1/docs/api/wuttaweb/views.auth.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.auth.rst +0 -0
  50. /wuttaweb-0.13.1/docs/api/wuttaweb/views.base.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.base.rst +0 -0
  51. /wuttaweb-0.13.1/docs/api/wuttaweb/views.common.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.common.rst +0 -0
  52. /wuttaweb-0.13.1/docs/api/wuttaweb/views.essential.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.essential.rst +0 -0
  53. /wuttaweb-0.13.1/docs/api/wuttaweb/views.master.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.master.rst +0 -0
  54. /wuttaweb-0.13.1/docs/api/wuttaweb/views.people.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.people.rst +0 -0
  55. /wuttaweb-0.13.1/docs/api/wuttaweb/views.progress.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.progress.rst +0 -0
  56. /wuttaweb-0.13.1/docs/api/wuttaweb/views.roles.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.roles.rst +0 -0
  57. /wuttaweb-0.13.1/docs/api/wuttaweb/views.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.rst +0 -0
  58. /wuttaweb-0.13.1/docs/api/wuttaweb/views.settings.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.settings.rst +0 -0
  59. /wuttaweb-0.13.1/docs/api/wuttaweb/views.upgrades.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.upgrades.rst +0 -0
  60. /wuttaweb-0.13.1/docs/api/wuttaweb/views.users.rst → /wuttaweb-0.14.0/docs/api/wuttaweb.views.users.rst +0 -0
  61. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/glossary.rst +0 -0
  62. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/make.bat +0 -0
  63. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/narr/templates/base.rst +0 -0
  64. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/narr/templates/index.rst +0 -0
  65. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/narr/templates/lookup.rst +0 -0
  66. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/docs/narr/templates/overview.rst +0 -0
  67. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/__init__.py +0 -0
  68. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/_version.py +0 -0
  69. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/app.py +0 -0
  70. /wuttaweb-0.13.1/src/wuttaweb/db.py → /wuttaweb-0.14.0/src/wuttaweb/db/sess.py +0 -0
  71. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/email/templates/feedback.html.mako +0 -0
  72. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/email/templates/feedback.txt.mako +0 -0
  73. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/forms/__init__.py +0 -0
  74. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/forms/base.py +0 -0
  75. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/grids/__init__.py +0 -0
  76. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/grids/base.py +0 -0
  77. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/grids/filters.py +0 -0
  78. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/handler.py +0 -0
  79. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/helpers.py +0 -0
  80. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/menus.py +0 -0
  81. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/progress.py +0 -0
  82. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/static/__init__.py +0 -0
  83. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/static/img/favicon.ico +0 -0
  84. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/static/img/logo.png +0 -0
  85. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/static/img/testing.png +0 -0
  86. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
  87. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/appinfo/index.mako +0 -0
  88. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  89. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/auth/login.mako +0 -0
  90. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/base.mako +0 -0
  91. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/base_meta.mako +0 -0
  92. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/configure.mako +0 -0
  93. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
  94. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  95. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
  96. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
  97. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/password.pt +0 -0
  98. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  99. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
  100. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
  101. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  102. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  103. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  104. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
  105. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/select.pt +0 -0
  106. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/textarea.pt +0 -0
  107. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/deform/textinput.pt +0 -0
  108. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/forbidden.mako +0 -0
  109. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/form.mako +0 -0
  110. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
  111. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/grids/table_element.mako +0 -0
  112. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
  113. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/home.mako +0 -0
  114. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/configure.mako +0 -0
  115. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/create.mako +0 -0
  116. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/delete.mako +0 -0
  117. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/edit.mako +0 -0
  118. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/form.mako +0 -0
  119. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/index.mako +0 -0
  120. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/master/view.mako +0 -0
  121. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/notfound.mako +0 -0
  122. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/page.mako +0 -0
  123. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  124. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/progress.mako +0 -0
  125. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/setup.mako +0 -0
  126. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/upgrade.mako +0 -0
  127. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
  128. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/upgrades/view.mako +0 -0
  129. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/templates/wutta-components.mako +0 -0
  130. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/__init__.py +0 -0
  131. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/auth.py +0 -0
  132. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/base.py +0 -0
  133. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/common.py +0 -0
  134. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/essential.py +0 -0
  135. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/master.py +0 -0
  136. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/people.py +0 -0
  137. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/progress.py +0 -0
  138. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/roles.py +0 -0
  139. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/settings.py +0 -0
  140. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/upgrades.py +0 -0
  141. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/src/wuttaweb/views/users.py +0 -0
  142. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tasks.py +0 -0
  143. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/__init__.py +0 -0
  144. {wuttaweb-0.13.1/tests/forms → wuttaweb-0.14.0/tests/db}/__init__.py +0 -0
  145. {wuttaweb-0.13.1/tests/grids → wuttaweb-0.14.0/tests/forms}/__init__.py +0 -0
  146. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/forms/test_base.py +0 -0
  147. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/forms/test_schema.py +0 -0
  148. {wuttaweb-0.13.1/tests/views → wuttaweb-0.14.0/tests/grids}/__init__.py +0 -0
  149. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/grids/test_base.py +0 -0
  150. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/grids/test_filters.py +0 -0
  151. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  152. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  153. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_oruga.js +0 -0
  154. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_oruga_bulma.css +0 -0
  155. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_oruga_bulma.js +0 -0
  156. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_vue.js +0 -0
  157. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
  158. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/buefy.css +0 -0
  159. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/buefy.js +0 -0
  160. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/fontawesome.js +0 -0
  161. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/vue.js +0 -0
  162. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/libcache/vue_resource.js +0 -0
  163. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_app.py +0 -0
  164. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_auth.py +0 -0
  165. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_handler.py +0 -0
  166. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_helpers.py +0 -0
  167. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_menus.py +0 -0
  168. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_progress.py +0 -0
  169. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_static.py +0 -0
  170. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/test_subscribers.py +0 -0
  171. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/util.py +0 -0
  172. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test___init__.py +0 -0
  173. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_auth.py +0 -0
  174. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_base.py +0 -0
  175. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_common.py +0 -0
  176. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_master.py +0 -0
  177. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_people.py +0 -0
  178. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_progress.py +0 -0
  179. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_roles.py +0 -0
  180. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_settings.py +0 -0
  181. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_upgrades.py +0 -0
  182. {wuttaweb-0.13.1 → wuttaweb-0.14.0}/tests/views/test_users.py +0 -0
@@ -5,6 +5,12 @@ 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.14.0 (2024-08-27)
9
+
10
+ ### Feat
11
+
12
+ - add basic support for wutta-continuum
13
+
8
14
  ## v0.13.1 (2024-08-26)
9
15
 
10
16
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: WuttaWeb
3
- Version: 0.13.1
3
+ Version: 0.14.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
@@ -36,8 +36,10 @@ Requires-Dist: pyramid-tm
36
36
  Requires-Dist: pyramid>=2
37
37
  Requires-Dist: waitress
38
38
  Requires-Dist: webhelpers2
39
- Requires-Dist: wuttjamaican[db,email]>=0.13.0
39
+ Requires-Dist: wuttjamaican[db,email]>=0.13.2
40
40
  Requires-Dist: zope-sqlalchemy>=1.5
41
+ Provides-Extra: continuum
42
+ Requires-Dist: wutta-continuum; extra == 'continuum'
41
43
  Provides-Extra: docs
42
44
  Requires-Dist: furo; extra == 'docs'
43
45
  Requires-Dist: sphinx; extra == 'docs'
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.conf``
3
+ =================
4
+
5
+ .. automodule:: wuttaweb.conf
6
+ :members:
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.db.continuum``
3
+ =========================
4
+
5
+ .. automodule:: wuttaweb.db.continuum
6
+ :members:
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.db.sess``
3
+ ====================
4
+
5
+ .. automodule:: wuttaweb.db.sess
6
+ :members:
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb``
3
+ ============
4
+
5
+ .. automodule:: wuttaweb
6
+ :members:
@@ -34,6 +34,7 @@ intersphinx_mapping = {
34
34
  'rattail-manual': ('https://rattailproject.org/docs/rattail-manual/', None),
35
35
  'webhelpers2': ('https://webhelpers2.readthedocs.io/en/latest/', None),
36
36
  'wuttjamaican': ('https://rattailproject.org/docs/wuttjamaican/', None),
37
+ 'wutta-continuum': ('https://rattailproject.org/docs/wutta-continuum/', None),
37
38
  }
38
39
 
39
40
 
@@ -0,0 +1,68 @@
1
+
2
+ WuttaWeb
3
+ ========
4
+
5
+ This package provides a "web layer" for custom apps.
6
+
7
+ It uses traditional server-side rendering with VueJS on the front-end.
8
+
9
+ Good documentation and 100% `test coverage`_ are priorities for this
10
+ project.
11
+
12
+ .. _test coverage: https://buildbot.rattailproject.org/coverage/wuttaweb/
13
+
14
+ However as you can see..the API should be fairly well documented but
15
+ the narrative docs are pretty scant. That will eventually change.
16
+
17
+ .. toctree::
18
+ :maxdepth: 2
19
+ :caption: Documentation:
20
+
21
+ glossary
22
+ narr/templates/index
23
+
24
+ .. toctree::
25
+ :maxdepth: 1
26
+ :caption: Package API:
27
+
28
+ api/wuttaweb
29
+ api/wuttaweb.app
30
+ api/wuttaweb.auth
31
+ api/wuttaweb.conf
32
+ api/wuttaweb.db
33
+ api/wuttaweb.db.continuum
34
+ api/wuttaweb.db.sess
35
+ api/wuttaweb.forms
36
+ api/wuttaweb.forms.base
37
+ api/wuttaweb.forms.schema
38
+ api/wuttaweb.forms.widgets
39
+ api/wuttaweb.grids
40
+ api/wuttaweb.grids.base
41
+ api/wuttaweb.grids.filters
42
+ api/wuttaweb.handler
43
+ api/wuttaweb.helpers
44
+ api/wuttaweb.menus
45
+ api/wuttaweb.progress
46
+ api/wuttaweb.static
47
+ api/wuttaweb.subscribers
48
+ api/wuttaweb.util
49
+ api/wuttaweb.views
50
+ api/wuttaweb.views.auth
51
+ api/wuttaweb.views.base
52
+ api/wuttaweb.views.common
53
+ api/wuttaweb.views.essential
54
+ api/wuttaweb.views.master
55
+ api/wuttaweb.views.people
56
+ api/wuttaweb.views.progress
57
+ api/wuttaweb.views.roles
58
+ api/wuttaweb.views.settings
59
+ api/wuttaweb.views.upgrades
60
+ api/wuttaweb.views.users
61
+
62
+
63
+ Indices and tables
64
+ ==================
65
+
66
+ * :ref:`genindex`
67
+ * :ref:`modindex`
68
+ * :ref:`search`
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "WuttaWeb"
9
- version = "0.13.1"
9
+ version = "0.14.0"
10
10
  description = "Web App for Wutta Framework"
11
11
  readme = "README.md"
12
12
  authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
@@ -42,12 +42,13 @@ dependencies = [
42
42
  "pyramid_tm",
43
43
  "waitress",
44
44
  "WebHelpers2",
45
- "WuttJamaican[db,email]>=0.13.0",
45
+ "WuttJamaican[db,email]>=0.13.2",
46
46
  "zope.sqlalchemy>=1.5",
47
47
  ]
48
48
 
49
49
 
50
50
  [project.optional-dependencies]
51
+ continuum = ["Wutta-Continuum"]
51
52
  docs = ["Sphinx", "furo"]
52
53
  tests = ["pytest-cov", "tox"]
53
54
 
@@ -60,6 +61,10 @@ main = "wuttaweb.app:main"
60
61
  wuttaweb = "wuttaweb.app:WebAppProvider"
61
62
 
62
63
 
64
+ [project.entry-points."wutta.config.extensions"]
65
+ wuttaweb = "wuttaweb.conf:WuttaWebConfigExtension"
66
+
67
+
63
68
  [project.urls]
64
69
  Homepage = "https://wuttaproject.org/"
65
70
  Repository = "https://forgejo.wuttaproject.org/wutta/wuttaweb"
@@ -98,7 +98,8 @@ class WuttaSecurityPolicy:
98
98
  for current user
99
99
 
100
100
  :param db_session: Optional :term:`db session` to use, instead of
101
- :class:`wuttaweb.db.Session`. Probably only useful for tests.
101
+ :class:`wuttaweb.db.sess.Session`. Probably only useful for
102
+ tests.
102
103
  """
103
104
 
104
105
  def __init__(self, db_session=None):
@@ -0,0 +1,43 @@
1
+ # -*- coding: utf-8; -*-
2
+ ################################################################################
3
+ #
4
+ # wuttaweb -- Web App for Wutta Framework
5
+ # Copyright © 2024 Lance Edgar
6
+ #
7
+ # This file is part of Wutta Framework.
8
+ #
9
+ # Wutta Framework is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by the Free
11
+ # Software Foundation, either version 3 of the License, or (at your option) any
12
+ # later version.
13
+ #
14
+ # Wutta Framework is distributed in the hope that it will be useful, but
15
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
+ # more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+ ################################################################################
23
+ """
24
+ Config Extension
25
+ """
26
+
27
+ from wuttjamaican.conf import WuttaConfigExtension
28
+
29
+
30
+ class WuttaWebConfigExtension(WuttaConfigExtension):
31
+ """
32
+ Config extension for WuttaWeb.
33
+
34
+ This sets the default plugin for SQLAlchemy-Continuum. Which is
35
+ only relevant if Wutta-Continuum is installed and enabled. For
36
+ more info see :doc:`wutta-continuum:index`.
37
+ """
38
+ key = 'wuttaweb'
39
+
40
+ def configure(self, config):
41
+ """ """
42
+ config.setdefault('wutta_continuum.wutta_plugin_spec',
43
+ 'wuttaweb.db.continuum:WuttaWebContinuumPlugin')
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8; -*-
2
+ ################################################################################
3
+ #
4
+ # wuttaweb -- Web App for Wutta Framework
5
+ # Copyright © 2024 Lance Edgar
6
+ #
7
+ # This file is part of Wutta Framework.
8
+ #
9
+ # Wutta Framework is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by the Free
11
+ # Software Foundation, either version 3 of the License, or (at your option) any
12
+ # later version.
13
+ #
14
+ # Wutta Framework is distributed in the hope that it will be useful, but
15
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
+ # more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+ ################################################################################
23
+ """
24
+ Database Utilities
25
+
26
+ The following are available from this ``wuttaweb.db`` namespace:
27
+
28
+ * :class:`~wuttaweb.db.sess.Session`
29
+ """
30
+
31
+ from .sess import Session
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8; -*-
2
+ ################################################################################
3
+ #
4
+ # wuttaweb -- Web App for Wutta Framework
5
+ # Copyright © 2024 Lance Edgar
6
+ #
7
+ # This file is part of Wutta Framework.
8
+ #
9
+ # Wutta Framework is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by the Free
11
+ # Software Foundation, either version 3 of the License, or (at your option) any
12
+ # later version.
13
+ #
14
+ # Wutta Framework is distributed in the hope that it will be useful, but
15
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
+ # more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21
+ #
22
+ ################################################################################
23
+ """
24
+ SQLAlchemy-Continuum Plugin
25
+ """
26
+
27
+ from pyramid.threadlocal import get_current_request
28
+
29
+ try:
30
+ from wutta_continuum.conf import WuttaContinuumPlugin
31
+ except ImportError: # pragma: no cover
32
+ pass
33
+ else:
34
+
35
+ class WuttaWebContinuumPlugin(WuttaContinuumPlugin):
36
+ """
37
+ SQLAlchemy-Continuum manager plugin for WuttaWeb.
38
+
39
+ This tries to use the current request to obtain user and IP
40
+ address for the transaction.
41
+ """
42
+
43
+ # TODO: should find a better way, threadlocals are bad?
44
+ # https://docs.pylonsproject.org/projects/pyramid/en/latest/api/threadlocal.html#pyramid.threadlocal.get_current_request
45
+
46
+ def get_remote_addr(self, uow, session):
47
+ """ """
48
+ request = get_current_request()
49
+ if request:
50
+ return request.client_addr
51
+
52
+ def get_user_id(self, uow, session):
53
+ """ """
54
+ request = get_current_request()
55
+ if request and request.user:
56
+ return request.user.uuid
@@ -128,7 +128,7 @@ class WuttaSet(colander.Set):
128
128
  :param request: Current :term:`request` object.
129
129
 
130
130
  :param session: Optional :term:`db session` to use instead of
131
- :class:`wuttaweb.db.Session`.
131
+ :class:`wuttaweb.db.sess.Session`.
132
132
  """
133
133
 
134
134
  def __init__(self, request, session=None):
@@ -99,8 +99,11 @@ class ObjectRefWidget(SelectWidget):
99
99
  """ """
100
100
  values = super().get_template_values(field, cstruct, kw)
101
101
 
102
- if 'url' not in values and self.url and field.schema.model_instance:
103
- values['url'] = self.url(field.schema.model_instance)
102
+ # add url, only if rendering readonly
103
+ readonly = kw.get('readonly', self.readonly)
104
+ if readonly:
105
+ if 'url' not in values and self.url and field.schema.model_instance:
106
+ values['url'] = self.url(field.schema.model_instance)
104
107
 
105
108
  return values
106
109
 
@@ -134,7 +137,7 @@ class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget):
134
137
  :param request: Current :term:`request` object.
135
138
 
136
139
  :param session: Optional :term:`db session` to use instead of
137
- :class:`wuttaweb.db.Session`.
140
+ :class:`wuttaweb.db.sess.Session`.
138
141
 
139
142
  It uses these Deform templates:
140
143
 
@@ -147,7 +147,7 @@ def new_request_set_user(
147
147
  from database, instead of :func:`default_user_getter()`.
148
148
 
149
149
  :param db_session: Optional :term:`db session` to use,
150
- instead of :class:`wuttaweb.db.Session`.
150
+ instead of :class:`wuttaweb.db.sess.Session`.
151
151
 
152
152
  This will add to the request object:
153
153
 
@@ -491,10 +491,16 @@ def get_model_fields(config, model_class=None):
491
491
  try:
492
492
  mapper = sa.inspect(model_class)
493
493
  except sa.exc.NoInspectionAvailable:
494
- pass
495
- else:
496
- fields = [prop.key for prop in mapper.iterate_properties]
497
- return fields
494
+ return
495
+
496
+ fields = [prop.key for prop in mapper.iterate_properties]
497
+
498
+ # nb. we never want the continuum 'versions' prop
499
+ app = config.get_app()
500
+ if app.continuum_is_enabled() and 'versions' in fields:
501
+ fields.remove('versions')
502
+
503
+ return fields
498
504
 
499
505
 
500
506
  def make_json_safe(value, key=None, warn=True):
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8; -*-
2
+
3
+ from unittest.mock import patch, MagicMock
4
+
5
+ import pytest
6
+
7
+ from tests.util import WebTestCase
8
+
9
+ from wuttaweb.db import continuum as mod
10
+
11
+
12
+ class TestWuttaWebContinuumPlugin(WebTestCase):
13
+
14
+ def setUp(self):
15
+ if not hasattr(mod, 'WuttaWebContinuumPlugin'):
16
+ pytest.skip("test not relevant without sqlalchemy-continuum")
17
+ self.setup_web()
18
+
19
+ def make_plugin(self):
20
+ return mod.WuttaWebContinuumPlugin()
21
+
22
+ def test_get_remote_addr(self):
23
+ plugin = self.make_plugin()
24
+
25
+ with patch.object(mod, 'get_current_request', return_value=None):
26
+ self.assertIsNone(plugin.get_remote_addr(None, self.session))
27
+
28
+ self.request.client_addr = '127.0.0.1'
29
+ self.assertEqual(plugin.get_remote_addr(None, self.session), '127.0.0.1')
30
+
31
+ def test_get_user_id(self):
32
+ plugin = self.make_plugin()
33
+
34
+ with patch.object(mod, 'get_current_request', return_value=None):
35
+ self.assertIsNone(plugin.get_user_id(None, self.session))
36
+
37
+ self.request.user = MagicMock(uuid='some-random-uuid')
38
+ self.assertEqual(plugin.get_user_id(None, self.session), 'some-random-uuid')
@@ -19,6 +19,9 @@ class TestObjectRefWidget(WebTestCase):
19
19
  kwargs.setdefault('renderer', deform.Form.default_renderer)
20
20
  return deform.Field(node, **kwargs)
21
21
 
22
+ def make_widget(self, **kwargs):
23
+ return mod.ObjectRefWidget(self.request, **kwargs)
24
+
22
25
  def test_serialize(self):
23
26
  model = self.app.model
24
27
  person = model.Person(full_name="Betty Boop")
@@ -27,7 +30,7 @@ class TestObjectRefWidget(WebTestCase):
27
30
 
28
31
  # standard (editable)
29
32
  node = colander.SchemaNode(PersonRef(self.request, session=self.session))
30
- widget = mod.ObjectRefWidget(self.request)
33
+ widget = self.make_widget()
31
34
  field = self.make_field(node)
32
35
  html = widget.serialize(field, person.uuid)
33
36
  self.assertIn('<b-select ', html)
@@ -35,7 +38,7 @@ class TestObjectRefWidget(WebTestCase):
35
38
  # readonly
36
39
  node = colander.SchemaNode(PersonRef(self.request, session=self.session))
37
40
  node.model_instance = person
38
- widget = mod.ObjectRefWidget(self.request)
41
+ widget = self.make_widget()
39
42
  field = self.make_field(node)
40
43
  html = widget.serialize(field, person.uuid, readonly=True)
41
44
  self.assertIn('Betty Boop', html)
@@ -44,13 +47,26 @@ class TestObjectRefWidget(WebTestCase):
44
47
  # with hyperlink
45
48
  node = colander.SchemaNode(PersonRef(self.request, session=self.session))
46
49
  node.model_instance = person
47
- widget = mod.ObjectRefWidget(self.request, url=lambda p: '/foo')
50
+ widget = self.make_widget(url=lambda p: '/foo')
48
51
  field = self.make_field(node)
49
52
  html = widget.serialize(field, person.uuid, readonly=True)
50
53
  self.assertIn('Betty Boop', html)
51
54
  self.assertIn('<a', html)
52
55
  self.assertIn('href="/foo"', html)
53
56
 
57
+ def test_get_template_values(self):
58
+ model = self.app.model
59
+ person = model.Person(full_name="Betty Boop")
60
+ self.session.add(person)
61
+ self.session.commit()
62
+
63
+ node = colander.SchemaNode(PersonRef(self.request, session=self.session))
64
+ widget = self.make_widget()
65
+ field = self.make_field(node)
66
+ values = widget.get_template_values(field, person.uuid, {})
67
+ self.assertIn('cstruct', values)
68
+ self.assertNotIn('url', values)
69
+
54
70
 
55
71
  class TestFileDownloadWidget(WebTestCase):
56
72
 
@@ -480,6 +480,27 @@ class TestGetModelFields(TestCase):
480
480
  fields = mod.get_model_fields(self.config, model.Setting)
481
481
  self.assertEqual(fields, ['name', 'value'])
482
482
 
483
+ def test_avoid_versions(self):
484
+ model = self.app.model
485
+
486
+ mapper = MagicMock(iterate_properties = [
487
+ MagicMock(key='uuid'),
488
+ MagicMock(key='full_name'),
489
+ MagicMock(key='first_name'),
490
+ MagicMock(key='middle_name'),
491
+ MagicMock(key='last_name'),
492
+ MagicMock(key='versions'),
493
+ ])
494
+
495
+ with patch.object(mod, 'sa') as sa:
496
+ sa.inspect.return_value = mapper
497
+
498
+ with patch.object(self.app, 'continuum_is_enabled', return_value=True):
499
+ fields = mod.get_model_fields(self.config, model.Person)
500
+ # nb. no versions field
501
+ self.assertEqual(set(fields), set(['uuid', 'full_name', 'first_name',
502
+ 'middle_name', 'last_name']))
503
+
483
504
 
484
505
  class TestGetCsrfToken(TestCase):
485
506
 
File without changes
@@ -1,11 +1,14 @@
1
1
 
2
2
  [tox]
3
- envlist = py38, py39, py310, py311
3
+ envlist = py38, py39, py310, py311, nox
4
4
 
5
5
  [testenv]
6
- extras = tests
6
+ extras = continuum,tests
7
7
  commands = pytest {posargs}
8
8
 
9
+ [testenv:nox]
10
+ extras = tests
11
+
9
12
  [testenv:coverage]
10
13
  basepython = python3.11
11
14
  commands = pytest --cov=wuttaweb --cov-report=html --cov-fail-under=100
@@ -1,10 +0,0 @@
1
-
2
- Package API
3
- ===========
4
-
5
- This is the "raw" API documentation for the ``wuttaweb`` package.
6
-
7
- .. toctree::
8
- :maxdepth: 2
9
-
10
- wuttaweb/index
@@ -1,38 +0,0 @@
1
-
2
- ``wuttaweb``
3
- ============
4
-
5
- .. automodule:: wuttaweb
6
-
7
- .. toctree::
8
- :maxdepth: 1
9
-
10
- app
11
- auth
12
- db
13
- forms
14
- forms.base
15
- forms.schema
16
- forms.widgets
17
- grids
18
- grids.base
19
- grids.filters
20
- handler
21
- helpers
22
- menus
23
- progress
24
- static
25
- subscribers
26
- util
27
- views
28
- views.auth
29
- views.base
30
- views.common
31
- views.essential
32
- views.master
33
- views.people
34
- views.progress
35
- views.roles
36
- views.settings
37
- views.upgrades
38
- views.users
@@ -1,28 +0,0 @@
1
-
2
- WuttaWeb
3
- ========
4
-
5
- This package provides a "web layer" for custom apps.
6
-
7
- It uses traditional server-side rendering with VueJS on the front-end.
8
-
9
- Good documentation and 100% `test coverage`_ are priorities for this
10
- project.
11
-
12
- .. _test coverage: https://buildbot.rattailproject.org/coverage/wuttaweb/
13
-
14
- .. toctree::
15
- :maxdepth: 3
16
- :caption: Contents:
17
-
18
- glossary
19
- narr/index
20
- api/index
21
-
22
-
23
- Indices and tables
24
- ==================
25
-
26
- * :ref:`genindex`
27
- * :ref:`modindex`
28
- * :ref:`search`
@@ -1,8 +0,0 @@
1
-
2
- Documentation
3
- =============
4
-
5
- .. toctree::
6
- :maxdepth: 2
7
-
8
- templates/index
File without changes
File without changes
File without changes
File without changes