cherrypy-foundation 1.0.0__tar.gz → 1.0.0a1__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 (172) hide show
  1. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/.gitlab-ci.yml +0 -54
  2. cherrypy_foundation-1.0.0a1/PKG-INFO +42 -0
  3. cherrypy_foundation-1.0.0a1/README.md +10 -0
  4. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/pyproject.toml +4 -9
  5. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/sonar-project.properties +1 -1
  6. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/ColorModes.jinja +4 -5
  7. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Datatable.jinja +2 -2
  8. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Datatable.js +2 -2
  9. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Field.jinja +6 -16
  10. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Fields.jinja +2 -0
  11. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Typeahead.css +1 -6
  12. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Typeahead.jinja +2 -2
  13. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/__init__.py +2 -2
  14. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/tests/test_static.py +1 -1
  15. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/error_page.py +17 -20
  16. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/flash.py +15 -17
  17. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/form.py +2 -2
  18. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/logging.py +2 -2
  19. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/passwd.py +2 -2
  20. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/db.py +9 -35
  21. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/ldap.py +38 -46
  22. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/restapi.py +1 -1
  23. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/plugins/scheduler.py +163 -0
  24. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/smtp.py +46 -78
  25. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/tests/test_db.py +4 -4
  26. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/tests/test_ldap.py +3 -76
  27. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/plugins/tests/test_scheduler.py +92 -0
  28. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/tests/test_smtp.py +7 -40
  29. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tests/test_error_page.py +1 -7
  30. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tests/test_passwd.py +2 -2
  31. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/auth.py +38 -59
  32. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/auth_mfa.py +88 -89
  33. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools/errors.py +27 -0
  34. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools/i18n.py +436 -0
  35. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/jinja2.py +13 -29
  36. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/ratelimit.py +27 -37
  37. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/secure_headers.py +5 -1
  38. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/sessions_timeout.py +21 -23
  39. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools/tests/locales/en/LC_MESSAGES/messages.mo +0 -0
  40. {cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/locales/de → cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools/tests/locales/en}/LC_MESSAGES/messages.po +2 -2
  41. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/test_auth.py +4 -21
  42. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/test_i18n.py +6 -81
  43. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/test_ratelimit.py +2 -2
  44. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/url.py +25 -25
  45. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/widgets.py +2 -2
  46. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation.egg-info/PKG-INFO +42 -0
  47. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation.egg-info/SOURCES.txt +4 -41
  48. cherrypy_foundation-1.0.0a1/src/cherrypy_foundation.egg-info/requires.txt +14 -0
  49. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/tox.ini +3 -10
  50. cherrypy_foundation-1.0.0/MANIFEST.in +0 -1
  51. cherrypy_foundation-1.0.0/PKG-INFO +0 -71
  52. cherrypy_foundation-1.0.0/README.md +0 -30
  53. cherrypy_foundation-1.0.0/debian/TODO +0 -3
  54. cherrypy_foundation-1.0.0/debian/changelog +0 -5
  55. cherrypy_foundation-1.0.0/debian/control +0 -63
  56. cherrypy_foundation-1.0.0/debian/copyright +0 -27
  57. cherrypy_foundation-1.0.0/debian/rules +0 -29
  58. cherrypy_foundation-1.0.0/debian/source/format +0 -1
  59. cherrypy_foundation-1.0.0/debian/upstream/metadata +0 -5
  60. cherrypy_foundation-1.0.0/doc/_templates/version.html +0 -2
  61. cherrypy_foundation-1.0.0/doc/conf.py +0 -69
  62. cherrypy_foundation-1.0.0/doc/error_page.md +0 -163
  63. cherrypy_foundation-1.0.0/doc/flash.md +0 -200
  64. cherrypy_foundation-1.0.0/doc/form.md +0 -286
  65. cherrypy_foundation-1.0.0/doc/index.rst +0 -8
  66. cherrypy_foundation-1.0.0/doc/introduction.md +0 -23
  67. cherrypy_foundation-1.0.0/doc/modules.rst +0 -10
  68. cherrypy_foundation-1.0.0/doc/url.md +0 -230
  69. cherrypy_foundation-1.0.0/src/cherrypy_foundation/components/Flash.jinja +0 -13
  70. cherrypy_foundation-1.0.0/src/cherrypy_foundation/components/LocaleSelection.jinja +0 -13
  71. cherrypy_foundation-1.0.0/src/cherrypy_foundation/components/LocaleSelection.js +0 -26
  72. cherrypy_foundation-1.0.0/src/cherrypy_foundation/plugins/scheduler.py +0 -287
  73. cherrypy_foundation-1.0.0/src/cherrypy_foundation/plugins/tests/test_scheduler.py +0 -100
  74. cherrypy_foundation-1.0.0/src/cherrypy_foundation/plugins/tests/test_scheduler_db.py +0 -107
  75. cherrypy_foundation-1.0.0/src/cherrypy_foundation/sessions.py +0 -93
  76. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/__init__.py +0 -72
  77. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/templates/test_flash.html +0 -9
  78. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/templates/test_form.html +0 -16
  79. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/templates/test_url.html +0 -15
  80. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/test_flash.py +0 -61
  81. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/test_form.py +0 -148
  82. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/test_logging.py +0 -78
  83. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/test_sessions.py +0 -89
  84. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tests/test_url.py +0 -161
  85. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/i18n.py +0 -529
  86. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/components/Button.jinja +0 -2
  87. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/locales/de/LC_MESSAGES/messages.mo +0 -0
  88. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/templates/test_jinja2.html +0 -11
  89. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/templates/test_jinjax.html +0 -9
  90. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/templates/test_jinjax_i18n.html +0 -22
  91. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/test_auth_mfa.py +0 -369
  92. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/test_jinja2.py +0 -153
  93. cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests/test_secure_headers.py +0 -200
  94. cherrypy_foundation-1.0.0/src/cherrypy_foundation.egg-info/PKG-INFO +0 -71
  95. cherrypy_foundation-1.0.0/src/cherrypy_foundation.egg-info/requires.txt +0 -28
  96. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/.gitignore +0 -0
  97. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/LICENSE.md +0 -0
  98. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/setup.cfg +0 -0
  99. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/__init__.py +0 -0
  100. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Datatable.css +0 -0
  101. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Field.css +0 -0
  102. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Field.js +0 -0
  103. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Icon.jinja +0 -0
  104. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/SideBySideMultiSelect.css +0 -0
  105. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/SideBySideMultiSelect.jinja +0 -0
  106. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/SideBySideMultiSelect.js +0 -0
  107. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/Typeahead.js +0 -0
  108. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/tests/__init__.py +0 -0
  109. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap-icons/bootstrap-icons.css +0 -0
  110. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap-icons/bootstrap-icons.min.css +0 -0
  111. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
  112. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
  113. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.css +0 -0
  114. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.css.map +0 -0
  115. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.min.css +0 -0
  116. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.min.css.map +0 -0
  117. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.js +0 -0
  118. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.js.map +0 -0
  119. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.min.js +0 -0
  120. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.min.js.map +0 -0
  121. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/bootstrap5/js/color-modes.js +0 -0
  122. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/css/dataTables.dataTables.css +0 -0
  123. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/css/dataTables.dataTables.min.css +0 -0
  124. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/images/sort_asc.png +0 -0
  125. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/images/sort_asc_disabled.png +0 -0
  126. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/images/sort_both.png +0 -0
  127. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/images/sort_desc.png +0 -0
  128. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/images/sort_desc_disabled.png +0 -0
  129. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/js/dataTables.js +0 -0
  130. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables/js/dataTables.min.js +0 -0
  131. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/css/buttons.dataTables.css +0 -0
  132. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/css/buttons.dataTables.min.css +0 -0
  133. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/buttons.html5.js +0 -0
  134. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/buttons.html5.min.js +0 -0
  135. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/dataTables.buttons.js +0 -0
  136. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/dataTables.buttons.min.js +0 -0
  137. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/css/fixedHeader.dataTables.css +0 -0
  138. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/css/fixedHeader.dataTables.min.css +0 -0
  139. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/js/dataTables.fixedHeader.js +0 -0
  140. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/js/dataTables.fixedHeader.min.js +0 -0
  141. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/JSZip/jszip.js +0 -0
  142. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/JSZip/jszip.min.js +0 -0
  143. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Responsive/css/responsive.dataTables.css +0 -0
  144. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Responsive/css/responsive.dataTables.min.css +0 -0
  145. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Responsive/js/dataTables.responsive.js +0 -0
  146. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/Responsive/js/dataTables.responsive.min.js +0 -0
  147. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/pdfmake.js +0 -0
  148. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/pdfmake.min.js +0 -0
  149. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/vfs_fonts.js +0 -0
  150. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/css/rowGroup.dataTables.css +0 -0
  151. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/css/rowGroup.dataTables.min.css +0 -0
  152. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/js/dataTables.rowGroup.js +0 -0
  153. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/js/dataTables.rowGroup.min.js +0 -0
  154. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/jquery/jquery.min.js +0 -0
  155. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/multi/LICENSE +0 -0
  156. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/multi/README.md +0 -0
  157. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/multi/multi.css +0 -0
  158. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/multi/multi.js +0 -0
  159. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/popper/popper.js +0 -0
  160. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/popper/popper.min.js +0 -0
  161. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/typeahead/jquery.typeahead.min.css +0 -0
  162. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/components/vendor/typeahead/jquery.typeahead.min.js +0 -0
  163. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/__init__.py +0 -0
  164. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/plugins/tests/__init__.py +0 -0
  165. {cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools → cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tests}/__init__.py +0 -0
  166. {cherrypy_foundation-1.0.0/src/cherrypy_foundation/tools/tests → cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools}/__init__.py +0 -0
  167. /cherrypy_foundation-1.0.0/debian/python3-cherrypy-foundation.links → /cherrypy_foundation-1.0.0a1/src/cherrypy_foundation/tools/tests/__init__.py +0 -0
  168. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/locales/fr/LC_MESSAGES/messages.mo +0 -0
  169. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/locales/fr/LC_MESSAGES/messages.po +0 -0
  170. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation/tools/tests/locales/messages.pot +0 -0
  171. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation.egg-info/dependency_links.txt +0 -0
  172. {cherrypy_foundation-1.0.0 → cherrypy_foundation-1.0.0a1}/src/cherrypy_foundation.egg-info/top_level.txt +0 -0
@@ -26,9 +26,6 @@ isort:
26
26
  djlint:
27
27
  <<: *tox
28
28
 
29
- doc:
30
- <<: *tox
31
-
32
29
  py3:
33
30
  <<: *tox
34
31
  artifacts:
@@ -61,31 +58,6 @@ package:py3:
61
58
  - dist/*.tar.gz
62
59
  expire_in: 1 day
63
60
 
64
- package:deb:
65
- stage: package
66
- needs: []
67
- image: buildpack-deps:$DIST
68
- parallel:
69
- matrix:
70
- - DIST: trixie
71
- - DIST: trixie
72
- DEB_BUILD_PROFILES: nocheck
73
- script: |
74
- set -x
75
- set -e
76
- apt update
77
- apt -y --no-install-recommends install devscripts lintian
78
- apt build-dep -y .
79
- export DEBEMAIL=$CI_COMMIT_AUTHOR
80
- dch -v "$(python3 -m setuptools_scm)" "automated build"
81
- dpkg-buildpackage -b
82
- lintian
83
- mkdir -p ./dist/$DIST
84
- mv ../*.deb ./dist/$DIST/
85
- artifacts:
86
- paths:
87
- - ./dist/*
88
-
89
61
  publish:sonar:
90
62
  allow_failure: true
91
63
  image: sonarsource/sonar-scanner-cli
@@ -116,29 +88,3 @@ publish:wheel:
116
88
  if [ ! -z "$CI_COMMIT_TAG" ]; then
117
89
  twine upload dist/*.whl dist/*.tar.gz -u $PYPI_USR -p $PYPI_PWD
118
90
  fi
119
-
120
- publish:deb:
121
- needs:
122
- - package:deb
123
- only:
124
- variables:
125
- - $NEXUS_USR
126
- - $NEXUS_PWD
127
- parallel:
128
- matrix:
129
- - DIST: trixie
130
- script: |
131
- set -e
132
- set -x
133
- if [[ "$CI_COMMIT_TAG" == *.+([0-9]) ]]; then
134
- APT_URL="$NEXUS_URL/repository/apt-release-${DIST}/"
135
- APT_COMPONENT=${DIST}
136
- else
137
- APT_URL="$NEXUS_URL/repository/apt-dev-${DIST}/"
138
- APT_COMPONENT=${DIST}-dev
139
- fi
140
- export FILE=$(ls -1 ./dist/$DIST/python3-cherrypy-foundation*.deb)
141
- curl --fail -u "$NEXUS_USR:$NEXUS_PWD" -H "Content-Type: multipart/form-data" --data-binary "@$FILE" "$APT_URL"
142
- sleep 2
143
- curl --fail ${APT_URL}dists/$APT_COMPONENT/main/binary-all/Packages | grep "$(basename $FILE)"
144
- stage: publish
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: cherrypy-foundation
3
+ Version: 1.0.0a1
4
+ Summary: CherryPy Foundation
5
+ Author-email: Patrik Dufresne <patrik@ikus-soft.com>
6
+ License: GPLv3
7
+ Project-URL: Homepage, https://gitlab.com/ikus-soft/cherrypy-foundation
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Framework :: CherryPy
10
+ Classifier: Intended Audience :: System Administrators
11
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: <4,>=3.11
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE.md
18
+ Requires-Dist: babel
19
+ Requires-Dist: CherryPy
20
+ Requires-Dist: Jinja2
21
+ Requires-Dist: jinjax
22
+ Requires-Dist: pytz
23
+ Requires-Dist: WTForms>=3.2.1
24
+ Provides-Extra: test
25
+ Requires-Dist: ldap3; extra == "test"
26
+ Requires-Dist: apscheduler; extra == "test"
27
+ Requires-Dist: sqlalchemy; extra == "test"
28
+ Requires-Dist: parameterized; extra == "test"
29
+ Requires-Dist: pytest; extra == "test"
30
+ Requires-Dist: selenium; extra == "test"
31
+ Dynamic: license-file
32
+
33
+ # Cherrypy-foundation
34
+
35
+ <p align="center">
36
+ <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-GPL--3.0-orange"></a>
37
+ <a href="https://gitlab.com/ikus-soft/cherrypy-foundation/pipelines"><img alt="Build" src="https://gitlab.com/ikus-soft/cherrypy-foundation/badges/master/pipeline.svg"></a>
38
+ <a href="https://sonar.ikus-soft.com/dashboard?id=cherrypy-foundation"><img alt="Quality Gate" src="https://sonar.ikus-soft.com/api/project_badges/measure?project=cherrypy-foundation&metric=alert_status"></a>
39
+ <a href="https://sonar.ikus-soft.com/dashboard?id=cherrypy-foundation"><img alt="Coverage" src="https://sonar.ikus-soft.com/api/project_badges/measure?project=cherrypy-foundation&metric=coverage"></a>
40
+ </p>
41
+
42
+ This project is a collection of common utilities for creating web applications with CherryPy. It provides integrations with SQLAlchemy, Jinja2, WTForms, and Bootstrap.
@@ -0,0 +1,10 @@
1
+ # Cherrypy-foundation
2
+
3
+ <p align="center">
4
+ <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-GPL--3.0-orange"></a>
5
+ <a href="https://gitlab.com/ikus-soft/cherrypy-foundation/pipelines"><img alt="Build" src="https://gitlab.com/ikus-soft/cherrypy-foundation/badges/master/pipeline.svg"></a>
6
+ <a href="https://sonar.ikus-soft.com/dashboard?id=cherrypy-foundation"><img alt="Quality Gate" src="https://sonar.ikus-soft.com/api/project_badges/measure?project=cherrypy-foundation&metric=alert_status"></a>
7
+ <a href="https://sonar.ikus-soft.com/dashboard?id=cherrypy-foundation"><img alt="Coverage" src="https://sonar.ikus-soft.com/api/project_badges/measure?project=cherrypy-foundation&metric=coverage"></a>
8
+ </p>
9
+
10
+ This project is a collection of common utilities for creating web applications with CherryPy. It provides integrations with SQLAlchemy, Jinja2, WTForms, and Bootstrap.
@@ -7,7 +7,7 @@ name = "cherrypy-foundation"
7
7
  authors = [
8
8
  {name = "Patrik Dufresne", email = "patrik@ikus-soft.com"},
9
9
  ]
10
- description = "Cherrypy-foundation"
10
+ description = "CherryPy Foundation"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.11, <4"
13
13
  license = {text = "GPLv3"}
@@ -15,6 +15,7 @@ classifiers = [
15
15
  "Development Status :: 4 - Beta",
16
16
  "Framework :: CherryPy",
17
17
  "Intended Audience :: System Administrators",
18
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
18
19
  "Programming Language :: Python :: 3.11",
19
20
  "Programming Language :: Python :: 3.12",
20
21
  "Programming Language :: Python :: 3.13",
@@ -31,19 +32,13 @@ dynamic = ["version"]
31
32
 
32
33
  [project.optional-dependencies]
33
34
  test = [
34
- "apscheduler",
35
- "argon2-cffi",
36
35
  "ldap3",
36
+ "apscheduler",
37
+ "sqlalchemy",
37
38
  "parameterized",
38
39
  "pytest",
39
- "requests_oauthlib",
40
40
  "selenium",
41
- "sqlalchemy",
42
41
  ]
43
- ldap = ["ldap3"]
44
- oauth = ["requests_oauthlib"]
45
- passwd = ["argon2-cffi"]
46
- scheduler = ["apscheduler"]
47
42
 
48
43
  [project.urls]
49
44
  Homepage = "https://gitlab.com/ikus-soft/cherrypy-foundation"
@@ -1,2 +1,2 @@
1
- sonar.exclusions=**/test_*.py,src/cherrypy_foundation/components/vendor,doc/conf.py
1
+ sonar.exclusions=**/test_*.py,src/cherrypy_foundation/components/vendor
2
2
  sonar.coverage.exclusions=**/*.js
@@ -1,4 +1,3 @@
1
- {# def header="Toggle theme", light_label="Light", dark_label="Dark", auto_label="Auto" #}
2
1
  {#css vendor/bootstrap5/css/bootstrap.min.css #}
3
2
  {#js vendor/popper/popper.min.js, vendor/bootstrap5/js/bootstrap.min.js, vendor/bootstrap5/js/color-modes.js #}
4
3
  <svg class="d-none" xmlns="http://www.w3.org/2000/svg">
@@ -22,7 +21,7 @@
22
21
  </svg>
23
22
  <li>
24
23
  <span id="bd-theme" class="dropdown-item disabled">
25
- <span id="bd-theme-text">{{ header }}</span>
24
+ <span id="bd-theme-text">{% trans %}Toggle theme{% endtrans %}</span>
26
25
  <svg aria-hidden="true"
27
26
  class="theme-icon-active visually-hidden"
28
27
  width="16"
@@ -41,7 +40,7 @@
41
40
  <use href="#sun-fill">
42
41
  </use>
43
42
  </svg>
44
- {{ light_label }}
43
+ {% trans %}Light{% endtrans %}
45
44
  </button>
46
45
  </li>
47
46
  <li>
@@ -53,7 +52,7 @@
53
52
  <use href="#moon-stars-fill">
54
53
  </use>
55
54
  </svg>
56
- {{ dark_label }}
55
+ {% trans %}Dark{% endtrans %}
57
56
  </button>
58
57
  </li>
59
58
  <li>
@@ -65,6 +64,6 @@
65
64
  <use href="#circle-half">
66
65
  </use>
67
66
  </svg>
68
- {{ auto_label }}
67
+ {% trans %}Auto{% endtrans %}
69
68
  </button>
70
69
  </li>
@@ -15,14 +15,14 @@
15
15
  {% set buttons_cfg_default = {
16
16
  "dom": {
17
17
  "button": {
18
- "className": "btn btn-sm ms-1 mb-2 mb-sm-0",
18
+ "className": "btn btn-sm ms-1 mb-1",
19
19
  "active": "active"
20
20
  },
21
21
  "collection": {
22
22
  "tag": "div",
23
23
  "button": {
24
24
  "tag": "a",
25
- "className": "btn btn-sm btn-link mb-2 mb-sm-0 w-100 text-start",
25
+ "className": "btn btn-sm btn-link mb-1 w-100 text-start",
26
26
  "active": "active",
27
27
  "disabled": "disabled"
28
28
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Cherrypy-foundation
3
- * Copyright (C) 2026 IKUS Software
2
+ * CherryPy Foundation
3
+ * Copyright (C) 2025 IKUS Software
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
6
6
  * it under the terms of the GNU General Public License as published by
@@ -1,6 +1,4 @@
1
1
  {# def field, floating=False #}
2
- {#css vendor/bootstrap5/css/bootstrap.min.css #}
3
- {#js vendor/jquery/jquery.min.js, vendor/popper/popper.min.js, vendor/bootstrap5/js/bootstrap.min.js #}
4
2
  {# djlint:off #}
5
3
  {% set bootstrap_class_table = {
6
4
  "CheckboxInput": ("form-check-input", "form-check-label", False, True),
@@ -31,24 +29,16 @@
31
29
  {% set input_class, label_class, floating_supported, label_always_last = bootstrap_class_table.get(field.widget.__class__.__name__) or ('', 'form-label', False, False) %}
32
30
  {% set label_last = (floating and floating_supported) or label_always_last %}
33
31
  {% do attrs.add_class(input_class) %}
32
+ {# Render label an widget #}
34
33
  {# Used for input-group #}
35
34
  {% set prepend = attrs.get('prepend', None) %}
36
35
  {% set append = attrs.get('append', None) %}
37
36
  {% set input_group = prepend or append %}
38
- {# Build container & label specific attributes #}
39
- {% set container_attrs = attrs.__class__({'class': 'mb-2 form-field'}) %}
40
- {% set label_attrs = attrs.__class__({'class': label_class}) %}
41
- {% for key, value in attrs.as_dict.items() %}
42
- {% if key.startswith('container-') or key.startswith('container_') %}
43
- {% do container_attrs.set(**{key[10:]: value|string}) %}
44
- {% endif %}
45
- {% if key.startswith('label-') or key.startswith('label_') %}
46
- {% do label_attrs.set(**{key[6:]: value|string}) %}
47
- {% endif %}
48
- {% endfor %}
49
- <div {{ container_attrs.as_dict | xmlattr }}>
37
+ {% set container_class = attrs.get('container_class', 'col-12') %}
38
+ {% do attrs.__delitem__('container_class') %}
39
+ <div class="mb-2 form-field {{ container_class }}">
50
40
  {% if floating and floating_supported %}<div class="form-floating">{% endif %}
51
- {% if not label_last %}{{ field.label(**label_attrs.as_dict) }}{% endif %}
41
+ {% if not label_last %}{{ field.label(class=label_class) }}{% endif %}
52
42
  {% if input_group %}
53
43
  <div class="input-group">
54
44
  {% if prepend %}<span class="input-group-text">{{ prepend }}</span>{% endif %}
@@ -58,7 +48,7 @@
58
48
  {% if append %}<span class="input-group-text">{{ append }}</span>{% endif %}
59
49
  </div>
60
50
  {% endif %}
61
- {% if label_last %}{{ field.label(**label_attrs.as_dict) }}{% endif %}
51
+ {% if label_last %}{{ field.label(class=label_class) }}{% endif %}
62
52
  {% for error in field.errors %}<div class="invalid-feedback">{{ error }}</div>{% endfor %}
63
53
  {% if field.description %}<div class="form-text small test-secondary">{{ field.description }}</div>{% endif %}
64
54
  {% if floating and floating_supported %}</div>{% endif %}
@@ -1,4 +1,6 @@
1
1
  {# def form, floating=False #}
2
+ {#css vendor/bootstrap5/css/bootstrap.min.css #}
3
+ {#js vendor/jquery/jquery.min.js, vendor/popper/popper.min.js, vendor/bootstrap5/js/bootstrap.min.js #}
2
4
  <div class="row">
3
5
  {% for id, field in form._fields.items() %}<Field field={{ field }} floating={{ floating }} />{% endfor %}
4
6
  </div>
@@ -10,11 +10,6 @@
10
10
  top: 0.5rem;
11
11
  }
12
12
 
13
- /* Fix lense position */
14
- .typeahead__button button {
15
- height: 100%;
16
- }
17
-
18
13
  /* Fix color for DarkMode */
19
14
  .typeahead__container button,
20
15
  .typeahead__container button.disabled,
@@ -52,4 +47,4 @@
52
47
  .typeahead__list .typeahead__item:not([disabled])>a:hover {
53
48
  background-color: var(--bs-tertiary-bg);
54
49
  color: var(--bs-body-color);
55
- }
50
+ }
@@ -1,5 +1,5 @@
1
1
  {#def
2
- accent=False,
2
+ accent=True,
3
3
  async_result=False,
4
4
  autofocus=False,
5
5
  backdrop=False,
@@ -27,7 +27,7 @@ href=None,
27
27
  loading_animation=True,
28
28
  matcher=None,
29
29
  max_item=8,
30
- max_item_per_group=None,
30
+ max_item_per_group=10,
31
31
  max_length=None,
32
32
  min_length=2,
33
33
  multiselect=None,
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2026 IKUS Software
1
+ # udb, A web interface to manage IT network
2
+ # Copyright (C) 2025 IKUS Software inc.
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -1,5 +1,5 @@
1
1
  # CherryPy
2
- # Copyright (C) 2026 IKUS Software
2
+ # Copyright (C) 2025 IKUS Software
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2020-2026 IKUS Software
1
+ # CherryPy Foundation
2
+ # Copyright (C) 2020-2025 IKUS Software
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -19,6 +19,9 @@ import logging
19
19
 
20
20
  import cherrypy
21
21
 
22
+ # Define the logger
23
+ logger = logging.getLogger(__name__)
24
+
22
25
  HTML_ERROR_TEMPLATE = '''<!DOCTYPE html>
23
26
  <html>
24
27
  <head>
@@ -50,45 +53,39 @@ HTML_ERROR_TEMPLATE = '''<!DOCTYPE html>
50
53
  '''
51
54
 
52
55
 
53
- def error_page(status='', message='', traceback='', version=''):
56
+ def error_page(**kwargs):
54
57
  """
55
58
  Error page handler to handle Plain Text (text/plain), Json (application/json) or HTML (text/html) output.
56
59
 
57
60
  If available, uses Jina2 environment to generate error page using `error_page.html`.
58
61
  """
59
62
  # Log server error exception
60
- if status.startswith('500'):
61
- cherrypy.log(
62
- f'error page status={status} message={message}\n{traceback}', context='ERROR-PAGE', severity=logging.WARNING
63
+ if kwargs.get('status', '').startswith('500'):
64
+ logger.error(
65
+ 'error page: %s %s\n%s' % (kwargs.get('status', ''), kwargs.get('message', ''), kwargs.get('traceback', ''))
63
66
  )
64
67
 
65
68
  # Replace message by generic one for 404. Default implementation leak path info.
66
- if status == '404 Not Found' and cherrypy.serving.request.path_info in message:
67
- message = 'Nothing matches the given URI'
69
+ if kwargs.get('status', '') == '404 Not Found':
70
+ kwargs['message'] = 'Nothing matches the given URI'
68
71
 
69
72
  # Check expected response type.
70
73
  mtype = cherrypy.serving.response.headers.get('Content-Type') or cherrypy.tools.accept.callable(
71
74
  ['text/html', 'text/plain', 'application/json']
72
75
  )
73
76
  if mtype == 'text/plain':
74
- return message
77
+ return kwargs.get('message')
75
78
  elif mtype == 'application/json':
76
- return json.dumps({'message': message, 'status': status})
79
+ return json.dumps({'message': kwargs.get('message', ''), 'status': kwargs.get('status', '')})
77
80
  elif mtype == 'text/html':
78
- context = {'status': status, 'message': message, 'traceback': traceback, 'version': version}
79
81
  if hasattr(cherrypy.tools, 'jinja2'):
80
82
  # Try to build a nice error page with Jinja2 env
81
83
  try:
82
- return cherrypy.tools.jinja2.render_request(template='error_page.html', context=context)
84
+ return cherrypy.tools.jinja2.render_request(template='error_page.html', vars=kwargs)
83
85
  except Exception:
84
- cherrypy.log(
85
- 'fail to render error page with jinja2',
86
- context='ERROR-PAGE',
87
- severity=logging.ERROR,
88
- traceback=True,
89
- )
86
+ logger.exception('fail to render error page')
90
87
  # Fallback to built-int HTML error page
91
- return HTML_ERROR_TEMPLATE % context
88
+ return HTML_ERROR_TEMPLATE % kwargs
92
89
 
93
90
  # Fallback to raw error message.
94
- return message
91
+ return kwargs.get('message')
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2020-2026 IKUS Software
1
+ # CherryPy Foundation
2
+ # Copyright (C) 2020-2025 IKUS Software
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
16
16
 
17
17
  from collections import namedtuple
18
18
 
19
- from cherrypy_foundation.sessions import session_lock
19
+ import cherrypy
20
20
 
21
21
  FlashMessage = namedtuple('FlashMessage', ['message', 'level'])
22
22
 
@@ -27,24 +27,22 @@ def flash(message, level='info'):
27
27
  """
28
28
  assert message
29
29
  assert level in ['info', 'error', 'warning', 'success']
30
- with session_lock() as session:
31
- if 'flash' not in session:
32
- session['flash'] = []
33
- # Support Markup and string
34
- if hasattr(message, '__html__'):
35
- flash_message = FlashMessage(message, level)
36
- else:
37
- flash_message = FlashMessage(str(message), level)
38
- session['flash'].append(flash_message)
30
+ if 'flash' not in cherrypy.session:
31
+ cherrypy.session['flash'] = []
32
+ # Support Markup and string
33
+ if hasattr(message, '__html__'):
34
+ flash_message = FlashMessage(message, level)
35
+ else:
36
+ flash_message = FlashMessage(str(message), level)
37
+ cherrypy.session['flash'].append(flash_message)
39
38
 
40
39
 
41
40
  def get_flashed_messages():
42
41
  """
43
42
  Return all flash message.
44
43
  """
45
- with session_lock() as session:
46
- if 'flash' in session:
47
- messages = session['flash']
48
- del session['flash']
49
- return messages
44
+ if 'flash' in cherrypy.session:
45
+ messages = cherrypy.session['flash']
46
+ del cherrypy.session['flash']
47
+ return messages
50
48
  return []
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2020-2026 IKUS Software
1
+ # CherryPy Foundation
2
+ # Copyright (C) 2020-2025 IKUS Software
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2026 IKUS Software
1
+ # CherryPy Foundation
2
+ # Copyright (C) 2025 IKUS Software inc.
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -1,5 +1,5 @@
1
- # Cherrypy-foundation
2
- # Copyright (C) 2026 IKUS Software
1
+ # CherryPy Foundation
2
+ # Copyright (C) 2025 IKUS Software inc.
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -1,5 +1,5 @@
1
1
  # SQLAlchemy plugins for cherrypy
2
- # Copyright (C) 2022-2026 IKUS Software
2
+ # Copyright (C) 2022-2025 IKUS Software
3
3
  #
4
4
  # This program is free software: you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -23,6 +23,8 @@ from sqlalchemy.engine import Engine
23
23
  from sqlalchemy.exc import IntegrityError, SQLAlchemyError
24
24
  from sqlalchemy.orm import declarative_base, scoped_session, sessionmaker
25
25
 
26
+ logger = logging.getLogger(__name__)
27
+
26
28
 
27
29
  @event.listens_for(Engine, 'connect')
28
30
  def _set_sqlite_journal_mode_wal(connection, connection_record):
@@ -166,10 +168,6 @@ class SQLA(SimplePlugin):
166
168
  _session = None
167
169
  _engine = None
168
170
 
169
- @property
170
- def engine(self):
171
- return self._engine
172
-
173
171
  def start(self):
174
172
  if self.uri is None:
175
173
  return
@@ -182,22 +180,14 @@ class SQLA(SimplePlugin):
182
180
  self.clear_sessions()
183
181
  # Associate our session to our engine
184
182
  self.get_session().configure(bind=self._engine)
185
- self.bus.log("database session plugin started")
186
-
187
- # This is slightly lower priority to get database started first.
188
- start.priority = 45
183
+ self.bus.log("Database session plugin started.")
189
184
 
190
185
  def stop(self):
191
186
  if self._session:
192
187
  self.clear_sessions()
193
188
  if self._engine:
194
189
  self._engine.dispose()
195
- self.bus.log("database session plugin stopped")
196
-
197
- def graceful(self):
198
- """Reload of subscribers."""
199
- self.stop()
200
- self.start()
190
+ self.bus.log("Database session plugin stopped.")
201
191
 
202
192
  def create_all(self):
203
193
  try:
@@ -252,27 +242,11 @@ class SQLA(SimplePlugin):
252
242
  try:
253
243
  # When terminating, raise an error if objects are not commit.
254
244
  if self._session.dirty or self._session.new or self._session.deleted:
255
- cherrypy.log(
256
- 'database session dirty; uncommitted objects detected — potential application bug',
257
- context='DB',
258
- severity=logging.ERROR,
245
+ changes = ', '.join([str(_get_model_changes(obj)) for obj in self._session.dirty])
246
+ logger.exception(
247
+ 'session is dirty, some database object(s) are not commited, this indicate a bug in the application '
248
+ 'dirty %s new %s deleted %s' % (changes, self._session.new, self._session.deleted)
259
249
  )
260
- if self._session.dirty:
261
- changes = ', '.join([str(_get_model_changes(obj)) for obj in self._session.dirty])
262
- cherrypy.log(
263
- f'database session dirty_objects={self._session.dirty}', context='DB', severity=logging.ERROR
264
- )
265
- cherrypy.log(f'database session pending_changes={changes}', context='DB', severity=logging.ERROR)
266
- if self._session.new:
267
- cherrypy.log(
268
- f'database session new_objects={self._session.new}', context='DB', severity=logging.ERROR
269
- )
270
- if self._session.deleted:
271
- cherrypy.log(
272
- f'database session deleted_objects={self._session.deleted}',
273
- context='DB',
274
- severity=logging.ERROR,
275
- )
276
250
  raise SQLAlchemyError('session is dirty')
277
251
  finally:
278
252
  self._session.rollback()