arthexis 0.1.17__tar.gz → 0.1.19__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.

Potentially problematic release.


This version of arthexis might be problematic. Click here for more details.

Files changed (251) hide show
  1. {arthexis-0.1.17 → arthexis-0.1.19}/PKG-INFO +37 -10
  2. {arthexis-0.1.17 → arthexis-0.1.19}/README.md +27 -0
  3. {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/PKG-INFO +37 -10
  4. {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/SOURCES.txt +3 -1
  5. {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/requires.txt +9 -9
  6. arthexis-0.1.19/config/middleware.py +71 -0
  7. {arthexis-0.1.17 → arthexis-0.1.19}/config/settings.py +2 -5
  8. {arthexis-0.1.17 → arthexis-0.1.19}/config/urls.py +5 -0
  9. {arthexis-0.1.17 → arthexis-0.1.19}/core/admin.py +1 -1
  10. {arthexis-0.1.17 → arthexis-0.1.19}/core/models.py +31 -1
  11. {arthexis-0.1.17 → arthexis-0.1.19}/core/system.py +125 -0
  12. {arthexis-0.1.17 → arthexis-0.1.19}/core/tasks.py +0 -22
  13. {arthexis-0.1.17 → arthexis-0.1.19}/core/tests.py +9 -0
  14. {arthexis-0.1.17 → arthexis-0.1.19}/core/views.py +87 -19
  15. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/admin.py +1 -2
  16. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/models.py +18 -23
  17. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/tests.py +42 -34
  18. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/urls.py +0 -1
  19. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/views.py +2 -15
  20. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/admin.py +23 -2
  21. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/consumers.py +63 -19
  22. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/models.py +7 -0
  23. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/store.py +6 -4
  24. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/test_rfid.py +70 -0
  25. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/tests.py +107 -1
  26. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/views.py +84 -10
  27. {arthexis-0.1.17 → arthexis-0.1.19}/pages/admin.py +150 -15
  28. {arthexis-0.1.17 → arthexis-0.1.19}/pages/apps.py +3 -0
  29. {arthexis-0.1.17 → arthexis-0.1.19}/pages/context_processors.py +11 -0
  30. {arthexis-0.1.17 → arthexis-0.1.19}/pages/middleware.py +3 -0
  31. {arthexis-0.1.17 → arthexis-0.1.19}/pages/models.py +35 -0
  32. arthexis-0.1.19/pages/site_config.py +137 -0
  33. {arthexis-0.1.17 → arthexis-0.1.19}/pages/tests.py +352 -30
  34. {arthexis-0.1.17 → arthexis-0.1.19}/pages/urls.py +2 -1
  35. {arthexis-0.1.17 → arthexis-0.1.19}/pages/views.py +70 -23
  36. arthexis-0.1.19/pyproject.toml +26 -0
  37. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_client_report.py +11 -0
  38. arthexis-0.1.19/tests/test_admin_system_stop.py +127 -0
  39. arthexis-0.1.19/tests/test_client_report_form.py +30 -0
  40. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_client_report_generation.py +33 -0
  41. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_invitation_login_view.py +28 -0
  42. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_node_info_view.py +20 -0
  43. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_progress.py +42 -0
  44. arthexis-0.1.19/tests/test_render_nginx_sites.py +72 -0
  45. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_seed_data.py +61 -0
  46. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_temp_passwords.py +30 -1
  47. arthexis-0.1.17/config/middleware.py +0 -25
  48. arthexis-0.1.17/pyproject.toml +0 -26
  49. arthexis-0.1.17/tests/test_admin_system_stop.py +0 -63
  50. arthexis-0.1.17/tests/test_birthday_greetings.py +0 -30
  51. {arthexis-0.1.17 → arthexis-0.1.19}/LICENSE +0 -0
  52. {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/dependency_links.txt +0 -0
  53. {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/top_level.txt +0 -0
  54. {arthexis-0.1.17 → arthexis-0.1.19}/config/__init__.py +0 -0
  55. {arthexis-0.1.17 → arthexis-0.1.19}/config/active_app.py +0 -0
  56. {arthexis-0.1.17 → arthexis-0.1.19}/config/asgi.py +0 -0
  57. {arthexis-0.1.17 → arthexis-0.1.19}/config/auth_app.py +0 -0
  58. {arthexis-0.1.17 → arthexis-0.1.19}/config/celery.py +0 -0
  59. {arthexis-0.1.17 → arthexis-0.1.19}/config/context_processors.py +0 -0
  60. {arthexis-0.1.17 → arthexis-0.1.19}/config/horologia_app.py +0 -0
  61. {arthexis-0.1.17 → arthexis-0.1.19}/config/loadenv.py +0 -0
  62. {arthexis-0.1.17 → arthexis-0.1.19}/config/logging.py +0 -0
  63. {arthexis-0.1.17 → arthexis-0.1.19}/config/offline.py +0 -0
  64. {arthexis-0.1.17 → arthexis-0.1.19}/config/settings_helpers.py +0 -0
  65. {arthexis-0.1.17 → arthexis-0.1.19}/config/wsgi.py +0 -0
  66. {arthexis-0.1.17 → arthexis-0.1.19}/core/__init__.py +0 -0
  67. {arthexis-0.1.17 → arthexis-0.1.19}/core/admin_history.py +0 -0
  68. {arthexis-0.1.17 → arthexis-0.1.19}/core/admindocs.py +0 -0
  69. {arthexis-0.1.17 → arthexis-0.1.19}/core/apps.py +0 -0
  70. {arthexis-0.1.17 → arthexis-0.1.19}/core/auto_upgrade.py +0 -0
  71. {arthexis-0.1.17 → arthexis-0.1.19}/core/backends.py +0 -0
  72. {arthexis-0.1.17 → arthexis-0.1.19}/core/changelog.py +0 -0
  73. {arthexis-0.1.17 → arthexis-0.1.19}/core/entity.py +0 -0
  74. {arthexis-0.1.17 → arthexis-0.1.19}/core/environment.py +0 -0
  75. {arthexis-0.1.17 → arthexis-0.1.19}/core/fields.py +0 -0
  76. {arthexis-0.1.17 → arthexis-0.1.19}/core/form_fields.py +0 -0
  77. {arthexis-0.1.17 → arthexis-0.1.19}/core/github_helper.py +0 -0
  78. {arthexis-0.1.17 → arthexis-0.1.19}/core/github_issues.py +0 -0
  79. {arthexis-0.1.17 → arthexis-0.1.19}/core/github_repos.py +0 -0
  80. {arthexis-0.1.17 → arthexis-0.1.19}/core/lcd_screen.py +0 -0
  81. {arthexis-0.1.17 → arthexis-0.1.19}/core/liveupdate.py +0 -0
  82. {arthexis-0.1.17 → arthexis-0.1.19}/core/log_paths.py +0 -0
  83. {arthexis-0.1.17 → arthexis-0.1.19}/core/mailer.py +0 -0
  84. {arthexis-0.1.17 → arthexis-0.1.19}/core/middleware.py +0 -0
  85. {arthexis-0.1.17 → arthexis-0.1.19}/core/notifications.py +0 -0
  86. {arthexis-0.1.17 → arthexis-0.1.19}/core/public_wifi.py +0 -0
  87. {arthexis-0.1.17 → arthexis-0.1.19}/core/reference_utils.py +0 -0
  88. {arthexis-0.1.17 → arthexis-0.1.19}/core/release.py +0 -0
  89. {arthexis-0.1.17 → arthexis-0.1.19}/core/rfid_import_export.py +0 -0
  90. {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_builder.py +0 -0
  91. {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_context.py +0 -0
  92. {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_resolver.py +0 -0
  93. {arthexis-0.1.17 → arthexis-0.1.19}/core/temp_passwords.py +0 -0
  94. {arthexis-0.1.17 → arthexis-0.1.19}/core/test_system_info.py +0 -0
  95. {arthexis-0.1.17 → arthexis-0.1.19}/core/tests_liveupdate.py +0 -0
  96. {arthexis-0.1.17 → arthexis-0.1.19}/core/urls.py +0 -0
  97. {arthexis-0.1.17 → arthexis-0.1.19}/core/user_data.py +0 -0
  98. {arthexis-0.1.17 → arthexis-0.1.19}/core/widgets.py +0 -0
  99. {arthexis-0.1.17 → arthexis-0.1.19}/core/workgroup_urls.py +0 -0
  100. {arthexis-0.1.17 → arthexis-0.1.19}/core/workgroup_views.py +0 -0
  101. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/__init__.py +0 -0
  102. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/apps.py +0 -0
  103. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/backends.py +0 -0
  104. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/dns.py +0 -0
  105. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/feature_checks.py +0 -0
  106. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/lcd.py +0 -0
  107. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/reports.py +0 -0
  108. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/rfid_sync.py +0 -0
  109. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/signals.py +0 -0
  110. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/tasks.py +0 -0
  111. {arthexis-0.1.17 → arthexis-0.1.19}/nodes/utils.py +0 -0
  112. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/__init__.py +0 -0
  113. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/apps.py +0 -0
  114. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/evcs.py +0 -0
  115. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/evcs_discovery.py +0 -0
  116. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/reference_utils.py +0 -0
  117. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/routing.py +0 -0
  118. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/simulator.py +0 -0
  119. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/status_display.py +0 -0
  120. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/tasks.py +0 -0
  121. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/test_export_import.py +0 -0
  122. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/transactions_io.py +0 -0
  123. {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/urls.py +0 -0
  124. {arthexis-0.1.17 → arthexis-0.1.19}/pages/__init__.py +0 -0
  125. {arthexis-0.1.17 → arthexis-0.1.19}/pages/checks.py +0 -0
  126. {arthexis-0.1.17 → arthexis-0.1.19}/pages/defaults.py +0 -0
  127. {arthexis-0.1.17 → arthexis-0.1.19}/pages/forms.py +0 -0
  128. {arthexis-0.1.17 → arthexis-0.1.19}/pages/module_defaults.py +0 -0
  129. {arthexis-0.1.17 → arthexis-0.1.19}/pages/tasks.py +0 -0
  130. {arthexis-0.1.17 → arthexis-0.1.19}/pages/utils.py +0 -0
  131. {arthexis-0.1.17 → arthexis-0.1.19}/setup.cfg +0 -0
  132. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_acronym_capitalization.py +0 -0
  133. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_doc_commands.py +0 -0
  134. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_doc_model_groups.py +0 -0
  135. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_history.py +0 -0
  136. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_index_actions.py +0 -0
  137. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_model_graph.py +0 -0
  138. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_object_history.py +0 -0
  139. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_profile_link.py +0 -0
  140. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_allowed_hosts_hostname.py +0 -0
  141. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_api_login_required.py +0 -0
  142. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_data_api.py +0 -0
  143. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_profile_admin.py +0 -0
  144. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_profile_api.py +0 -0
  145. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_auto_upgrade_scheduler.py +0 -0
  146. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_awg_admin.py +0 -0
  147. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_benchmark_command.py +0 -0
  148. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_build_pypi_command.py +0 -0
  149. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_celery_no_debug.py +0 -0
  150. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_changelog_builder.py +0 -0
  151. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_admin_command.py +0 -0
  152. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_migrations_script.py +0 -0
  153. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_pypi_command.py +0 -0
  154. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_clean_release_logs_command.py +0 -0
  155. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_client_report_schedule.py +0 -0
  156. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_csrf_failure.py +0 -0
  157. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_csrf_origin_subnet.py +0 -0
  158. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_dist_cleanup.py +0 -0
  159. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_collector.py +0 -0
  160. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox.py +0 -0
  161. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox_admin.py +0 -0
  162. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox_search_action.py +0 -0
  163. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_outbox_admin.py +0 -0
  164. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_profiles.py +0 -0
  165. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_transaction.py +0 -0
  166. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_clean.py +0 -0
  167. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_pip.py +0 -0
  168. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_unlink.py +0 -0
  169. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_experience_admin_group.py +0 -0
  170. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_fixture_presence.py +0 -0
  171. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_no_references.py +0 -0
  172. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_presence.py +0 -0
  173. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_render.py +0 -0
  174. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_git_checks.py +0 -0
  175. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_github_issue_reporting.py +0 -0
  176. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_install_script.py +0 -0
  177. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_language_switch.py +0 -0
  178. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_lcd_check_command.py +0 -0
  179. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_lcd_smbus2.py +0 -0
  180. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_localhost_admin_backend.py +0 -0
  181. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_log_paths.py +0 -0
  182. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_login_view_no_site.py +0 -0
  183. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_manage_debug_flag.py +0 -0
  184. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_manuals.py +0 -0
  185. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_asgi.py +0 -0
  186. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_auto_start.py +0 -0
  187. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_process.py +0 -0
  188. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_sigil_server.py +0 -0
  189. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_sigil_server_command.py +0 -0
  190. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_message_command.py +0 -0
  191. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_migrations.py +0 -0
  192. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_model_verbose_name_capitalization.py +0 -0
  193. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_network_setup_interactive.py +0 -0
  194. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_notifications_fallback.py +0 -0
  195. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_notify_command.py +0 -0
  196. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_ocpp_session_lock.py +0 -0
  197. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_product.py +0 -0
  198. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_profile.py +0 -0
  199. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_profile_admin.py +0 -0
  200. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_quote_report.py +0 -0
  201. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_offline.py +0 -0
  202. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_package_admin_next_release.py +0 -0
  203. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_power_admin_group.py +0 -0
  204. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_profile_inline_deletion.py +0 -0
  205. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_pypi_check.py +0 -0
  206. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_pypi_token.py +0 -0
  207. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_readme_language.py +0 -0
  208. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_reference_qr_code.py +0 -0
  209. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_reference_transaction_uuid.py +0 -0
  210. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_register_site_apps_command.py +0 -0
  211. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_build.py +0 -0
  212. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_build_flow.py +0 -0
  213. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_checklist.py +0 -0
  214. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_logs.py +0 -0
  215. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_manager_admin.py +0 -0
  216. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_packages.py +0 -0
  217. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_progress_pre_release_integration.py +0 -0
  218. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_push.py +0 -0
  219. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_tasks.py +0 -0
  220. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_request_invite.py +0 -0
  221. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_print_labels.py +0 -0
  222. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_reference_clear.py +0 -0
  223. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_scan_csrf.py +0 -0
  224. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_always_on.py +0 -0
  225. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_backend.py +0 -0
  226. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_background_reader.py +0 -0
  227. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_client_report.py +0 -0
  228. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_watch_command.py +0 -0
  229. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_role_marker_filtering.py +0 -0
  230. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_send_invite_command.py +0 -0
  231. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_settings_helpers.py +0 -0
  232. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_shell_scripts.py +0 -0
  233. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_show_leads_command.py +0 -0
  234. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sigil_builder.py +0 -0
  235. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sigil_resolution.py +0 -0
  236. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sites_utils.py +0 -0
  237. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_social_profile.py +0 -0
  238. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_staff_login_net_message.py +0 -0
  239. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_staff_required_decorator.py +0 -0
  240. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_switch_role_script.py +0 -0
  241. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_system_changelog_report.py +0 -0
  242. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_totp_admin.py +0 -0
  243. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_totp_backend.py +0 -0
  244. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_uninstall_script.py +0 -0
  245. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_update_fixtures_command.py +0 -0
  246. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_upgrade_report.py +0 -0
  247. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_urls_autodiscover.py +0 -0
  248. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_user_data_admin.py +0 -0
  249. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_version_endpoint.py +0 -0
  250. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_version_file.py +0 -0
  251. {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_vscode_manage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arthexis
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  Summary: Power & Energy Infrastructure
5
5
  Author-email: "Rafael J. Guillén-Osorio" <tecnologia@gelectriic.com>
6
6
  License-Expression: GPL-3.0-only
@@ -15,7 +15,7 @@ Requires-Dist: amqp==5.3.1
15
15
  Requires-Dist: annotated-types==0.7.0
16
16
  Requires-Dist: anyio==4.9.0
17
17
  Requires-Dist: asgiref==3.10.0
18
- Requires-Dist: atproto==0.0.61
18
+ Requires-Dist: atproto==0.0.62
19
19
  Requires-Dist: attrs==25.3.0
20
20
  Requires-Dist: autobahn==24.4.2
21
21
  Requires-Dist: Automat==25.4.16
@@ -41,7 +41,7 @@ Requires-Dist: defusedxml==0.7.1
41
41
  Requires-Dist: Django==5.2.7
42
42
  Requires-Dist: django-celery-beat==2.8.1
43
43
  Requires-Dist: django-debug-toolbar==6.0.0
44
- Requires-Dist: django-import-export==4.3.9
44
+ Requires-Dist: django-import-export==4.3.12
45
45
  Requires-Dist: django-object-actions==5.0.0
46
46
  Requires-Dist: django-otp==1.5.4
47
47
  Requires-Dist: django-timezone-field==7.1
@@ -53,28 +53,28 @@ Requires-Dist: h11==0.16.0
53
53
  Requires-Dist: httpcore==1.0.9
54
54
  Requires-Dist: httpx==0.28.1
55
55
  Requires-Dist: hyperlink==21.0.0
56
- Requires-Dist: idna==3.10
56
+ Requires-Dist: idna==3.11
57
57
  Requires-Dist: incremental==24.7.2
58
58
  Requires-Dist: kombu==5.5.4
59
59
  Requires-Dist: libipld==3.1.1
60
60
  Requires-Dist: Markdown==3.8.2
61
61
  Requires-Dist: mdx_truly_sane_lists==1.3
62
- Requires-Dist: mcp==1.16.0
62
+ Requires-Dist: mcp==1.18.0
63
63
  Requires-Dist: mfrc522==0.0.7; sys_platform == "linux"
64
64
  Requires-Dist: outcome==1.3.0.post0
65
65
  Requires-Dist: packaging==25.0
66
66
  Requires-Dist: pillow==11.3.0
67
67
  Requires-Dist: prompt_toolkit==3.0.51
68
- Requires-Dist: psutil==5.9.8
68
+ Requires-Dist: psutil==7.1.1
69
69
  Requires-Dist: psycopg==3.2.9
70
- Requires-Dist: psycopg-binary==3.2.9
70
+ Requires-Dist: psycopg-binary==3.2.11
71
71
  Requires-Dist: pyasn1==0.6.1
72
72
  Requires-Dist: pyasn1_modules==0.4.2
73
73
  Requires-Dist: pycparser==2.22
74
74
  Requires-Dist: pydantic==2.11.7
75
75
  Requires-Dist: pydantic_core==2.33.2
76
76
  Requires-Dist: pyOpenSSL==25.1.0
77
- Requires-Dist: pyperclip==1.9.0
77
+ Requires-Dist: pyperclip==1.11.0
78
78
  Requires-Dist: PySocks==1.7.1
79
79
  Requires-Dist: python-crontab==3.3.0
80
80
  Requires-Dist: python-dateutil==2.9.0.post0
@@ -99,7 +99,7 @@ Requires-Dist: trio-websocket==0.12.2
99
99
  Requires-Dist: Twisted==25.5.0
100
100
  Requires-Dist: twine==6.1.0
101
101
  Requires-Dist: txaio==25.6.1
102
- Requires-Dist: typing-inspection==0.4.1
102
+ Requires-Dist: typing-inspection==0.4.2
103
103
  Requires-Dist: typing_extensions==4.14.1
104
104
  Requires-Dist: tzdata==2025.2
105
105
  Requires-Dist: urllib3==2.5.0
@@ -108,7 +108,7 @@ Requires-Dist: wcwidth==0.2.13
108
108
  Requires-Dist: webencodings==0.5.1
109
109
  Requires-Dist: websocket-client==1.8.0
110
110
  Requires-Dist: websockets==13.1
111
- Requires-Dist: whitenoise==6.9.0
111
+ Requires-Dist: whitenoise==6.11.0
112
112
  Requires-Dist: plyer==2.1.0; sys_platform == "win32"
113
113
  Requires-Dist: wsproto==1.2.0
114
114
  Requires-Dist: zope.interface==7.2
@@ -212,10 +212,37 @@ Terminal nodes can start directly with the scripts below without installing; Con
212
212
  ### 4. Administration
213
213
  Visit [`http://localhost:8000/admin/`](http://localhost:8000/admin/) for the [Django admin](https://docs.djangoproject.com/en/stable/ref/contrib/admin/) and [`http://localhost:8000/admindocs/`](http://localhost:8000/admindocs/) for the [admindocs](https://docs.djangoproject.com/en/stable/ref/contrib/admin/admindocs/). Use `--port` with the start scripts or installer when you need to expose a different port.
214
214
 
215
+ ## Sigils
216
+
217
+ Sigils are bracketed tokens such as `[ENV.SMTP_PASSWORD]` that Arthexis expands at runtime. They make it possible to reference configuration secrets, system metadata, or records stored in other apps without duplicating values across the project.
218
+
219
+ ### Syntax at a glance
220
+
221
+ - `[PREFIX.KEY]` &mdash; returns a field or attribute. Hyphens and casing are normalized automatically.
222
+ - `[PREFIX=IDENTIFIER.FIELD]` &mdash; selects a specific record by primary key or any unique field.
223
+ - `[PREFIX:FIELD=VALUE.ATTRIBUTE]` &mdash; filters by a custom field instead of the primary key.
224
+ - `[PREFIX.FIELD=[OTHER.SIGIL]]` &mdash; nests sigils so the value after `=` resolves before the outer token.
225
+ - `[PREFIX]` &mdash; for entity prefixes, returns the serialized object in JSON; for configuration prefixes, resolves to an empty string when the key is missing.
226
+
227
+ The platform ships with three configuration prefixes:
228
+
229
+ - `ENV` reads environment variables.
230
+ - `CONF` reads Django settings.
231
+ - `SYS` exposes computed system information such as build metadata.
232
+
233
+ Additional prefixes are defined through **Sigil Roots**, which map a short code (for example `ROLE`, `ODOO`, or `USER`) to a Django model. You can review them from **Admin &rarr; Sigil Builder** (`/admin/sigil-builder/`), where a test console is also available.
234
+
235
+ Unknown prefixes remain in place (e.g. `[UNKNOWN.VALUE]`) and are logged. When the optional `gway` CLI is installed, the resolver will attempt to delegate unresolved tokens to it before falling back to the original text.
236
+
215
237
  ## Support
216
238
 
217
239
  Contact us at [tecnologia@gelectriic.com](mailto:tecnologia@gelectriic.com) or visit our [web page](https://www.gelectriic.com/) for [professional services](https://en.wikipedia.org/wiki/Professional_services) and [commercial support](https://en.wikipedia.org/wiki/Technical_support).
218
240
 
241
+ ## Project Guidelines
242
+
243
+ - [AGENTS](AGENTS.md) – operating handbook for repository workflows, testing, and release management.
244
+ - [DESIGN](DESIGN.md) – visual, UX, and branding guidance that all interfaces must follow.
245
+
219
246
  ## About Me
220
247
 
221
248
  > "What, you want to know about me too? Well, I enjoy [developing software](https://en.wikipedia.org/wiki/Software_development), [role-playing games](https://en.wikipedia.org/wiki/Role-playing_game), long walks on the [beach](https://en.wikipedia.org/wiki/Beach) and a fourth secret thing."
@@ -96,10 +96,37 @@ Terminal nodes can start directly with the scripts below without installing; Con
96
96
  ### 4. Administration
97
97
  Visit [`http://localhost:8000/admin/`](http://localhost:8000/admin/) for the [Django admin](https://docs.djangoproject.com/en/stable/ref/contrib/admin/) and [`http://localhost:8000/admindocs/`](http://localhost:8000/admindocs/) for the [admindocs](https://docs.djangoproject.com/en/stable/ref/contrib/admin/admindocs/). Use `--port` with the start scripts or installer when you need to expose a different port.
98
98
 
99
+ ## Sigils
100
+
101
+ Sigils are bracketed tokens such as `[ENV.SMTP_PASSWORD]` that Arthexis expands at runtime. They make it possible to reference configuration secrets, system metadata, or records stored in other apps without duplicating values across the project.
102
+
103
+ ### Syntax at a glance
104
+
105
+ - `[PREFIX.KEY]` &mdash; returns a field or attribute. Hyphens and casing are normalized automatically.
106
+ - `[PREFIX=IDENTIFIER.FIELD]` &mdash; selects a specific record by primary key or any unique field.
107
+ - `[PREFIX:FIELD=VALUE.ATTRIBUTE]` &mdash; filters by a custom field instead of the primary key.
108
+ - `[PREFIX.FIELD=[OTHER.SIGIL]]` &mdash; nests sigils so the value after `=` resolves before the outer token.
109
+ - `[PREFIX]` &mdash; for entity prefixes, returns the serialized object in JSON; for configuration prefixes, resolves to an empty string when the key is missing.
110
+
111
+ The platform ships with three configuration prefixes:
112
+
113
+ - `ENV` reads environment variables.
114
+ - `CONF` reads Django settings.
115
+ - `SYS` exposes computed system information such as build metadata.
116
+
117
+ Additional prefixes are defined through **Sigil Roots**, which map a short code (for example `ROLE`, `ODOO`, or `USER`) to a Django model. You can review them from **Admin &rarr; Sigil Builder** (`/admin/sigil-builder/`), where a test console is also available.
118
+
119
+ Unknown prefixes remain in place (e.g. `[UNKNOWN.VALUE]`) and are logged. When the optional `gway` CLI is installed, the resolver will attempt to delegate unresolved tokens to it before falling back to the original text.
120
+
99
121
  ## Support
100
122
 
101
123
  Contact us at [tecnologia@gelectriic.com](mailto:tecnologia@gelectriic.com) or visit our [web page](https://www.gelectriic.com/) for [professional services](https://en.wikipedia.org/wiki/Professional_services) and [commercial support](https://en.wikipedia.org/wiki/Technical_support).
102
124
 
125
+ ## Project Guidelines
126
+
127
+ - [AGENTS](AGENTS.md) – operating handbook for repository workflows, testing, and release management.
128
+ - [DESIGN](DESIGN.md) – visual, UX, and branding guidance that all interfaces must follow.
129
+
103
130
  ## About Me
104
131
 
105
132
  > "What, you want to know about me too? Well, I enjoy [developing software](https://en.wikipedia.org/wiki/Software_development), [role-playing games](https://en.wikipedia.org/wiki/Role-playing_game), long walks on the [beach](https://en.wikipedia.org/wiki/Beach) and a fourth secret thing."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arthexis
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  Summary: Power & Energy Infrastructure
5
5
  Author-email: "Rafael J. Guillén-Osorio" <tecnologia@gelectriic.com>
6
6
  License-Expression: GPL-3.0-only
@@ -15,7 +15,7 @@ Requires-Dist: amqp==5.3.1
15
15
  Requires-Dist: annotated-types==0.7.0
16
16
  Requires-Dist: anyio==4.9.0
17
17
  Requires-Dist: asgiref==3.10.0
18
- Requires-Dist: atproto==0.0.61
18
+ Requires-Dist: atproto==0.0.62
19
19
  Requires-Dist: attrs==25.3.0
20
20
  Requires-Dist: autobahn==24.4.2
21
21
  Requires-Dist: Automat==25.4.16
@@ -41,7 +41,7 @@ Requires-Dist: defusedxml==0.7.1
41
41
  Requires-Dist: Django==5.2.7
42
42
  Requires-Dist: django-celery-beat==2.8.1
43
43
  Requires-Dist: django-debug-toolbar==6.0.0
44
- Requires-Dist: django-import-export==4.3.9
44
+ Requires-Dist: django-import-export==4.3.12
45
45
  Requires-Dist: django-object-actions==5.0.0
46
46
  Requires-Dist: django-otp==1.5.4
47
47
  Requires-Dist: django-timezone-field==7.1
@@ -53,28 +53,28 @@ Requires-Dist: h11==0.16.0
53
53
  Requires-Dist: httpcore==1.0.9
54
54
  Requires-Dist: httpx==0.28.1
55
55
  Requires-Dist: hyperlink==21.0.0
56
- Requires-Dist: idna==3.10
56
+ Requires-Dist: idna==3.11
57
57
  Requires-Dist: incremental==24.7.2
58
58
  Requires-Dist: kombu==5.5.4
59
59
  Requires-Dist: libipld==3.1.1
60
60
  Requires-Dist: Markdown==3.8.2
61
61
  Requires-Dist: mdx_truly_sane_lists==1.3
62
- Requires-Dist: mcp==1.16.0
62
+ Requires-Dist: mcp==1.18.0
63
63
  Requires-Dist: mfrc522==0.0.7; sys_platform == "linux"
64
64
  Requires-Dist: outcome==1.3.0.post0
65
65
  Requires-Dist: packaging==25.0
66
66
  Requires-Dist: pillow==11.3.0
67
67
  Requires-Dist: prompt_toolkit==3.0.51
68
- Requires-Dist: psutil==5.9.8
68
+ Requires-Dist: psutil==7.1.1
69
69
  Requires-Dist: psycopg==3.2.9
70
- Requires-Dist: psycopg-binary==3.2.9
70
+ Requires-Dist: psycopg-binary==3.2.11
71
71
  Requires-Dist: pyasn1==0.6.1
72
72
  Requires-Dist: pyasn1_modules==0.4.2
73
73
  Requires-Dist: pycparser==2.22
74
74
  Requires-Dist: pydantic==2.11.7
75
75
  Requires-Dist: pydantic_core==2.33.2
76
76
  Requires-Dist: pyOpenSSL==25.1.0
77
- Requires-Dist: pyperclip==1.9.0
77
+ Requires-Dist: pyperclip==1.11.0
78
78
  Requires-Dist: PySocks==1.7.1
79
79
  Requires-Dist: python-crontab==3.3.0
80
80
  Requires-Dist: python-dateutil==2.9.0.post0
@@ -99,7 +99,7 @@ Requires-Dist: trio-websocket==0.12.2
99
99
  Requires-Dist: Twisted==25.5.0
100
100
  Requires-Dist: twine==6.1.0
101
101
  Requires-Dist: txaio==25.6.1
102
- Requires-Dist: typing-inspection==0.4.1
102
+ Requires-Dist: typing-inspection==0.4.2
103
103
  Requires-Dist: typing_extensions==4.14.1
104
104
  Requires-Dist: tzdata==2025.2
105
105
  Requires-Dist: urllib3==2.5.0
@@ -108,7 +108,7 @@ Requires-Dist: wcwidth==0.2.13
108
108
  Requires-Dist: webencodings==0.5.1
109
109
  Requires-Dist: websocket-client==1.8.0
110
110
  Requires-Dist: websockets==13.1
111
- Requires-Dist: whitenoise==6.9.0
111
+ Requires-Dist: whitenoise==6.11.0
112
112
  Requires-Dist: plyer==2.1.0; sys_platform == "win32"
113
113
  Requires-Dist: wsproto==1.2.0
114
114
  Requires-Dist: zope.interface==7.2
@@ -212,10 +212,37 @@ Terminal nodes can start directly with the scripts below without installing; Con
212
212
  ### 4. Administration
213
213
  Visit [`http://localhost:8000/admin/`](http://localhost:8000/admin/) for the [Django admin](https://docs.djangoproject.com/en/stable/ref/contrib/admin/) and [`http://localhost:8000/admindocs/`](http://localhost:8000/admindocs/) for the [admindocs](https://docs.djangoproject.com/en/stable/ref/contrib/admin/admindocs/). Use `--port` with the start scripts or installer when you need to expose a different port.
214
214
 
215
+ ## Sigils
216
+
217
+ Sigils are bracketed tokens such as `[ENV.SMTP_PASSWORD]` that Arthexis expands at runtime. They make it possible to reference configuration secrets, system metadata, or records stored in other apps without duplicating values across the project.
218
+
219
+ ### Syntax at a glance
220
+
221
+ - `[PREFIX.KEY]` &mdash; returns a field or attribute. Hyphens and casing are normalized automatically.
222
+ - `[PREFIX=IDENTIFIER.FIELD]` &mdash; selects a specific record by primary key or any unique field.
223
+ - `[PREFIX:FIELD=VALUE.ATTRIBUTE]` &mdash; filters by a custom field instead of the primary key.
224
+ - `[PREFIX.FIELD=[OTHER.SIGIL]]` &mdash; nests sigils so the value after `=` resolves before the outer token.
225
+ - `[PREFIX]` &mdash; for entity prefixes, returns the serialized object in JSON; for configuration prefixes, resolves to an empty string when the key is missing.
226
+
227
+ The platform ships with three configuration prefixes:
228
+
229
+ - `ENV` reads environment variables.
230
+ - `CONF` reads Django settings.
231
+ - `SYS` exposes computed system information such as build metadata.
232
+
233
+ Additional prefixes are defined through **Sigil Roots**, which map a short code (for example `ROLE`, `ODOO`, or `USER`) to a Django model. You can review them from **Admin &rarr; Sigil Builder** (`/admin/sigil-builder/`), where a test console is also available.
234
+
235
+ Unknown prefixes remain in place (e.g. `[UNKNOWN.VALUE]`) and are logged. When the optional `gway` CLI is installed, the resolver will attempt to delegate unresolved tokens to it before falling back to the original text.
236
+
215
237
  ## Support
216
238
 
217
239
  Contact us at [tecnologia@gelectriic.com](mailto:tecnologia@gelectriic.com) or visit our [web page](https://www.gelectriic.com/) for [professional services](https://en.wikipedia.org/wiki/Professional_services) and [commercial support](https://en.wikipedia.org/wiki/Technical_support).
218
240
 
241
+ ## Project Guidelines
242
+
243
+ - [AGENTS](AGENTS.md) – operating handbook for repository workflows, testing, and release management.
244
+ - [DESIGN](DESIGN.md) – visual, UX, and branding guidance that all interfaces must follow.
245
+
219
246
  ## About Me
220
247
 
221
248
  > "What, you want to know about me too? Well, I enjoy [developing software](https://en.wikipedia.org/wiki/Software_development), [role-playing games](https://en.wikipedia.org/wiki/Role-playing_game), long walks on the [beach](https://en.wikipedia.org/wiki/Beach) and a fourth secret thing."
@@ -107,6 +107,7 @@ pages/forms.py
107
107
  pages/middleware.py
108
108
  pages/models.py
109
109
  pages/module_defaults.py
110
+ pages/site_config.py
110
111
  pages/tasks.py
111
112
  pages/tests.py
112
113
  pages/urls.py
@@ -130,7 +131,6 @@ tests/test_assistant_profile_api.py
130
131
  tests/test_auto_upgrade_scheduler.py
131
132
  tests/test_awg_admin.py
132
133
  tests/test_benchmark_command.py
133
- tests/test_birthday_greetings.py
134
134
  tests/test_build_pypi_command.py
135
135
  tests/test_celery_no_debug.py
136
136
  tests/test_changelog_builder.py
@@ -138,6 +138,7 @@ tests/test_check_admin_command.py
138
138
  tests/test_check_migrations_script.py
139
139
  tests/test_check_pypi_command.py
140
140
  tests/test_clean_release_logs_command.py
141
+ tests/test_client_report_form.py
141
142
  tests/test_client_report_generation.py
142
143
  tests/test_client_report_schedule.py
143
144
  tests/test_csrf_failure.py
@@ -207,6 +208,7 @@ tests/test_release_progress.py
207
208
  tests/test_release_progress_pre_release_integration.py
208
209
  tests/test_release_push.py
209
210
  tests/test_release_tasks.py
211
+ tests/test_render_nginx_sites.py
210
212
  tests/test_request_invite.py
211
213
  tests/test_rfid_admin_print_labels.py
212
214
  tests/test_rfid_admin_reference_clear.py
@@ -2,7 +2,7 @@ amqp==5.3.1
2
2
  annotated-types==0.7.0
3
3
  anyio==4.9.0
4
4
  asgiref==3.10.0
5
- atproto==0.0.61
5
+ atproto==0.0.62
6
6
  attrs==25.3.0
7
7
  autobahn==24.4.2
8
8
  Automat==25.4.16
@@ -28,7 +28,7 @@ defusedxml==0.7.1
28
28
  Django==5.2.7
29
29
  django-celery-beat==2.8.1
30
30
  django-debug-toolbar==6.0.0
31
- django-import-export==4.3.9
31
+ django-import-export==4.3.12
32
32
  django-object-actions==5.0.0
33
33
  django-otp==1.5.4
34
34
  django-timezone-field==7.1
@@ -39,27 +39,27 @@ h11==0.16.0
39
39
  httpcore==1.0.9
40
40
  httpx==0.28.1
41
41
  hyperlink==21.0.0
42
- idna==3.10
42
+ idna==3.11
43
43
  incremental==24.7.2
44
44
  kombu==5.5.4
45
45
  libipld==3.1.1
46
46
  Markdown==3.8.2
47
47
  mdx_truly_sane_lists==1.3
48
- mcp==1.16.0
48
+ mcp==1.18.0
49
49
  outcome==1.3.0.post0
50
50
  packaging==25.0
51
51
  pillow==11.3.0
52
52
  prompt_toolkit==3.0.51
53
- psutil==5.9.8
53
+ psutil==7.1.1
54
54
  psycopg==3.2.9
55
- psycopg-binary==3.2.9
55
+ psycopg-binary==3.2.11
56
56
  pyasn1==0.6.1
57
57
  pyasn1_modules==0.4.2
58
58
  pycparser==2.22
59
59
  pydantic==2.11.7
60
60
  pydantic_core==2.33.2
61
61
  pyOpenSSL==25.1.0
62
- pyperclip==1.9.0
62
+ pyperclip==1.11.0
63
63
  PySocks==1.7.1
64
64
  python-crontab==3.3.0
65
65
  python-dateutil==2.9.0.post0
@@ -84,7 +84,7 @@ trio-websocket==0.12.2
84
84
  Twisted==25.5.0
85
85
  twine==6.1.0
86
86
  txaio==25.6.1
87
- typing-inspection==0.4.1
87
+ typing-inspection==0.4.2
88
88
  typing_extensions==4.14.1
89
89
  tzdata==2025.2
90
90
  urllib3==2.5.0
@@ -93,7 +93,7 @@ wcwidth==0.2.13
93
93
  webencodings==0.5.1
94
94
  websocket-client==1.8.0
95
95
  websockets==13.1
96
- whitenoise==6.9.0
96
+ whitenoise==6.11.0
97
97
  wsproto==1.2.0
98
98
  zope.interface==7.2
99
99
 
@@ -0,0 +1,71 @@
1
+ import socket
2
+ from django.core.exceptions import DisallowedHost
3
+ from django.http import HttpResponsePermanentRedirect
4
+ from nodes.models import Node
5
+ from utils.sites import get_site
6
+
7
+ from .active_app import set_active_app
8
+
9
+
10
+ class ActiveAppMiddleware:
11
+ """Store the current app based on the request's site."""
12
+
13
+ def __init__(self, get_response):
14
+ self.get_response = get_response
15
+
16
+ def __call__(self, request):
17
+ site = get_site(request)
18
+ node = Node.get_local()
19
+ role_name = node.role.name if node and node.role else "Terminal"
20
+ active = site.name or role_name
21
+ set_active_app(active)
22
+ request.site = site
23
+ request.active_app = active
24
+ try:
25
+ response = self.get_response(request)
26
+ finally:
27
+ set_active_app(socket.gethostname())
28
+ return response
29
+
30
+
31
+ def _is_https_request(request) -> bool:
32
+ if request.is_secure():
33
+ return True
34
+
35
+ forwarded_proto = request.META.get("HTTP_X_FORWARDED_PROTO", "")
36
+ if forwarded_proto:
37
+ candidate = forwarded_proto.split(",")[0].strip().lower()
38
+ if candidate == "https":
39
+ return True
40
+
41
+ forwarded_header = request.META.get("HTTP_FORWARDED", "")
42
+ for forwarded_part in forwarded_header.split(","):
43
+ for element in forwarded_part.split(";"):
44
+ key, _, value = element.partition("=")
45
+ if key.strip().lower() == "proto" and value.strip().strip('"').lower() == "https":
46
+ return True
47
+
48
+ return False
49
+
50
+
51
+ class SiteHttpsRedirectMiddleware:
52
+ """Redirect HTTP traffic to HTTPS for sites that require it."""
53
+
54
+ def __init__(self, get_response):
55
+ self.get_response = get_response
56
+
57
+ def __call__(self, request):
58
+ site = getattr(request, "site", None)
59
+ if site is None:
60
+ site = get_site(request)
61
+ request.site = site
62
+
63
+ if getattr(site, "require_https", False) and not _is_https_request(request):
64
+ try:
65
+ host = request.get_host()
66
+ except DisallowedHost: # pragma: no cover - defensive guard
67
+ host = request.META.get("HTTP_HOST", "")
68
+ redirect_url = f"https://{host}{request.get_full_path()}"
69
+ return HttpResponsePermanentRedirect(redirect_url)
70
+
71
+ return self.get_response(request)
@@ -390,6 +390,7 @@ MIDDLEWARE = [
390
390
  "whitenoise.middleware.WhiteNoiseMiddleware",
391
391
  "django.contrib.sessions.middleware.SessionMiddleware",
392
392
  "config.middleware.ActiveAppMiddleware",
393
+ "config.middleware.SiteHttpsRedirectMiddleware",
393
394
  "django.middleware.locale.LocaleMiddleware",
394
395
  "django.middleware.common.CommonMiddleware",
395
396
  "django.middleware.csrf.CsrfViewMiddleware",
@@ -584,7 +585,7 @@ AUTH_PASSWORD_VALIDATORS = [
584
585
  LANGUAGE_CODE = "en-us"
585
586
 
586
587
  LANGUAGES = [
587
- ("es", _("Spanish")),
588
+ ("es", _("Spanish (Latin America)")),
588
589
  ("en", _("English")),
589
590
  ("it", _("Italian")),
590
591
  ("de", _("German")),
@@ -687,8 +688,4 @@ CELERY_BEAT_SCHEDULE = {
687
688
  "task": "core.tasks.heartbeat",
688
689
  "schedule": crontab(minute="*/5"),
689
690
  },
690
- "birthday_greetings": {
691
- "task": "core.tasks.birthday_greetings",
692
- "schedule": crontab(hour=9, minute=0),
693
- },
694
691
  }
@@ -149,6 +149,11 @@ urlpatterns = [
149
149
  core_views.odoo_quote_report,
150
150
  name="odoo-quote-report",
151
151
  ),
152
+ path(
153
+ "admin/request-temp-password/",
154
+ core_views.request_temp_password,
155
+ name="admin-request-temp-password",
156
+ ),
152
157
  path("admin/", admin.site.urls),
153
158
  path("i18n/setlang/", csrf_exempt(set_language), name="set_language"),
154
159
  path("api/", include("core.workgroup_urls")),
@@ -2947,7 +2947,7 @@ class RFIDAdmin(EntityModelAdmin, ImportExportModelAdmin):
2947
2947
  "toggle_selected_released",
2948
2948
  "toggle_selected_allowed",
2949
2949
  ]
2950
- readonly_fields = ("added_on", "last_seen_on")
2950
+ readonly_fields = ("added_on", "last_seen_on", "reversed_uid")
2951
2951
  form = RFIDForm
2952
2952
 
2953
2953
  def get_import_resource_kwargs(self, request, form=None, **kwargs):
@@ -1775,6 +1775,14 @@ class RFID(Entity):
1775
1775
  )
1776
1776
  ],
1777
1777
  )
1778
+ reversed_uid = models.CharField(
1779
+ max_length=255,
1780
+ default="",
1781
+ blank=True,
1782
+ editable=False,
1783
+ verbose_name="Reversed UID",
1784
+ help_text="UID value stored with opposite endianness for reference.",
1785
+ )
1778
1786
  custom_label = models.CharField(
1779
1787
  max_length=32,
1780
1788
  blank=True,
@@ -1906,7 +1914,16 @@ class RFID(Entity):
1906
1914
  if self.key_b and old["key_b"] != self.key_b.upper():
1907
1915
  self.key_b_verified = False
1908
1916
  if self.rfid:
1909
- self.rfid = self.rfid.upper()
1917
+ normalized_rfid = self.rfid.upper()
1918
+ self.rfid = normalized_rfid
1919
+ reversed_uid = self.reverse_uid(normalized_rfid)
1920
+ if reversed_uid != self.reversed_uid:
1921
+ self.reversed_uid = reversed_uid
1922
+ if update_fields:
1923
+ fields = set(update_fields)
1924
+ if "reversed_uid" not in fields:
1925
+ fields.add("reversed_uid")
1926
+ kwargs["update_fields"] = tuple(fields)
1910
1927
  if self.key_a:
1911
1928
  self.key_a = self.key_a.upper()
1912
1929
  if self.key_b:
@@ -1933,6 +1950,19 @@ class RFID(Entity):
1933
1950
  return candidate
1934
1951
  return cls.BIG_ENDIAN
1935
1952
 
1953
+ @staticmethod
1954
+ def reverse_uid(value: str) -> str:
1955
+ """Return ``value`` with reversed byte order for reference storage."""
1956
+
1957
+ normalized = "".join((value or "").split()).upper()
1958
+ if not normalized:
1959
+ return ""
1960
+ if len(normalized) % 2 != 0:
1961
+ return normalized[::-1]
1962
+ bytes_list = [normalized[index : index + 2] for index in range(0, len(normalized), 2)]
1963
+ bytes_list.reverse()
1964
+ return "".join(bytes_list)
1965
+
1936
1966
  @classmethod
1937
1967
  def next_scan_label(
1938
1968
  cls, *, step: int | None = None, start: int | None = None