Flask-Exts 0.2.8__tar.gz → 0.3.1__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 (450) hide show
  1. flask_exts-0.3.1/.editorconfig +69 -0
  2. flask_exts-0.3.1/.github/workflows/docs.yml +49 -0
  3. {flask_exts-0.2.8 → flask_exts-0.3.1}/.gitignore +4 -4
  4. flask_exts-0.3.1/.vscode/settings.json +16 -0
  5. flask_exts-0.3.1/CHANGES.rst +39 -0
  6. flask_exts-0.3.1/Makefile +31 -0
  7. flask_exts-0.3.1/PKG-INFO +111 -0
  8. flask_exts-0.3.1/README.rst +69 -0
  9. {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/messages.pot +79 -83
  10. flask_exts-0.3.1/docs/advanced/database.rst +123 -0
  11. flask_exts-0.3.1/docs/advanced/index.rst +13 -0
  12. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/api.rst +2 -2
  13. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/conf.py +10 -9
  14. flask_exts-0.3.1/docs/configure.rst +53 -0
  15. flask_exts-0.3.1/docs/develop.rst +81 -0
  16. flask_exts-0.3.1/docs/examples.rst +11 -0
  17. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/index.rst +14 -5
  18. flask_exts-0.3.1/docs/quickstart.rst +52 -0
  19. flask_exts-0.3.1/examples/README.rst +51 -0
  20. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/admin_views.py +3 -3
  21. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/build_sample.py +42 -38
  22. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/make_app.py +3 -14
  23. flask_exts-0.3.1/examples/demo/models/__init__.py +9 -0
  24. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/author.py +14 -17
  25. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/post.py +7 -8
  26. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/post_tag.py +2 -3
  27. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/tag.py +4 -4
  28. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/tree.py +6 -8
  29. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/author_view.py +8 -7
  30. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/post_view.py +10 -10
  31. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/tag_view.py +3 -1
  32. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/tree_view.py +3 -6
  33. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/simple/__init__.py +4 -3
  34. {flask_exts-0.2.8 → flask_exts-0.3.1}/package.json +5 -1
  35. {flask_exts-0.2.8 → flask_exts-0.3.1}/pyproject.toml +42 -16
  36. flask_exts-0.3.1/requirements/develop.in +1 -0
  37. flask_exts-0.3.1/scripts/copy-vendor.js +195 -0
  38. flask_exts-0.3.1/src/flask_exts/__about__.py +1 -0
  39. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/__init__.py +0 -1
  40. flask_exts-0.3.1/src/flask_exts/admin/__init__.py +10 -0
  41. flask_exts-0.2.8/src/flask_exts/web/admin.py → flask_exts-0.3.1/src/flask_exts/admin/base.py +40 -37
  42. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/exposer.py +12 -10
  43. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/menu.py +31 -32
  44. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/__init__.py +23 -26
  45. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/actions_mixin.py +3 -2
  46. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/ajax.py +13 -10
  47. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/base.py +22 -57
  48. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/__init__.py +7 -7
  49. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/columns.py +26 -25
  50. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/forms.py +26 -23
  51. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/pagination.py +45 -39
  52. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/sorting.py +13 -24
  53. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/values.py +25 -19
  54. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/filter.py +24 -18
  55. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/filter_mixin.py +17 -13
  56. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/__init__.py +7 -7
  57. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/create.py +3 -3
  58. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/export.py +14 -17
  59. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/read.py +9 -9
  60. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/update.py +5 -4
  61. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/row_actions.py +2 -8
  62. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/type_formatters.py +22 -15
  63. flask_exts-0.3.1/src/flask_exts/admin/model/types.py +5 -0
  64. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/view.py +34 -40
  65. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/ajax.py +22 -19
  66. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/filter_converter.py +43 -55
  67. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/filters.py +14 -14
  68. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/field_converters.py +8 -6
  69. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/inline_form.py +6 -4
  70. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/inline_model_convert.py +57 -98
  71. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/model_field_convert.py +9 -8
  72. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/utils.py +22 -14
  73. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/__init__.py +6 -6
  74. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/type_formatters.py +1 -2
  75. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/view.py +270 -59
  76. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/view.py +51 -47
  77. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/__init__.py +8 -9
  78. flask_exts-0.2.8/src/flask_exts/builtin_extensions/web_ext.py → flask_exts-0.3.1/src/flask_exts/builtin_extensions/admin_ext.py +2 -6
  79. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/babel_ext.py +34 -37
  80. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/database_ext.py +4 -5
  81. flask_exts-0.3.1/src/flask_exts/builtin_extensions/emailer_ext.py +15 -0
  82. flask_exts-0.2.8/src/flask_exts/builtin_extensions/html_ext.py → flask_exts-0.3.1/src/flask_exts/builtin_extensions/frontend_ext.py +7 -7
  83. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/login_ext.py +55 -28
  84. flask_exts-0.3.1/src/flask_exts/builtin_extensions/portal_ext.py +14 -0
  85. flask_exts-0.3.1/src/flask_exts/builtin_extensions/security_ext.py +24 -0
  86. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/usercenter_ext.py +4 -8
  87. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/userstore_ext.py +1 -5
  88. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/commands.py +17 -5
  89. flask_exts-0.3.1/src/flask_exts/datastore/sqla/__init__.py +4 -0
  90. flask_exts-0.3.1/src/flask_exts/datastore/sqla/_db.py +45 -0
  91. flask_exts-0.3.1/src/flask_exts/datastore/sqla/database.py +154 -0
  92. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query.py +20 -13
  93. flask_exts-0.3.1/src/flask_exts/datastore/sqla/utils/__init__.py +8 -0
  94. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/utils/model_mapper.py +4 -4
  95. flask_exts-0.3.1/src/flask_exts/datastore/sqla/utils/orm.py +32 -0
  96. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/base.py +9 -3
  97. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/smtp.py +15 -5
  98. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/extension_core/base.py +11 -53
  99. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/extension_core/manager.py +43 -26
  100. flask_exts-0.3.1/src/flask_exts/extension_core/registry.py +219 -0
  101. flask_exts-0.3.1/src/flask_exts/forms/fields/__init__.py +5 -0
  102. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/ajax_select.py +6 -7
  103. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/datetime.py +24 -21
  104. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/file.py +38 -28
  105. flask_exts-0.3.1/src/flask_exts/forms/fields/inline.py +51 -0
  106. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/json.py +1 -0
  107. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/select.py +14 -32
  108. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/sqla.py +3 -146
  109. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/__init__.py +2 -0
  110. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/base_form.py +2 -1
  111. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/csrf.py +7 -10
  112. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/meta.py +8 -12
  113. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/session_csrf.py +7 -10
  114. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/field_list.py +4 -1
  115. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/file.py +20 -21
  116. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/recaptcha.py +5 -5
  117. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/sqla.py +7 -6
  118. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/__init__.py +1 -1
  119. flask_exts-0.3.1/src/flask_exts/forms/widgets/checkbox.py +30 -0
  120. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/editable.py +21 -17
  121. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/file.py +1 -0
  122. flask_exts-0.3.1/src/flask_exts/forms/widgets/inline.py +8 -0
  123. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/recaptcha.py +4 -3
  124. flask_exts-0.3.1/src/flask_exts/forms/widgets/select.py +75 -0
  125. flask_exts-0.3.1/src/flask_exts/frontend/plugin_base.py +24 -0
  126. flask_exts-0.3.1/src/flask_exts/frontend/plugin_manager.py +117 -0
  127. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_detail_filter_plugin.py +1 -0
  128. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_filters_plugin.py +1 -0
  129. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_form_plugin.py +1 -0
  130. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_list_action_plugin.py +1 -0
  131. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_plugin.py +1 -0
  132. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/bootstrap5_plugin.py +1 -0
  133. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/clipboard_plugin.py +1 -0
  134. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/copybutton_plugin.py +1 -0
  135. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/dayjs_plugin.py +8 -8
  136. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/editable_plugin.py +3 -3
  137. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/flatpickr_plugin.py +10 -7
  138. flask_exts-0.3.1/src/flask_exts/frontend/plugins/modal_plugin.py +41 -0
  139. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/qrcode_plugin.py +1 -0
  140. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/rediscli_plugin.py +1 -0
  141. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/sphinx_copybutton_plugin.py +1 -0
  142. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/tom_select_plugin.py +4 -3
  143. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/template.py +0 -5
  144. {flask_exts-0.2.8/src/flask_exts/web/default_views → flask_exts-0.3.1/src/flask_exts/portal}/index_view.py +1 -1
  145. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/proxies.py +3 -2
  146. flask_exts-0.3.1/src/flask_exts/security/__init__.py +3 -0
  147. flask_exts-0.3.1/src/flask_exts/security/authorizer/base.py +8 -0
  148. flask_exts-0.3.1/src/flask_exts/security/authorizer/simple_authorizer.py +56 -0
  149. flask_exts-0.3.1/src/flask_exts/security/core.py +39 -0
  150. flask_exts-0.3.1/src/flask_exts/security/exceptions.py +24 -0
  151. flask_exts-0.3.1/src/flask_exts/security/keys.py +23 -0
  152. flask_exts-0.3.1/src/flask_exts/security/plugins/email_change.py +92 -0
  153. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/email_verification.py +8 -4
  154. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/reset_password.py +13 -7
  155. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/two_factor_authentication.py +1 -0
  156. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/registry.py +7 -1
  157. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/serializer.py +19 -13
  158. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/token_action.py +60 -33
  159. flask_exts-0.3.1/src/flask_exts/security/urls.py +28 -0
  160. flask_exts-0.3.1/src/flask_exts/security/user_mixin.py +10 -0
  161. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/admin.css +2 -3
  162. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/copybutton.js +4 -4
  163. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/detail_filter.js +13 -9
  164. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/editable.js +2 -2
  165. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/field-registry.js +0 -2
  166. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/filters.js +5 -23
  167. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/form.js +167 -121
  168. flask_exts-0.3.1/src/flask_exts/static/js/modal.js +621 -0
  169. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/rediscli.js +2 -6
  170. flask_exts-0.3.1/src/flask_exts/static/vendor/bootstrap5/bootstrap.bundle.min.js +7 -0
  171. flask_exts-0.3.1/src/flask_exts/static/vendor/bootstrap5/bootstrap.min.css +6 -0
  172. flask_exts-0.3.1/src/flask_exts/static/vendor/clipboard/clipboard.min.js +7 -0
  173. flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/dayjs.min.js +1 -0
  174. flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/timezone.js +1 -0
  175. flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/utc.js +1 -0
  176. flask_exts-0.3.1/src/flask_exts/static/vendor/flatpickr/flatpickr.min.css +13 -0
  177. flask_exts-0.3.1/src/flask_exts/static/vendor/flatpickr/flatpickr.min.js +2 -0
  178. flask_exts-0.3.1/src/flask_exts/static/vendor/tom-select/tom-select.bootstrap5.min.css +2 -0
  179. flask_exts-0.3.1/src/flask_exts/static/vendor/tom-select/tom-select.complete.min.js +454 -0
  180. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/master.html +7 -7
  181. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/create.html +3 -1
  182. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/details.html +1 -1
  183. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/edit.html +1 -1
  184. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/list.html +34 -45
  185. flask_exts-0.3.1/src/flask_exts/templates/base.html +19 -0
  186. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/index.html +0 -1
  187. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/layout.html +2 -2
  188. flask_exts-0.3.1/src/flask_exts/templates/macro/form.html +137 -0
  189. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/layout.html +10 -7
  190. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/menu.html +7 -7
  191. flask_exts-0.3.1/src/flask_exts/templates/macro/message.html +22 -0
  192. flask_exts-0.3.1/src/flask_exts/templates/macro/modal.html +15 -0
  193. flask_exts-0.3.1/src/flask_exts/templates/user/email_change.html +22 -0
  194. flask_exts-0.3.1/src/flask_exts/templates/user/index.html +42 -0
  195. flask_exts-0.3.1/src/flask_exts/templates/user/list.html +5 -0
  196. flask_exts-0.3.1/src/flask_exts/templates/user/profile.html +96 -0
  197. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/recovery_codes.html +4 -6
  198. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/setup_tfa.html +18 -7
  199. flask_exts-0.3.1/src/flask_exts/templates/user/show_tfa.html +26 -0
  200. flask_exts-0.3.1/src/flask_exts/templates/user/verify_email.html +26 -0
  201. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/verify_tfa.html +1 -1
  202. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/en/LC_MESSAGES/messages.mo +0 -0
  203. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/en/LC_MESSAGES/messages.po +139 -83
  204. flask_exts-0.3.1/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
  205. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.po +159 -102
  206. flask_exts-0.3.1/src/flask_exts/usercenter/auth_requires.py +34 -0
  207. flask_exts-0.3.1/src/flask_exts/usercenter/forms/email_change.py +29 -0
  208. flask_exts-0.3.1/src/flask_exts/usercenter/forms/forgot_password.py +12 -0
  209. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/register.py +8 -6
  210. flask_exts-0.3.1/src/flask_exts/usercenter/forms/resend_verification.py +7 -0
  211. flask_exts-0.3.1/src/flask_exts/usercenter/user_view.py +410 -0
  212. flask_exts-0.2.8/src/flask_exts/userstore/store.py → flask_exts-0.3.1/src/flask_exts/userstore/base.py +1 -3
  213. flask_exts-0.3.1/src/flask_exts/userstore/exceptions.py +15 -0
  214. flask_exts-0.3.1/src/flask_exts/userstore/sqla/__init__.py +4 -0
  215. flask_exts-0.3.1/src/flask_exts/userstore/sqla/models/__init__.py +6 -0
  216. {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/role.py +5 -5
  217. {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user.py +25 -21
  218. {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user_profile.py +13 -12
  219. {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user_role.py +3 -4
  220. flask_exts-0.2.8/src/flask_exts/userstore/sqla_user_store.py → flask_exts-0.3.1/src/flask_exts/userstore/sqla/userstore.py +18 -14
  221. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/core/test_columns.py +1 -1
  222. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_action_mixin.py +2 -4
  223. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_model_view.py +25 -91
  224. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_model_view_csrf.py +17 -14
  225. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/custom_sqla_model_view.py +1 -1
  226. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_basic.py +41 -49
  227. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_filter.py +2 -3
  228. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_form.py +11 -5
  229. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_inline_model.py +219 -48
  230. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_multi_pk.py +30 -3
  231. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_primary_string.py +3 -3
  232. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_translation.py +5 -5
  233. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/test_admin.py +3 -25
  234. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/test_view.py +1 -3
  235. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/conftest.py +7 -4
  236. flask_exts-0.3.1/tests/datastore/sqla/test_db.py +171 -0
  237. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/datastore/sqla/test_query.py +5 -3
  238. {flask_exts-0.2.8/tests/email → flask_exts-0.3.1/tests/emailer}/test_base.py +1 -0
  239. {flask_exts-0.2.8/tests/email → flask_exts-0.3.1/tests/emailer}/test_smtp.py +2 -1
  240. flask_exts-0.3.1/tests/extension_core/test_manager.py +89 -0
  241. flask_exts-0.3.1/tests/extension_core/test_registry.py +199 -0
  242. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_datetime.py +2 -0
  243. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_filefield.py +4 -3
  244. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_json.py +4 -4
  245. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_uploadfile.py +5 -3
  246. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_wtforms.py +3 -2
  247. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/form/test_form.py +19 -1
  248. flask_exts-0.3.1/tests/frontend/__init__.py +0 -0
  249. {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/conftest.py +2 -1
  250. flask_exts-0.3.1/tests/frontend/test_base.py +23 -0
  251. flask_exts-0.3.1/tests/frontend/test_plugin_manager.py +95 -0
  252. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/demo.py +37 -32
  253. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/multpk.py +1 -3
  254. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/primary_string_model.py +2 -4
  255. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/relations.py +5 -7
  256. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/simple.py +1 -3
  257. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/tree.py +4 -9
  258. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/unique.py +2 -3
  259. flask_exts-0.3.1/tests/security/test_authorizer.py +94 -0
  260. flask_exts-0.3.1/tests/security/test_core.py +118 -0
  261. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/security/test_tfa.py +3 -1
  262. flask_exts-0.3.1/tests/security/test_urls.py +23 -0
  263. flask_exts-0.3.1/tests/test_builtin_exts.py +55 -0
  264. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/test_login.py +23 -14
  265. {flask_exts-0.2.8/tests/views → flask_exts-0.3.1/tests/usercenter}/test_user_view.py +309 -59
  266. flask_exts-0.3.1/tests/userstore/test_sqla_userstore.py +72 -0
  267. flask_exts-0.2.8/.djlintrc +0 -8
  268. flask_exts-0.2.8/CHANGES.rst +0 -147
  269. flask_exts-0.2.8/PKG-INFO +0 -95
  270. flask_exts-0.2.8/README.rst +0 -40
  271. flask_exts-0.2.8/docs/advanced/bootstrap5.rst +0 -429
  272. flask_exts-0.2.8/docs/advanced/custom_fields.rst +0 -384
  273. flask_exts-0.2.8/docs/advanced/custom_plugins.rst +0 -247
  274. flask_exts-0.2.8/docs/advanced/custom_validators.rst +0 -4
  275. flask_exts-0.2.8/docs/advanced/index.rst +0 -16
  276. flask_exts-0.2.8/docs/advanced/modelview.rst +0 -337
  277. flask_exts-0.2.8/docs/advanced/performance.rst +0 -493
  278. flask_exts-0.2.8/docs/advanced/security.rst +0 -498
  279. flask_exts-0.2.8/docs/advanced/theming.rst +0 -401
  280. flask_exts-0.2.8/docs/configure.rst +0 -25
  281. flask_exts-0.2.8/docs/develop.rst +0 -65
  282. flask_exts-0.2.8/docs/examples.rst +0 -6
  283. flask_exts-0.2.8/docs/quickstart.rst +0 -264
  284. flask_exts-0.2.8/examples/README.rst +0 -38
  285. flask_exts-0.2.8/examples/demo/models/__init__.py +0 -9
  286. flask_exts-0.2.8/src/flask_exts/__about__.py +0 -1
  287. flask_exts-0.2.8/src/flask_exts/builtin_extensions/email_ext.py +0 -16
  288. flask_exts-0.2.8/src/flask_exts/builtin_extensions/security_ext.py +0 -23
  289. flask_exts-0.2.8/src/flask_exts/builtin_extensions/startup_ext.py +0 -41
  290. flask_exts-0.2.8/src/flask_exts/datastore/sqla/__init__.py +0 -3
  291. flask_exts-0.2.8/src/flask_exts/datastore/sqla/sqla_db.py +0 -82
  292. flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/__init__.py +0 -6
  293. flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/orm.py +0 -40
  294. flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/paginate.py +0 -74
  295. flask_exts-0.2.8/src/flask_exts/extension_core/registry.py +0 -263
  296. flask_exts-0.2.8/src/flask_exts/forms/fields/__init__.py +0 -6
  297. flask_exts-0.2.8/src/flask_exts/forms/fields/inline.py +0 -90
  298. flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/__init__.py +0 -39
  299. flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/checkbox_fields.py +0 -9
  300. flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/inline_fields.py +0 -10
  301. flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/query_fields.py +0 -11
  302. flask_exts-0.2.8/src/flask_exts/forms/validators/__init__.py +0 -1
  303. flask_exts-0.2.8/src/flask_exts/forms/widgets/checkbox.py +0 -32
  304. flask_exts-0.2.8/src/flask_exts/forms/widgets/inline.py +0 -14
  305. flask_exts-0.2.8/src/flask_exts/forms/widgets/select.py +0 -81
  306. flask_exts-0.2.8/src/flask_exts/html/plugin_base.py +0 -32
  307. flask_exts-0.2.8/src/flask_exts/html/plugin_manager.py +0 -85
  308. flask_exts-0.2.8/src/flask_exts/html/plugins/admin_modal_plugin.py +0 -11
  309. flask_exts-0.2.8/src/flask_exts/html/plugins/bootstrap4_plugin.py +0 -19
  310. flask_exts-0.2.8/src/flask_exts/security/authorizer/base.py +0 -17
  311. flask_exts-0.2.8/src/flask_exts/security/authorizer/simple_authorizer.py +0 -21
  312. flask_exts-0.2.8/src/flask_exts/security/core.py +0 -54
  313. flask_exts-0.2.8/src/flask_exts/static/js/modal.js +0 -49
  314. flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/create.html +0 -5
  315. flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/details.html +0 -37
  316. flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/edit.html +0 -5
  317. flask_exts-0.2.8/src/flask_exts/templates/base.html +0 -19
  318. flask_exts-0.2.8/src/flask_exts/templates/macro/form.html +0 -83
  319. flask_exts-0.2.8/src/flask_exts/templates/macro/inline.html +0 -44
  320. flask_exts-0.2.8/src/flask_exts/templates/macro/message.html +0 -22
  321. flask_exts-0.2.8/src/flask_exts/templates/macro/modal.html +0 -13
  322. flask_exts-0.2.8/src/flask_exts/templates/user/index.html +0 -53
  323. flask_exts-0.2.8/src/flask_exts/templates/user/list.html +0 -5
  324. flask_exts-0.2.8/src/flask_exts/templates/user/show_tfa.html +0 -23
  325. flask_exts-0.2.8/src/flask_exts/templates/user/verify_email.html +0 -5
  326. flask_exts-0.2.8/src/flask_exts/templates/user/verify_tfa_modal.html +0 -13
  327. flask_exts-0.2.8/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
  328. flask_exts-0.2.8/src/flask_exts/usercenter/auth_requires.py +0 -39
  329. flask_exts-0.2.8/src/flask_exts/usercenter/forms/forgot_password.py +0 -19
  330. flask_exts-0.2.8/src/flask_exts/usercenter/forms/profile.py +0 -11
  331. flask_exts-0.2.8/src/flask_exts/usercenter/user.py +0 -14
  332. flask_exts-0.2.8/src/flask_exts/usercenter/user_view.py +0 -291
  333. flask_exts-0.2.8/src/flask_exts/userstore/models/__init__.py +0 -1
  334. flask_exts-0.2.8/src/flask_exts/web/__init__.py +0 -3
  335. flask_exts-0.2.8/src/flask_exts/web/model/types.py +0 -4
  336. flask_exts-0.2.8/tests/datastore/sqla/test_db.py +0 -82
  337. flask_exts-0.2.8/tests/html/test_base.py +0 -28
  338. flask_exts-0.2.8/tests/security/test_authorizer.py +0 -116
  339. flask_exts-0.2.8/tests/security/test_core.py +0 -51
  340. flask_exts-0.2.8/tests/test_base.py +0 -9
  341. flask_exts-0.2.8/tests/test_db.py +0 -19
  342. flask_exts-0.2.8/tests/test_exts_base.py +0 -38
  343. flask_exts-0.2.8/tests/usercenter/test_sqla_usercenter.py +0 -50
  344. {flask_exts-0.2.8 → flask_exts-0.3.1}/.github/workflows/release.yml +0 -0
  345. {flask_exts-0.2.8 → flask_exts-0.3.1}/.readthedocs.yaml +0 -0
  346. {flask_exts-0.2.8 → flask_exts-0.3.1}/LICENSE.rst +0 -0
  347. {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/babel.cfg +0 -0
  348. {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/babel.sh +0 -0
  349. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/Makefile +0 -0
  350. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/_static/logo.png +0 -0
  351. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/changes.rst +0 -0
  352. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/make.bat +0 -0
  353. {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/requirements.txt +0 -0
  354. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/__init__.py +0 -0
  355. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/file_op.py +0 -0
  356. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/static/favicon.ico +0 -0
  357. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/field_list.html +0 -0
  358. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/locations.html +0 -0
  359. {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/tree_list.html +0 -0
  360. {flask_exts-0.2.8 → flask_exts-0.3.1}/requirements/build.in +0 -0
  361. {flask_exts-0.2.8 → flask_exts-0.3.1}/requirements/test.in +0 -0
  362. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/delete.py +0 -0
  363. {flask_exts-0.2.8/src/flask_exts/datastore → flask_exts-0.3.1/src/flask_exts/admin/sqla}/__init__.py +0 -0
  364. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/__init__.py +0 -0
  365. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/__init__.py +0 -0
  366. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/pagination_handler.py +0 -0
  367. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/query_handler.py +0 -0
  368. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/relationships_handler.py +0 -0
  369. {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/sorting_handler.py +0 -0
  370. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/constants.py +0 -0
  371. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/datastore}/__init__.py +0 -0
  372. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/__init__.py +0 -0
  373. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/filter_builder.py +0 -0
  374. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/join_builder.py +0 -0
  375. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/pagination_builder.py +0 -0
  376. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/sort_builder.py +0 -0
  377. {flask_exts-0.2.8/src/flask_exts/extension_core → flask_exts-0.3.1/src/flask_exts/emailer}/__init__.py +0 -0
  378. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/reset_password_sender.py +0 -0
  379. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/sender.py +0 -0
  380. {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/verify_email_sender.py +0 -0
  381. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/extension_core}/__init__.py +0 -0
  382. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/__init__.py +0 -0
  383. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/recaptcha.py +0 -0
  384. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/switch.py +0 -0
  385. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/taglist.py +0 -0
  386. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/flask_form.py +0 -0
  387. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/utils.py +0 -0
  388. {flask_exts-0.2.8/src/flask_exts/html/plugins → flask_exts-0.3.1/src/flask_exts/forms/validators}/__init__.py +0 -0
  389. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/datetime.py +0 -0
  390. {flask_exts-0.2.8/src/flask_exts/security → flask_exts-0.3.1/src/flask_exts/frontend}/__init__.py +0 -0
  391. {flask_exts-0.2.8/src/flask_exts/security/authorizer → flask_exts-0.3.1/src/flask_exts/frontend/plugins}/__init__.py +0 -0
  392. {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/theme.py +0 -0
  393. {flask_exts-0.2.8/src/flask_exts/translations → flask_exts-0.3.1/src/flask_exts/portal}/__init__.py +0 -0
  394. {flask_exts-0.2.8/src/flask_exts/usercenter → flask_exts-0.3.1/src/flask_exts/security/authorizer}/__init__.py +0 -0
  395. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/hasher.py +0 -0
  396. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/signals.py +0 -0
  397. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/editable.css +0 -0
  398. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/rediscli.css +0 -0
  399. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/list_action.js +0 -0
  400. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/qrcode.js +0 -0
  401. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/security/base64.js +0 -0
  402. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/security/webauthn.js +0 -0
  403. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/ui-factory.js +0 -0
  404. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/logo.png +0 -0
  405. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/vendor/sphinx-copybutton/sphinx-copybutton.css +0 -0
  406. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/vendor/sphinx-copybutton/sphinx-copybutton.js +0 -0
  407. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/index.html +0 -0
  408. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/icon.html +0 -0
  409. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/nav.html +0 -0
  410. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/pagination.html +0 -0
  411. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/change_password.html +0 -0
  412. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/forgot_password.html +0 -0
  413. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/login.html +0 -0
  414. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/recovery.html +0 -0
  415. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/register.html +0 -0
  416. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/reset_password.html +0 -0
  417. {flask_exts-0.2.8/src/flask_exts/web/default_views → flask_exts-0.3.1/src/flask_exts/translations}/__init__.py +0 -0
  418. {flask_exts-0.2.8/src/flask_exts/web/sqla → flask_exts-0.3.1/src/flask_exts/usercenter}/__init__.py +0 -0
  419. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/core.py +0 -0
  420. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/__init__.py +0 -0
  421. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/change_password.py +0 -0
  422. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/login.py +0 -0
  423. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/recovery.py +0 -0
  424. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/reset_password.py +0 -0
  425. {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/two_factor.py +0 -0
  426. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/__init__.py +0 -0
  427. {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/admin}/__init__.py +0 -0
  428. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/__init__.py +0 -0
  429. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/templates/another_macro.html +0 -0
  430. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/templates/macro.html +0 -0
  431. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.gif +0 -0
  432. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.jpeg +0 -0
  433. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.jpg +0 -0
  434. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.png +0 -0
  435. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.tiff +0 -0
  436. {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/extension_core}/__init__.py +0 -0
  437. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/common.py +0 -0
  438. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_inline.py +0 -0
  439. {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/macros/test_render_breadcrumb_item.py +0 -0
  440. {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/macros/test_render_nav_item.py +0 -0
  441. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/helper.py +0 -0
  442. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/__init__.py +0 -0
  443. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/templates/method.html +0 -0
  444. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/templates/mock.html +0 -0
  445. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/test_babel.py +1 -1
  446. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/en/LC_MESSAGES/messages.mo +0 -0
  447. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/en/LC_MESSAGES/messages.po +0 -0
  448. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/messages.pot +0 -0
  449. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
  450. {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
@@ -0,0 +1,69 @@
1
+ # EditorConfig is awesome: https://EditorConfig.org
2
+ # Team style guide blending Google and Microsoft conventions
3
+
4
+ # Mark as root so EditorConfig stops searching parent directories
5
+ root = true
6
+
7
+ # ============================================================
8
+ # General defaults (common to Google and Microsoft)
9
+ # ============================================================
10
+ [*]
11
+ charset = utf-8
12
+ end_of_line = lf
13
+ insert_final_newline = true
14
+ trim_trailing_whitespace = true
15
+ indent_style = space
16
+ indent_size = 4
17
+
18
+ # ============================================================
19
+ # JavaScript / TypeScript (Google style: 2 spaces)
20
+ # Ref: Google JavaScript Style Guide - Block indentation
21
+ # ============================================================
22
+ [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}]
23
+ indent_size = 2
24
+
25
+ # ============================================================
26
+ # JSON / YAML / HTML / CSS (industry common: 2 spaces)
27
+ # ============================================================
28
+ [*.{json,jsonc,yml,yaml,html,css,scss,less,vue,svelte}]
29
+ indent_size = 2
30
+
31
+ # ============================================================
32
+ # Python (Google style: 4 spaces, never tabs)
33
+ # Ref: Google Python Style Guide - Indentation
34
+ # ============================================================
35
+ [*.py]
36
+ indent_size = 4
37
+
38
+ # ============================================================
39
+ # Go (gofmt enforces tabs)
40
+ # Ref: gofmt specification
41
+ # ============================================================
42
+ [*.go]
43
+ indent_style = tab
44
+
45
+ # ============================================================
46
+ # C# / .NET (Microsoft style: 4 spaces, UTF-8 BOM)
47
+ # Ref: dotnet/roslyn .editorconfig
48
+ # ============================================================
49
+ [*.{cs,csx,vb,vbx}]
50
+ indent_size = 4
51
+ charset = utf-8-bom
52
+
53
+ # ============================================================
54
+ # Shell scripts
55
+ # ============================================================
56
+ [*.sh]
57
+ indent_size = 2
58
+
59
+ # ============================================================
60
+ # Markdown (do not trim trailing whitespace; preserves line breaks)
61
+ # ============================================================
62
+ [*.md]
63
+ trim_trailing_whitespace = false
64
+
65
+ # ============================================================
66
+ # Makefile (must use tabs)
67
+ # ============================================================
68
+ [Makefile]
69
+ indent_style = tab
@@ -0,0 +1,49 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ paths:
6
+ - "docs/**"
7
+ - "src/**"
8
+ - "examples/**"
9
+ - "CHANGES.rst"
10
+ - "pyproject.toml"
11
+ - ".github/workflows/docs.yml"
12
+ pull_request:
13
+ paths:
14
+ - "docs/**"
15
+ - "src/**"
16
+ - "examples/**"
17
+ - "CHANGES.rst"
18
+ - "pyproject.toml"
19
+ - ".github/workflows/docs.yml"
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ build-docs:
26
+ name: Build Sphinx documentation
27
+ runs-on: ubuntu-latest
28
+
29
+ steps:
30
+ - name: Check out repository
31
+ uses: actions/checkout@v4
32
+
33
+ - name: Set up Python
34
+ uses: actions/setup-python@v5
35
+ with:
36
+ python-version: "3.13"
37
+ cache: pip
38
+ cache-dependency-path: |
39
+ pyproject.toml
40
+ docs/requirements.txt
41
+
42
+ - name: Install project and documentation dependencies
43
+ run: |
44
+ python -m pip install --upgrade pip
45
+ python -m pip install -e .
46
+ python -m pip install -r docs/requirements.txt
47
+
48
+ - name: Build documentation
49
+ run: python -m sphinx -b html docs docs/_build/html -W -n --keep-going
@@ -1,6 +1,3 @@
1
- ### vscode
2
- .vscode
3
-
4
1
  ### JupyterNotebooks ###
5
2
  .ipynb_checkpoints
6
3
  */.ipynb_checkpoints/*
@@ -24,6 +21,9 @@ build/
24
21
  .coverage
25
22
  htmlcov/
26
23
 
24
+ # djlint
25
+ .djlint_cache/
26
+
27
27
  # Translations
28
28
  # *.mo
29
29
 
@@ -33,7 +33,7 @@ docs/_build/
33
33
  # sqlite db
34
34
  *.sqlite
35
35
 
36
- # npm front-end deps (symlinked into src/flask_exts/static/vendor; install via `npm ci`)
36
+ # npm front-end deps
37
37
  node_modules/
38
38
  package-lock.json
39
39
 
@@ -0,0 +1,16 @@
1
+ {
2
+ "files.eol": "\n",
3
+ "files.associations": {
4
+ "**/templates/**/*.html": "jinja-html"
5
+ },
6
+ "[jinja-html]": {
7
+ "editor.defaultFormatter": "monosans.djlint",
8
+ "editor.formatOnSave": true
9
+ },
10
+ "djlint.useEditorIndentation": false,
11
+ "python.testing.unittestEnabled": false,
12
+ "python.testing.pytestEnabled": true,
13
+ "python.testing.pytestArgs": [
14
+ "tests"
15
+ ],
16
+ }
@@ -0,0 +1,39 @@
1
+ v0.3.1
2
+ ------
3
+
4
+ Released 2026-10-11
5
+
6
+ - Improve SQLAlchemy lifecycle management, session configuration, and in-memory SQLite support.
7
+ - Add reusable modal form flows and improve two-factor authentication setup.
8
+ - Allow extensions to provide admin views for automatic registration, and clarify duplicate extension-name errors.
9
+
10
+ v0.3.0
11
+ ------
12
+
13
+ Released 2026-10-07
14
+
15
+ - Add user registration, login, logout, profile management, and user-center views.
16
+ - Add email verification, email change, password reset, and recovery workflows.
17
+ - Add a SQLAlchemy-backed user store with user profiles and role management.
18
+ - Add authentication and role-based authorization.
19
+ - Add TOTP-based two-factor authentication and recovery codes.
20
+
21
+ v0.2.0
22
+ ------
23
+
24
+ Released 2026-01-07
25
+
26
+ - Add an extension system with registration, dependency management, and lifecycle hooks.
27
+ - Add an admin interface with model views, CRUD operations, filtering, sorting, pagination, and data export.
28
+ - Add SQLAlchemy integration for database access, model forms, relationships, and queries.
29
+ - Add form fields, widgets, validators, and CSRF protection.
30
+ - Add email delivery and notification support.
31
+ - Add frontend plugin management and Bootstrap-based components.
32
+ - Add Babel integration for localization.
33
+
34
+ v0.1.0
35
+ ------
36
+
37
+ Released 2024-03-20
38
+
39
+ - Initial release of the Flask-Exts package and documentation.
@@ -0,0 +1,31 @@
1
+ .PHONY: docs-build docs-serve docs-clean
2
+
3
+ docs-build:
4
+ python -m sphinx -b html docs docs/_build/html -W -n --keep-going
5
+
6
+ docs-serve:
7
+ python -m http.server -d docs/_build/html 8000
8
+
9
+ docs-clean:
10
+ rm -rf docs/_build
11
+
12
+ test:
13
+ pytest
14
+
15
+ pytest-last:
16
+ pytest --lf --last-failed-no-failures=none
17
+
18
+ pytest-clean:
19
+ rm -rf .pytest_cache
20
+
21
+ pytest-warn:
22
+ pytest -W error
23
+
24
+ pytest-print:
25
+ pytest -s
26
+
27
+ coverage:
28
+ coverage run -m pytest
29
+
30
+ coverage-report:
31
+ coverage report -m
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.5
2
+ Name: Flask-Exts
3
+ Version: 0.3.1
4
+ Summary: Flask extensions with admin, SQLAlchemy, Babel, forms, fields, widgets, and more.
5
+ Project-URL: Documentation, https://flask-exts.readthedocs.io
6
+ Project-URL: Source, https://github.com/ojso/flask-exts
7
+ Project-URL: Homepage, https://github.com/ojso/flask-exts
8
+ Project-URL: Issues, https://github.com/ojso/flask-exts/issues
9
+ Project-URL: Changelog, https://flask-exts.readthedocs.io/en/latest/changes.html
10
+ Author-email: David Hua <david.dong.hua@gmail.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE.rst
13
+ Keywords: admin,babel,flask,form,sqlalchemy,widget
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Web Environment
16
+ Classifier: Framework :: Flask
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Requires-Python: >=3.10
28
+ Requires-Dist: email-validator>=2.0
29
+ Requires-Dist: flask-babel>=4.0
30
+ Requires-Dist: flask-login>=0.6
31
+ Requires-Dist: flask>=3.0
32
+ Requires-Dist: pyjwt>=2.0
33
+ Requires-Dist: pyotp>=2.0
34
+ Requires-Dist: sqlalchemy>=2.0
35
+ Requires-Dist: tablib>=3.0
36
+ Requires-Dist: wtforms>=3.0
37
+ Provides-Extra: dev
38
+ Requires-Dist: djlint; extra == 'dev'
39
+ Requires-Dist: pytest; extra == 'dev'
40
+ Requires-Dist: ruff; extra == 'dev'
41
+ Description-Content-Type: text/x-rst
42
+
43
+ Flask-Exts
44
+ ==========
45
+
46
+ Flask-Exts is a toolkit for building Flask applications with an integrated
47
+ admin interface, SQLAlchemy support, forms, localization, and user-account
48
+ features. It brings common application components together behind a
49
+ dependency-aware extension system. The project is inspired by
50
+ `Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_ and
51
+ `Bootstrap <https://getbootstrap.com/>`_.
52
+
53
+ Highlights
54
+ ----------
55
+
56
+ - **Modern frontend:** Uses Bootstrap 5 and native browser APIs, with no
57
+ jQuery dependency or Bootstrap 4 frontend.
58
+ - **Composable extensions:** Initializes extensions in dependency order and
59
+ lets extensions contribute views to the admin interface.
60
+ - **Built-in account features:** Provides authentication, email verification
61
+ and recovery flows, TOTP-based two-factor authentication, and recovery
62
+ codes.
63
+ - **Integrated admin and data tools:** Includes SQLAlchemy integration,
64
+ model management, forms, filtering, and data export.
65
+ - **Localization support:** Integrates Babel for translating application
66
+ interfaces.
67
+
68
+ Installation
69
+ ------------
70
+
71
+ Flask-Exts requires Python 3.10 or later. Install it with pip:
72
+
73
+ .. code-block:: console
74
+
75
+ pip install flask-exts
76
+
77
+ Quick start
78
+ -----------
79
+
80
+ Create a Flask application and initialize the extension manager:
81
+
82
+ .. code-block:: python
83
+
84
+ from flask import Flask
85
+ from flask_exts import ExtensionManager
86
+
87
+ app = Flask(__name__)
88
+ app.config["SECRET_KEY"] = "change-this-for-local-development"
89
+ app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.sqlite"
90
+
91
+ extensions = ExtensionManager()
92
+ extensions.init_app(app)
93
+
94
+ if __name__ == "__main__":
95
+ app.run(debug=True)
96
+
97
+ For a complete example with a custom admin view and database setup, see
98
+ ``examples/simple``.
99
+
100
+ Documentation
101
+ -------------
102
+
103
+ - `Documentation <https://flask-exts.readthedocs.io/>`_
104
+ - `Runnable examples <https://github.com/ojso/flask-exts/tree/main/examples>`_
105
+ - `Changelog <https://flask-exts.readthedocs.io/en/latest/changes.html>`_
106
+
107
+ License
108
+ -------
109
+
110
+ Flask-Exts is distributed under the terms of the
111
+ `MIT License <https://opensource.org/licenses/MIT>`_.
@@ -0,0 +1,69 @@
1
+ Flask-Exts
2
+ ==========
3
+
4
+ Flask-Exts is a toolkit for building Flask applications with an integrated
5
+ admin interface, SQLAlchemy support, forms, localization, and user-account
6
+ features. It brings common application components together behind a
7
+ dependency-aware extension system. The project is inspired by
8
+ `Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_ and
9
+ `Bootstrap <https://getbootstrap.com/>`_.
10
+
11
+ Highlights
12
+ ----------
13
+
14
+ - **Modern frontend:** Uses Bootstrap 5 and native browser APIs, with no
15
+ jQuery dependency or Bootstrap 4 frontend.
16
+ - **Composable extensions:** Initializes extensions in dependency order and
17
+ lets extensions contribute views to the admin interface.
18
+ - **Built-in account features:** Provides authentication, email verification
19
+ and recovery flows, TOTP-based two-factor authentication, and recovery
20
+ codes.
21
+ - **Integrated admin and data tools:** Includes SQLAlchemy integration,
22
+ model management, forms, filtering, and data export.
23
+ - **Localization support:** Integrates Babel for translating application
24
+ interfaces.
25
+
26
+ Installation
27
+ ------------
28
+
29
+ Flask-Exts requires Python 3.10 or later. Install it with pip:
30
+
31
+ .. code-block:: console
32
+
33
+ pip install flask-exts
34
+
35
+ Quick start
36
+ -----------
37
+
38
+ Create a Flask application and initialize the extension manager:
39
+
40
+ .. code-block:: python
41
+
42
+ from flask import Flask
43
+ from flask_exts import ExtensionManager
44
+
45
+ app = Flask(__name__)
46
+ app.config["SECRET_KEY"] = "change-this-for-local-development"
47
+ app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.sqlite"
48
+
49
+ extensions = ExtensionManager()
50
+ extensions.init_app(app)
51
+
52
+ if __name__ == "__main__":
53
+ app.run(debug=True)
54
+
55
+ For a complete example with a custom admin view and database setup, see
56
+ ``examples/simple``.
57
+
58
+ Documentation
59
+ -------------
60
+
61
+ - `Documentation <https://flask-exts.readthedocs.io/>`_
62
+ - `Runnable examples <https://github.com/ojso/flask-exts/tree/main/examples>`_
63
+ - `Changelog <https://flask-exts.readthedocs.io/en/latest/changes.html>`_
64
+
65
+ License
66
+ -------
67
+
68
+ Flask-Exts is distributed under the terms of the
69
+ `MIT License <https://opensource.org/licenses/MIT>`_.