arthexis 0.1.22__tar.gz → 0.1.23__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 (244) hide show
  1. {arthexis-0.1.22 → arthexis-0.1.23}/PKG-INFO +2 -1
  2. {arthexis-0.1.22 → arthexis-0.1.23}/README.md +1 -0
  3. {arthexis-0.1.22 → arthexis-0.1.23}/arthexis.egg-info/PKG-INFO +2 -1
  4. {arthexis-0.1.22 → arthexis-0.1.23}/arthexis.egg-info/SOURCES.txt +2 -0
  5. {arthexis-0.1.22 → arthexis-0.1.23}/core/admin.py +85 -13
  6. {arthexis-0.1.22 → arthexis-0.1.23}/core/models.py +484 -63
  7. {arthexis-0.1.22 → arthexis-0.1.23}/core/release.py +0 -5
  8. {arthexis-0.1.22 → arthexis-0.1.23}/core/tests.py +29 -1
  9. {arthexis-0.1.22 → arthexis-0.1.23}/core/user_data.py +42 -2
  10. {arthexis-0.1.22 → arthexis-0.1.23}/core/views.py +33 -26
  11. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/admin.py +64 -23
  12. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/models.py +9 -1
  13. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/tests.py +74 -0
  14. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/views.py +100 -48
  15. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/admin.py +12 -1
  16. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/models.py +29 -2
  17. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/tests.py +123 -0
  18. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/views.py +19 -3
  19. {arthexis-0.1.22 → arthexis-0.1.23}/pages/tests.py +25 -6
  20. {arthexis-0.1.22 → arthexis-0.1.23}/pages/urls.py +5 -0
  21. {arthexis-0.1.22 → arthexis-0.1.23}/pages/views.py +84 -8
  22. {arthexis-0.1.22 → arthexis-0.1.23}/pyproject.toml +1 -1
  23. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_client_report.py +44 -14
  24. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_client_report_generation.py +32 -9
  25. arthexis-0.1.23/tests/test_csrf_origin_subnet.py +138 -0
  26. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_fixture_presence.py +18 -6
  27. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_network_setup_interactive.py +3 -7
  28. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_power_admin_group.py +1 -1
  29. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_progress.py +45 -0
  30. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_seed_data.py +10 -5
  31. arthexis-0.1.23/tests/test_stop_script.py +44 -0
  32. arthexis-0.1.23/tests/test_transaction_meter_readings.py +113 -0
  33. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_uninstall_script.py +2 -2
  34. arthexis-0.1.22/tests/test_csrf_origin_subnet.py +0 -21
  35. {arthexis-0.1.22 → arthexis-0.1.23}/LICENSE +0 -0
  36. {arthexis-0.1.22 → arthexis-0.1.23}/arthexis.egg-info/dependency_links.txt +0 -0
  37. {arthexis-0.1.22 → arthexis-0.1.23}/arthexis.egg-info/requires.txt +0 -0
  38. {arthexis-0.1.22 → arthexis-0.1.23}/arthexis.egg-info/top_level.txt +0 -0
  39. {arthexis-0.1.22 → arthexis-0.1.23}/config/__init__.py +0 -0
  40. {arthexis-0.1.22 → arthexis-0.1.23}/config/active_app.py +0 -0
  41. {arthexis-0.1.22 → arthexis-0.1.23}/config/asgi.py +0 -0
  42. {arthexis-0.1.22 → arthexis-0.1.23}/config/auth_app.py +0 -0
  43. {arthexis-0.1.22 → arthexis-0.1.23}/config/celery.py +0 -0
  44. {arthexis-0.1.22 → arthexis-0.1.23}/config/context_processors.py +0 -0
  45. {arthexis-0.1.22 → arthexis-0.1.23}/config/horologia_app.py +0 -0
  46. {arthexis-0.1.22 → arthexis-0.1.23}/config/loadenv.py +0 -0
  47. {arthexis-0.1.22 → arthexis-0.1.23}/config/logging.py +0 -0
  48. {arthexis-0.1.22 → arthexis-0.1.23}/config/middleware.py +0 -0
  49. {arthexis-0.1.22 → arthexis-0.1.23}/config/offline.py +0 -0
  50. {arthexis-0.1.22 → arthexis-0.1.23}/config/settings.py +0 -0
  51. {arthexis-0.1.22 → arthexis-0.1.23}/config/settings_helpers.py +0 -0
  52. {arthexis-0.1.22 → arthexis-0.1.23}/config/urls.py +0 -0
  53. {arthexis-0.1.22 → arthexis-0.1.23}/config/wsgi.py +0 -0
  54. {arthexis-0.1.22 → arthexis-0.1.23}/core/__init__.py +0 -0
  55. {arthexis-0.1.22 → arthexis-0.1.23}/core/admin_history.py +0 -0
  56. {arthexis-0.1.22 → arthexis-0.1.23}/core/admindocs.py +0 -0
  57. {arthexis-0.1.22 → arthexis-0.1.23}/core/apps.py +0 -0
  58. {arthexis-0.1.22 → arthexis-0.1.23}/core/auto_upgrade.py +0 -0
  59. {arthexis-0.1.22 → arthexis-0.1.23}/core/backends.py +0 -0
  60. {arthexis-0.1.22 → arthexis-0.1.23}/core/changelog.py +0 -0
  61. {arthexis-0.1.22 → arthexis-0.1.23}/core/entity.py +0 -0
  62. {arthexis-0.1.22 → arthexis-0.1.23}/core/environment.py +0 -0
  63. {arthexis-0.1.22 → arthexis-0.1.23}/core/fields.py +0 -0
  64. {arthexis-0.1.22 → arthexis-0.1.23}/core/form_fields.py +0 -0
  65. {arthexis-0.1.22 → arthexis-0.1.23}/core/github_helper.py +0 -0
  66. {arthexis-0.1.22 → arthexis-0.1.23}/core/github_issues.py +0 -0
  67. {arthexis-0.1.22 → arthexis-0.1.23}/core/github_repos.py +0 -0
  68. {arthexis-0.1.22 → arthexis-0.1.23}/core/lcd_screen.py +0 -0
  69. {arthexis-0.1.22 → arthexis-0.1.23}/core/liveupdate.py +0 -0
  70. {arthexis-0.1.22 → arthexis-0.1.23}/core/log_paths.py +0 -0
  71. {arthexis-0.1.22 → arthexis-0.1.23}/core/mailer.py +0 -0
  72. {arthexis-0.1.22 → arthexis-0.1.23}/core/middleware.py +0 -0
  73. {arthexis-0.1.22 → arthexis-0.1.23}/core/notifications.py +0 -0
  74. {arthexis-0.1.22 → arthexis-0.1.23}/core/public_wifi.py +0 -0
  75. {arthexis-0.1.22 → arthexis-0.1.23}/core/reference_utils.py +0 -0
  76. {arthexis-0.1.22 → arthexis-0.1.23}/core/rfid_import_export.py +0 -0
  77. {arthexis-0.1.22 → arthexis-0.1.23}/core/sigil_builder.py +0 -0
  78. {arthexis-0.1.22 → arthexis-0.1.23}/core/sigil_context.py +0 -0
  79. {arthexis-0.1.22 → arthexis-0.1.23}/core/sigil_resolver.py +0 -0
  80. {arthexis-0.1.22 → arthexis-0.1.23}/core/system.py +0 -0
  81. {arthexis-0.1.22 → arthexis-0.1.23}/core/tasks.py +0 -0
  82. {arthexis-0.1.22 → arthexis-0.1.23}/core/temp_passwords.py +0 -0
  83. {arthexis-0.1.22 → arthexis-0.1.23}/core/test_system_info.py +0 -0
  84. {arthexis-0.1.22 → arthexis-0.1.23}/core/tests_liveupdate.py +0 -0
  85. {arthexis-0.1.22 → arthexis-0.1.23}/core/urls.py +0 -0
  86. {arthexis-0.1.22 → arthexis-0.1.23}/core/widgets.py +0 -0
  87. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/__init__.py +0 -0
  88. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/apps.py +0 -0
  89. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/backends.py +0 -0
  90. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/dns.py +0 -0
  91. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/feature_checks.py +0 -0
  92. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/lcd.py +0 -0
  93. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/reports.py +0 -0
  94. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/rfid_sync.py +0 -0
  95. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/signals.py +0 -0
  96. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/tasks.py +0 -0
  97. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/urls.py +0 -0
  98. {arthexis-0.1.22 → arthexis-0.1.23}/nodes/utils.py +0 -0
  99. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/__init__.py +0 -0
  100. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/apps.py +0 -0
  101. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/consumers.py +0 -0
  102. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/evcs.py +0 -0
  103. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/evcs_discovery.py +0 -0
  104. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/reference_utils.py +0 -0
  105. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/routing.py +0 -0
  106. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/simulator.py +0 -0
  107. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/status_display.py +0 -0
  108. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/store.py +0 -0
  109. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/tasks.py +0 -0
  110. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/test_export_import.py +0 -0
  111. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/test_rfid.py +0 -0
  112. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/transactions_io.py +0 -0
  113. {arthexis-0.1.22 → arthexis-0.1.23}/ocpp/urls.py +0 -0
  114. {arthexis-0.1.22 → arthexis-0.1.23}/pages/__init__.py +0 -0
  115. {arthexis-0.1.22 → arthexis-0.1.23}/pages/admin.py +0 -0
  116. {arthexis-0.1.22 → arthexis-0.1.23}/pages/apps.py +0 -0
  117. {arthexis-0.1.22 → arthexis-0.1.23}/pages/checks.py +0 -0
  118. {arthexis-0.1.22 → arthexis-0.1.23}/pages/context_processors.py +0 -0
  119. {arthexis-0.1.22 → arthexis-0.1.23}/pages/defaults.py +0 -0
  120. {arthexis-0.1.22 → arthexis-0.1.23}/pages/forms.py +0 -0
  121. {arthexis-0.1.22 → arthexis-0.1.23}/pages/middleware.py +0 -0
  122. {arthexis-0.1.22 → arthexis-0.1.23}/pages/models.py +0 -0
  123. {arthexis-0.1.22 → arthexis-0.1.23}/pages/module_defaults.py +0 -0
  124. {arthexis-0.1.22 → arthexis-0.1.23}/pages/site_config.py +0 -0
  125. {arthexis-0.1.22 → arthexis-0.1.23}/pages/tasks.py +0 -0
  126. {arthexis-0.1.22 → arthexis-0.1.23}/pages/utils.py +0 -0
  127. {arthexis-0.1.22 → arthexis-0.1.23}/setup.cfg +0 -0
  128. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_acronym_capitalization.py +0 -0
  129. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_doc_commands.py +0 -0
  130. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_doc_model_groups.py +0 -0
  131. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_history.py +0 -0
  132. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_index_actions.py +0 -0
  133. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_model_graph.py +0 -0
  134. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_object_history.py +0 -0
  135. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_profile_link.py +0 -0
  136. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_admin_system_stop.py +0 -0
  137. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_allowed_hosts_hostname.py +0 -0
  138. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_api_login_required.py +0 -0
  139. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_auto_upgrade_scheduler.py +0 -0
  140. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_awg_admin.py +0 -0
  141. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_benchmark_command.py +0 -0
  142. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_build_pypi_command.py +0 -0
  143. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_celery_no_debug.py +0 -0
  144. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_changelog_builder.py +0 -0
  145. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_check_admin_command.py +0 -0
  146. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_check_migrations_script.py +0 -0
  147. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_check_pypi_command.py +0 -0
  148. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_clean_release_logs_command.py +0 -0
  149. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_client_report_form.py +0 -0
  150. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_client_report_schedule.py +0 -0
  151. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_csrf_failure.py +0 -0
  152. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_dist_cleanup.py +0 -0
  153. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_collector.py +0 -0
  154. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_inbox.py +0 -0
  155. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_inbox_admin.py +0 -0
  156. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_inbox_search_action.py +0 -0
  157. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_outbox_admin.py +0 -0
  158. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_profiles.py +0 -0
  159. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_email_transaction.py +0 -0
  160. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_env_refresh_clean.py +0 -0
  161. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_env_refresh_pip.py +0 -0
  162. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_env_refresh_unlink.py +0 -0
  163. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_experience_admin_group.py +0 -0
  164. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_footer_no_references.py +0 -0
  165. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_footer_presence.py +0 -0
  166. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_footer_render.py +0 -0
  167. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_git_checks.py +0 -0
  168. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_github_issue_reporting.py +0 -0
  169. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_install_script.py +0 -0
  170. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_invitation_login_view.py +0 -0
  171. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_language_switch.py +0 -0
  172. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_lcd_check_command.py +0 -0
  173. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_lcd_smbus2.py +0 -0
  174. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_localhost_admin_backend.py +0 -0
  175. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_log_paths.py +0 -0
  176. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_login_view_no_site.py +0 -0
  177. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_manage_debug_flag.py +0 -0
  178. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_manuals.py +0 -0
  179. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_message_command.py +0 -0
  180. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_migrations.py +0 -0
  181. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_model_verbose_name_capitalization.py +0 -0
  182. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_node_info_view.py +0 -0
  183. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_notifications_fallback.py +0 -0
  184. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_notify_command.py +0 -0
  185. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_ocpp_session_lock.py +0 -0
  186. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_odoo_product.py +0 -0
  187. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_odoo_profile.py +0 -0
  188. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_odoo_profile_admin.py +0 -0
  189. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_odoo_quote_report.py +0 -0
  190. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_offline.py +0 -0
  191. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_package_admin_next_release.py +0 -0
  192. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_profile_inline_deletion.py +0 -0
  193. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_pypi_check.py +0 -0
  194. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_pypi_token.py +0 -0
  195. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_readme_assets.py +0 -0
  196. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_readme_editor.py +0 -0
  197. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_readme_language.py +0 -0
  198. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_reference_qr_code.py +0 -0
  199. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_reference_transaction_uuid.py +0 -0
  200. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_register_site_apps_command.py +0 -0
  201. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_build.py +0 -0
  202. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_build_flow.py +0 -0
  203. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_checklist.py +0 -0
  204. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_logs.py +0 -0
  205. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_manager_admin.py +0 -0
  206. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_packages.py +0 -0
  207. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_progress_pre_release_integration.py +0 -0
  208. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_push.py +0 -0
  209. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_release_tasks.py +0 -0
  210. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_render_nginx_sites.py +0 -0
  211. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_request_invite.py +0 -0
  212. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_admin_print_labels.py +0 -0
  213. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_admin_reference_clear.py +0 -0
  214. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_admin_scan_csrf.py +0 -0
  215. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_always_on.py +0 -0
  216. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_backend.py +0 -0
  217. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_background_reader.py +0 -0
  218. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_client_report.py +0 -0
  219. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_rfid_watch_command.py +0 -0
  220. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_role_marker_filtering.py +0 -0
  221. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_send_invite_command.py +0 -0
  222. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_settings_helpers.py +0 -0
  223. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_settings_mcp_port.py +0 -0
  224. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_shell_scripts.py +0 -0
  225. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_show_leads_command.py +0 -0
  226. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_sigil_builder.py +0 -0
  227. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_sigil_resolution.py +0 -0
  228. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_sites_utils.py +0 -0
  229. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_social_profile.py +0 -0
  230. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_staff_login_net_message.py +0 -0
  231. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_staff_required_decorator.py +0 -0
  232. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_suite_gateway.py +0 -0
  233. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_switch_role_script.py +0 -0
  234. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_system_changelog_report.py +0 -0
  235. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_temp_passwords.py +0 -0
  236. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_totp_admin.py +0 -0
  237. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_totp_backend.py +0 -0
  238. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_update_fixtures_command.py +0 -0
  239. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_upgrade_report.py +0 -0
  240. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_urls_autodiscover.py +0 -0
  241. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_user_data_admin.py +0 -0
  242. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_version_endpoint.py +0 -0
  243. {arthexis-0.1.22 → arthexis-0.1.23}/tests/test_version_file.py +0 -0
  244. {arthexis-0.1.22 → arthexis-0.1.23}/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.22
3
+ Version: 0.1.23
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
@@ -203,6 +203,7 @@ Terminal nodes can start directly with the scripts below without installing; Con
203
203
  - `--constellation` – enables the multi-user orchestration stack.
204
204
  - Use `./install.sh --help` to list every available flag if you need to customize the node beyond the role defaults.
205
205
  - Upgrade with [`./upgrade.sh`](upgrade.sh).
206
+ - Consult the [Install & Lifecycle Scripts Manual](docs/development/install-lifecycle-scripts-manual.md) for complete flag descriptions and operational notes.
206
207
 
207
208
  - **Windows:**
208
209
  - Run [`install.bat`](install.bat) to install (Terminal role) and [`upgrade.bat`](upgrade.bat) to upgrade.
@@ -88,6 +88,7 @@ Terminal nodes can start directly with the scripts below without installing; Con
88
88
  - `--constellation` – enables the multi-user orchestration stack.
89
89
  - Use `./install.sh --help` to list every available flag if you need to customize the node beyond the role defaults.
90
90
  - Upgrade with [`./upgrade.sh`](upgrade.sh).
91
+ - Consult the [Install & Lifecycle Scripts Manual](docs/development/install-lifecycle-scripts-manual.md) for complete flag descriptions and operational notes.
91
92
 
92
93
  - **Windows:**
93
94
  - Run [`install.bat`](install.bat) to install (Terminal role) and [`upgrade.bat`](upgrade.bat) to upgrade.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arthexis
3
- Version: 0.1.22
3
+ Version: 0.1.23
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
@@ -203,6 +203,7 @@ Terminal nodes can start directly with the scripts below without installing; Con
203
203
  - `--constellation` – enables the multi-user orchestration stack.
204
204
  - Use `./install.sh --help` to list every available flag if you need to customize the node beyond the role defaults.
205
205
  - Upgrade with [`./upgrade.sh`](upgrade.sh).
206
+ - Consult the [Install & Lifecycle Scripts Manual](docs/development/install-lifecycle-scripts-manual.md) for complete flag descriptions and operational notes.
206
207
 
207
208
  - **Windows:**
208
209
  - Run [`install.bat`](install.bat) to install (Terminal role) and [`upgrade.bat`](upgrade.bat) to upgrade.
@@ -223,12 +223,14 @@ tests/test_sites_utils.py
223
223
  tests/test_social_profile.py
224
224
  tests/test_staff_login_net_message.py
225
225
  tests/test_staff_required_decorator.py
226
+ tests/test_stop_script.py
226
227
  tests/test_suite_gateway.py
227
228
  tests/test_switch_role_script.py
228
229
  tests/test_system_changelog_report.py
229
230
  tests/test_temp_passwords.py
230
231
  tests/test_totp_admin.py
231
232
  tests/test_totp_backend.py
233
+ tests/test_transaction_meter_readings.py
232
234
  tests/test_uninstall_script.py
233
235
  tests/test_update_fixtures_command.py
234
236
  tests/test_upgrade_report.py
@@ -9,10 +9,13 @@ from django.urls import NoReverseMatch, path, reverse
9
9
  from urllib.parse import urlencode, urlparse
10
10
  from django.shortcuts import get_object_or_404, redirect, render
11
11
  from django.http import (
12
+ FileResponse,
13
+ Http404,
12
14
  HttpResponse,
13
15
  JsonResponse,
14
16
  HttpResponseBase,
15
17
  HttpResponseRedirect,
18
+ HttpResponseNotAllowed,
16
19
  )
17
20
  from django.template.response import TemplateResponse
18
21
  from django.conf import settings
@@ -606,15 +609,18 @@ class PackageAdmin(SaveBeforeChangeAction, EntityModelAdmin):
606
609
  change_actions = ["create_repository_action", "prepare_next_release_action"]
607
610
 
608
611
  def _prepare(self, request, package):
612
+ if request.method not in {"POST", "GET"}:
613
+ return HttpResponseNotAllowed(["GET", "POST"])
609
614
  from pathlib import Path
610
615
  from packaging.version import Version
611
616
 
612
617
  ver_file = Path("VERSION")
613
- repo_version = (
614
- Version(ver_file.read_text().strip())
615
- if ver_file.exists()
616
- else Version("0.0.0")
617
- )
618
+ if ver_file.exists():
619
+ raw_version = ver_file.read_text().strip()
620
+ cleaned_version = raw_version.rstrip("+") or "0.0.0"
621
+ repo_version = Version(cleaned_version)
622
+ else:
623
+ repo_version = Version("0.0.0")
618
624
 
619
625
  pypi_latest = Version("0.0.0")
620
626
  try:
@@ -3670,10 +3676,10 @@ class ClientReportAdmin(EntityModelAdmin):
3670
3676
  initial=ClientReportSchedule.PERIODICITY_NONE,
3671
3677
  help_text="Defines how often the report should be generated automatically.",
3672
3678
  )
3673
- disable_emails = forms.BooleanField(
3674
- label="Disable email delivery",
3679
+ enable_emails = forms.BooleanField(
3680
+ label="Enable email delivery",
3675
3681
  required=False,
3676
- help_text="Generate files without sending emails.",
3682
+ help_text="Send the report via email to the recipients listed above.",
3677
3683
  )
3678
3684
 
3679
3685
  def __init__(self, *args, request=None, **kwargs):
@@ -3737,6 +3743,11 @@ class ClientReportAdmin(EntityModelAdmin):
3737
3743
  self.admin_site.admin_view(self.generate_view),
3738
3744
  name="core_clientreport_generate",
3739
3745
  ),
3746
+ path(
3747
+ "download/<int:report_id>/",
3748
+ self.admin_site.admin_view(self.download_view),
3749
+ name="core_clientreport_download",
3750
+ ),
3740
3751
  ]
3741
3752
  return custom + urls
3742
3753
 
@@ -3744,16 +3755,20 @@ class ClientReportAdmin(EntityModelAdmin):
3744
3755
  form = self.ClientReportForm(request.POST or None, request=request)
3745
3756
  report = None
3746
3757
  schedule = None
3758
+ download_url = None
3747
3759
  if request.method == "POST" and form.is_valid():
3748
3760
  owner = form.cleaned_data.get("owner")
3749
3761
  if not owner and request.user.is_authenticated:
3750
3762
  owner = request.user
3763
+ enable_emails = form.cleaned_data.get("enable_emails", False)
3764
+ disable_emails = not enable_emails
3765
+ recipients = form.cleaned_data.get("destinations") if enable_emails else []
3751
3766
  report = ClientReport.generate(
3752
3767
  form.cleaned_data["start"],
3753
3768
  form.cleaned_data["end"],
3754
3769
  owner=owner,
3755
- recipients=form.cleaned_data.get("destinations"),
3756
- disable_emails=form.cleaned_data.get("disable_emails", False),
3770
+ recipients=recipients,
3771
+ disable_emails=disable_emails,
3757
3772
  )
3758
3773
  report.store_local_copy()
3759
3774
  recurrence = form.cleaned_data.get("recurrence")
@@ -3762,8 +3777,8 @@ class ClientReportAdmin(EntityModelAdmin):
3762
3777
  owner=owner,
3763
3778
  created_by=request.user if request.user.is_authenticated else None,
3764
3779
  periodicity=recurrence,
3765
- email_recipients=form.cleaned_data.get("destinations", []),
3766
- disable_emails=form.cleaned_data.get("disable_emails", False),
3780
+ email_recipients=recipients,
3781
+ disable_emails=disable_emails,
3767
3782
  )
3768
3783
  report.schedule = schedule
3769
3784
  report.save(update_fields=["schedule"])
@@ -3772,12 +3787,69 @@ class ClientReportAdmin(EntityModelAdmin):
3772
3787
  "Client report schedule created; future reports will be generated automatically.",
3773
3788
  messages.SUCCESS,
3774
3789
  )
3790
+ if disable_emails:
3791
+ self.message_user(
3792
+ request,
3793
+ "Consumer report generated. The download will begin automatically.",
3794
+ messages.SUCCESS,
3795
+ )
3796
+ redirect_url = f"{reverse('admin:core_clientreport_generate')}?download={report.pk}"
3797
+ return HttpResponseRedirect(redirect_url)
3798
+ download_param = request.GET.get("download")
3799
+ if download_param:
3800
+ try:
3801
+ download_report = ClientReport.objects.get(pk=download_param)
3802
+ except ClientReport.DoesNotExist:
3803
+ pass
3804
+ else:
3805
+ download_url = reverse(
3806
+ "admin:core_clientreport_download", args=[download_report.pk]
3807
+ )
3775
3808
  context = self.admin_site.each_context(request)
3776
- context.update({"form": form, "report": report, "schedule": schedule})
3809
+ context.update(
3810
+ {
3811
+ "form": form,
3812
+ "report": report,
3813
+ "schedule": schedule,
3814
+ "download_url": download_url,
3815
+ "previous_reports": self._build_report_history(request),
3816
+ }
3817
+ )
3777
3818
  return TemplateResponse(
3778
3819
  request, "admin/core/clientreport/generate.html", context
3779
3820
  )
3780
3821
 
3822
+ def download_view(self, request, report_id: int):
3823
+ report = get_object_or_404(ClientReport, pk=report_id)
3824
+ pdf_path = report.ensure_pdf()
3825
+ if not pdf_path.exists():
3826
+ raise Http404("Report file unavailable")
3827
+ filename = f"consumer-report-{report.start_date}-{report.end_date}.pdf"
3828
+ response = FileResponse(pdf_path.open("rb"), content_type="application/pdf")
3829
+ response["Content-Disposition"] = f'attachment; filename="{filename}"'
3830
+ return response
3831
+
3832
+ def _build_report_history(self, request):
3833
+ queryset = ClientReport.objects.order_by("-created_on")[:20]
3834
+ history = []
3835
+ for item in queryset:
3836
+ totals = item.rows_for_display.get("totals", {})
3837
+ history.append(
3838
+ {
3839
+ "instance": item,
3840
+ "download_url": reverse(
3841
+ "admin:core_clientreport_download", args=[item.pk]
3842
+ ),
3843
+ "email_enabled": not item.disable_emails,
3844
+ "recipients": item.recipients or [],
3845
+ "totals": {
3846
+ "total_kw": totals.get("total_kw", 0.0),
3847
+ "total_kw_period": totals.get("total_kw_period", 0.0),
3848
+ },
3849
+ }
3850
+ )
3851
+ return history
3852
+
3781
3853
 
3782
3854
  @admin.register(PackageRelease)
3783
3855
  class PackageReleaseAdmin(SaveBeforeChangeAction, EntityModelAdmin):