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.
- {arthexis-0.1.17 → arthexis-0.1.19}/PKG-INFO +37 -10
- {arthexis-0.1.17 → arthexis-0.1.19}/README.md +27 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/PKG-INFO +37 -10
- {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/SOURCES.txt +3 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/requires.txt +9 -9
- arthexis-0.1.19/config/middleware.py +71 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/settings.py +2 -5
- {arthexis-0.1.17 → arthexis-0.1.19}/config/urls.py +5 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/admin.py +1 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/core/models.py +31 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/core/system.py +125 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/tasks.py +0 -22
- {arthexis-0.1.17 → arthexis-0.1.19}/core/tests.py +9 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/views.py +87 -19
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/admin.py +1 -2
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/models.py +18 -23
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/tests.py +42 -34
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/urls.py +0 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/views.py +2 -15
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/admin.py +23 -2
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/consumers.py +63 -19
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/models.py +7 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/store.py +6 -4
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/test_rfid.py +70 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/tests.py +107 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/views.py +84 -10
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/admin.py +150 -15
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/apps.py +3 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/context_processors.py +11 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/middleware.py +3 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/models.py +35 -0
- arthexis-0.1.19/pages/site_config.py +137 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/tests.py +352 -30
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/urls.py +2 -1
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/views.py +70 -23
- arthexis-0.1.19/pyproject.toml +26 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_client_report.py +11 -0
- arthexis-0.1.19/tests/test_admin_system_stop.py +127 -0
- arthexis-0.1.19/tests/test_client_report_form.py +30 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_client_report_generation.py +33 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_invitation_login_view.py +28 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_node_info_view.py +20 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_progress.py +42 -0
- arthexis-0.1.19/tests/test_render_nginx_sites.py +72 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_seed_data.py +61 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_temp_passwords.py +30 -1
- arthexis-0.1.17/config/middleware.py +0 -25
- arthexis-0.1.17/pyproject.toml +0 -26
- arthexis-0.1.17/tests/test_admin_system_stop.py +0 -63
- arthexis-0.1.17/tests/test_birthday_greetings.py +0 -30
- {arthexis-0.1.17 → arthexis-0.1.19}/LICENSE +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/dependency_links.txt +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/arthexis.egg-info/top_level.txt +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/__init__.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/active_app.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/asgi.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/auth_app.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/celery.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/context_processors.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/horologia_app.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/loadenv.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/logging.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/offline.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/settings_helpers.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/config/wsgi.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/__init__.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/admin_history.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/admindocs.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/apps.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/auto_upgrade.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/backends.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/changelog.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/entity.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/environment.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/fields.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/form_fields.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/github_helper.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/github_issues.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/github_repos.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/lcd_screen.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/liveupdate.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/log_paths.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/mailer.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/middleware.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/notifications.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/public_wifi.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/reference_utils.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/release.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/rfid_import_export.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_builder.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_context.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/sigil_resolver.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/temp_passwords.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/test_system_info.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/tests_liveupdate.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/urls.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/user_data.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/widgets.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/workgroup_urls.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/core/workgroup_views.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/__init__.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/apps.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/backends.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/dns.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/feature_checks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/lcd.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/reports.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/rfid_sync.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/signals.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/tasks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/nodes/utils.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/__init__.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/apps.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/evcs.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/evcs_discovery.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/reference_utils.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/routing.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/simulator.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/status_display.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/tasks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/test_export_import.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/transactions_io.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/ocpp/urls.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/__init__.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/checks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/defaults.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/forms.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/module_defaults.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/tasks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/pages/utils.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/setup.cfg +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_acronym_capitalization.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_doc_commands.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_doc_model_groups.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_history.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_index_actions.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_model_graph.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_object_history.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_admin_profile_link.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_allowed_hosts_hostname.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_api_login_required.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_data_api.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_profile_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_assistant_profile_api.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_auto_upgrade_scheduler.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_awg_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_benchmark_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_build_pypi_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_celery_no_debug.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_changelog_builder.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_admin_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_migrations_script.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_check_pypi_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_clean_release_logs_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_client_report_schedule.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_csrf_failure.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_csrf_origin_subnet.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_dist_cleanup.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_collector.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_inbox_search_action.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_outbox_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_profiles.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_email_transaction.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_clean.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_pip.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_env_refresh_unlink.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_experience_admin_group.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_fixture_presence.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_no_references.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_presence.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_footer_render.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_git_checks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_github_issue_reporting.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_install_script.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_language_switch.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_lcd_check_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_lcd_smbus2.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_localhost_admin_backend.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_log_paths.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_login_view_no_site.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_manage_debug_flag.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_manuals.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_asgi.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_auto_start.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_process.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_sigil_server.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_mcp_sigil_server_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_message_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_migrations.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_model_verbose_name_capitalization.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_network_setup_interactive.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_notifications_fallback.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_notify_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_ocpp_session_lock.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_product.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_profile.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_profile_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_odoo_quote_report.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_offline.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_package_admin_next_release.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_power_admin_group.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_profile_inline_deletion.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_pypi_check.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_pypi_token.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_readme_language.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_reference_qr_code.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_reference_transaction_uuid.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_register_site_apps_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_build.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_build_flow.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_checklist.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_logs.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_manager_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_packages.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_progress_pre_release_integration.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_push.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_release_tasks.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_request_invite.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_print_labels.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_reference_clear.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_admin_scan_csrf.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_always_on.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_backend.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_background_reader.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_client_report.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_rfid_watch_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_role_marker_filtering.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_send_invite_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_settings_helpers.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_shell_scripts.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_show_leads_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sigil_builder.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sigil_resolution.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_sites_utils.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_social_profile.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_staff_login_net_message.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_staff_required_decorator.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_switch_role_script.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_system_changelog_report.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_totp_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_totp_backend.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_uninstall_script.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_update_fixtures_command.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_upgrade_report.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_urls_autodiscover.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_user_data_admin.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_version_endpoint.py +0 -0
- {arthexis-0.1.17 → arthexis-0.1.19}/tests/test_version_file.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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==
|
|
68
|
+
Requires-Dist: psutil==7.1.1
|
|
69
69
|
Requires-Dist: psycopg==3.2.9
|
|
70
|
-
Requires-Dist: psycopg-binary==3.2.
|
|
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.
|
|
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.
|
|
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.
|
|
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]` — returns a field or attribute. Hyphens and casing are normalized automatically.
|
|
222
|
+
- `[PREFIX=IDENTIFIER.FIELD]` — selects a specific record by primary key or any unique field.
|
|
223
|
+
- `[PREFIX:FIELD=VALUE.ATTRIBUTE]` — filters by a custom field instead of the primary key.
|
|
224
|
+
- `[PREFIX.FIELD=[OTHER.SIGIL]]` — nests sigils so the value after `=` resolves before the outer token.
|
|
225
|
+
- `[PREFIX]` — 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 → 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]` — returns a field or attribute. Hyphens and casing are normalized automatically.
|
|
106
|
+
- `[PREFIX=IDENTIFIER.FIELD]` — selects a specific record by primary key or any unique field.
|
|
107
|
+
- `[PREFIX:FIELD=VALUE.ATTRIBUTE]` — filters by a custom field instead of the primary key.
|
|
108
|
+
- `[PREFIX.FIELD=[OTHER.SIGIL]]` — nests sigils so the value after `=` resolves before the outer token.
|
|
109
|
+
- `[PREFIX]` — 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 → 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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==
|
|
68
|
+
Requires-Dist: psutil==7.1.1
|
|
69
69
|
Requires-Dist: psycopg==3.2.9
|
|
70
|
-
Requires-Dist: psycopg-binary==3.2.
|
|
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.
|
|
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.
|
|
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.
|
|
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]` — returns a field or attribute. Hyphens and casing are normalized automatically.
|
|
222
|
+
- `[PREFIX=IDENTIFIER.FIELD]` — selects a specific record by primary key or any unique field.
|
|
223
|
+
- `[PREFIX:FIELD=VALUE.ATTRIBUTE]` — filters by a custom field instead of the primary key.
|
|
224
|
+
- `[PREFIX.FIELD=[OTHER.SIGIL]]` — nests sigils so the value after `=` resolves before the outer token.
|
|
225
|
+
- `[PREFIX]` — 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 → 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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==
|
|
53
|
+
psutil==7.1.1
|
|
54
54
|
psycopg==3.2.9
|
|
55
|
-
psycopg-binary==3.2.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|