arthexis 0.1.21__tar.gz → 0.1.22__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.21 → arthexis-0.1.22}/PKG-INFO +8 -8
- {arthexis-0.1.21 → arthexis-0.1.22}/arthexis.egg-info/PKG-INFO +8 -8
- {arthexis-0.1.21 → arthexis-0.1.22}/arthexis.egg-info/SOURCES.txt +1 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/arthexis.egg-info/requires.txt +7 -7
- {arthexis-0.1.21 → arthexis-0.1.22}/config/settings.py +4 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/urls.py +5 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/admin.py +139 -19
- arthexis-0.1.22/core/environment.py +60 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/models.py +419 -2
- {arthexis-0.1.21 → arthexis-0.1.22}/core/system.py +76 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/tests.py +152 -8
- {arthexis-0.1.21 → arthexis-0.1.22}/core/views.py +35 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/admin.py +148 -38
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/apps.py +11 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/models.py +26 -6
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/tests.py +214 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/views.py +1 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/admin.py +20 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/consumers.py +1 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/models.py +23 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/tasks.py +99 -1
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/tests.py +227 -2
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/views.py +281 -3
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/admin.py +112 -15
- arthexis-0.1.22/pages/apps.py +45 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/forms.py +31 -8
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/models.py +42 -2
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/tests.py +361 -22
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/urls.py +5 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/views.py +264 -11
- {arthexis-0.1.21 → arthexis-0.1.22}/pyproject.toml +2 -2
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_system_stop.py +18 -3
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_odoo_product.py +36 -0
- arthexis-0.1.22/tests/test_readme_assets.py +87 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_shell_scripts.py +5 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_version_endpoint.py +15 -0
- arthexis-0.1.21/core/environment.py +0 -297
- arthexis-0.1.21/pages/apps.py +0 -13
- arthexis-0.1.21/tests/test_environment_network_setup_form.py +0 -39
- {arthexis-0.1.21 → arthexis-0.1.22}/LICENSE +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/README.md +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/arthexis.egg-info/dependency_links.txt +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/arthexis.egg-info/top_level.txt +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/__init__.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/active_app.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/asgi.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/auth_app.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/celery.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/context_processors.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/horologia_app.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/loadenv.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/logging.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/middleware.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/offline.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/settings_helpers.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/config/wsgi.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/__init__.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/admin_history.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/admindocs.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/apps.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/auto_upgrade.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/backends.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/changelog.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/entity.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/fields.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/form_fields.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/github_helper.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/github_issues.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/github_repos.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/lcd_screen.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/liveupdate.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/log_paths.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/mailer.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/middleware.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/notifications.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/public_wifi.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/reference_utils.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/release.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/rfid_import_export.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/sigil_builder.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/sigil_context.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/sigil_resolver.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/tasks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/temp_passwords.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/test_system_info.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/tests_liveupdate.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/urls.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/user_data.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/core/widgets.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/__init__.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/backends.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/dns.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/feature_checks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/lcd.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/reports.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/rfid_sync.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/signals.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/tasks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/urls.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/nodes/utils.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/__init__.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/apps.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/evcs.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/evcs_discovery.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/reference_utils.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/routing.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/simulator.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/status_display.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/store.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/test_export_import.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/test_rfid.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/transactions_io.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/ocpp/urls.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/__init__.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/checks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/context_processors.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/defaults.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/middleware.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/module_defaults.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/site_config.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/tasks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/pages/utils.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/setup.cfg +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_acronym_capitalization.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_client_report.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_doc_commands.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_doc_model_groups.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_history.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_index_actions.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_model_graph.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_object_history.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_admin_profile_link.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_allowed_hosts_hostname.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_api_login_required.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_auto_upgrade_scheduler.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_awg_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_benchmark_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_build_pypi_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_celery_no_debug.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_changelog_builder.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_check_admin_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_check_migrations_script.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_check_pypi_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_clean_release_logs_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_client_report_form.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_client_report_generation.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_client_report_schedule.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_csrf_failure.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_csrf_origin_subnet.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_dist_cleanup.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_collector.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_inbox.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_inbox_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_inbox_search_action.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_outbox_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_profiles.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_email_transaction.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_env_refresh_clean.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_env_refresh_pip.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_env_refresh_unlink.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_experience_admin_group.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_fixture_presence.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_footer_no_references.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_footer_presence.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_footer_render.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_git_checks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_github_issue_reporting.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_install_script.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_invitation_login_view.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_language_switch.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_lcd_check_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_lcd_smbus2.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_localhost_admin_backend.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_log_paths.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_login_view_no_site.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_manage_debug_flag.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_manuals.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_message_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_migrations.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_model_verbose_name_capitalization.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_network_setup_interactive.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_node_info_view.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_notifications_fallback.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_notify_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_ocpp_session_lock.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_odoo_profile.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_odoo_profile_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_odoo_quote_report.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_offline.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_package_admin_next_release.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_power_admin_group.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_profile_inline_deletion.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_pypi_check.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_pypi_token.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_readme_editor.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_readme_language.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_reference_qr_code.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_reference_transaction_uuid.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_register_site_apps_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_build.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_build_flow.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_checklist.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_logs.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_manager_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_packages.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_progress.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_progress_pre_release_integration.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_push.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_release_tasks.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_render_nginx_sites.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_request_invite.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_admin_print_labels.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_admin_reference_clear.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_admin_scan_csrf.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_always_on.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_backend.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_background_reader.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_client_report.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_rfid_watch_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_role_marker_filtering.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_seed_data.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_send_invite_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_settings_helpers.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_settings_mcp_port.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_show_leads_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_sigil_builder.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_sigil_resolution.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_sites_utils.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_social_profile.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_staff_login_net_message.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_staff_required_decorator.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_suite_gateway.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_switch_role_script.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_system_changelog_report.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_temp_passwords.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_totp_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_totp_backend.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_uninstall_script.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_update_fixtures_command.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_upgrade_report.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_urls_autodiscover.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_user_data_admin.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/tests/test_version_file.py +0 -0
- {arthexis-0.1.21 → arthexis-0.1.22}/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.22
|
|
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
|
|
@@ -26,14 +26,14 @@ Requires-Dist: celery==5.5.3
|
|
|
26
26
|
Requires-Dist: certifi==2025.7.14
|
|
27
27
|
Requires-Dist: cffi==2.0.0
|
|
28
28
|
Requires-Dist: channels==4.1.0
|
|
29
|
-
Requires-Dist: charset-normalizer==3.4.
|
|
29
|
+
Requires-Dist: charset-normalizer==3.4.4
|
|
30
30
|
Requires-Dist: click==8.2.1
|
|
31
31
|
Requires-Dist: click-didyoumean==0.3.1
|
|
32
32
|
Requires-Dist: click-plugins==1.1.1.2
|
|
33
33
|
Requires-Dist: click-repl==0.3.0
|
|
34
34
|
Requires-Dist: colorama==0.4.6
|
|
35
35
|
Requires-Dist: constantly==23.10.4
|
|
36
|
-
Requires-Dist: cron-descriptor==
|
|
36
|
+
Requires-Dist: cron-descriptor==2.0.6
|
|
37
37
|
Requires-Dist: cryptography==45.0.5
|
|
38
38
|
Requires-Dist: daphne==4.2.1
|
|
39
39
|
Requires-Dist: diff-match-patch==20241021
|
|
@@ -56,15 +56,15 @@ Requires-Dist: hyperlink==21.0.0
|
|
|
56
56
|
Requires-Dist: idna==3.11
|
|
57
57
|
Requires-Dist: incremental==24.7.2
|
|
58
58
|
Requires-Dist: kombu==5.5.4
|
|
59
|
-
Requires-Dist: libipld==3.
|
|
60
|
-
Requires-Dist: Markdown==3.
|
|
59
|
+
Requires-Dist: libipld==3.2.0
|
|
60
|
+
Requires-Dist: Markdown==3.9
|
|
61
61
|
Requires-Dist: mdx_truly_sane_lists==1.3
|
|
62
62
|
Requires-Dist: mfrc522==0.0.7; sys_platform == "linux"
|
|
63
63
|
Requires-Dist: outcome==1.3.0.post0
|
|
64
64
|
Requires-Dist: packaging==25.0
|
|
65
65
|
Requires-Dist: pillow==11.3.0
|
|
66
66
|
Requires-Dist: prompt_toolkit==3.0.51
|
|
67
|
-
Requires-Dist: psutil==7.1.
|
|
67
|
+
Requires-Dist: psutil==7.1.2
|
|
68
68
|
Requires-Dist: psycopg==3.2.9
|
|
69
69
|
Requires-Dist: psycopg-binary==3.2.12
|
|
70
70
|
Requires-Dist: pyasn1==0.6.1
|
|
@@ -79,7 +79,7 @@ Requires-Dist: python-crontab==3.3.0
|
|
|
79
79
|
Requires-Dist: python-dateutil==2.9.0.post0
|
|
80
80
|
Requires-Dist: python-dotenv==1.1.1
|
|
81
81
|
Requires-Dist: qrcode==8.2
|
|
82
|
-
Requires-Dist: redis==
|
|
82
|
+
Requires-Dist: redis==7.0.1
|
|
83
83
|
Requires-Dist: reportlab==4.2.2
|
|
84
84
|
Requires-Dist: requests==2.32.5
|
|
85
85
|
Requires-Dist: selenium==4.34.2
|
|
@@ -103,7 +103,7 @@ Requires-Dist: typing_extensions==4.14.1
|
|
|
103
103
|
Requires-Dist: tzdata==2025.2
|
|
104
104
|
Requires-Dist: urllib3==2.5.0
|
|
105
105
|
Requires-Dist: vine==5.1.0
|
|
106
|
-
Requires-Dist: wcwidth==0.2.
|
|
106
|
+
Requires-Dist: wcwidth==0.2.14
|
|
107
107
|
Requires-Dist: webencodings==0.5.1
|
|
108
108
|
Requires-Dist: websocket-client==1.8.0
|
|
109
109
|
Requires-Dist: websockets==13.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arthexis
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.22
|
|
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
|
|
@@ -26,14 +26,14 @@ Requires-Dist: celery==5.5.3
|
|
|
26
26
|
Requires-Dist: certifi==2025.7.14
|
|
27
27
|
Requires-Dist: cffi==2.0.0
|
|
28
28
|
Requires-Dist: channels==4.1.0
|
|
29
|
-
Requires-Dist: charset-normalizer==3.4.
|
|
29
|
+
Requires-Dist: charset-normalizer==3.4.4
|
|
30
30
|
Requires-Dist: click==8.2.1
|
|
31
31
|
Requires-Dist: click-didyoumean==0.3.1
|
|
32
32
|
Requires-Dist: click-plugins==1.1.1.2
|
|
33
33
|
Requires-Dist: click-repl==0.3.0
|
|
34
34
|
Requires-Dist: colorama==0.4.6
|
|
35
35
|
Requires-Dist: constantly==23.10.4
|
|
36
|
-
Requires-Dist: cron-descriptor==
|
|
36
|
+
Requires-Dist: cron-descriptor==2.0.6
|
|
37
37
|
Requires-Dist: cryptography==45.0.5
|
|
38
38
|
Requires-Dist: daphne==4.2.1
|
|
39
39
|
Requires-Dist: diff-match-patch==20241021
|
|
@@ -56,15 +56,15 @@ Requires-Dist: hyperlink==21.0.0
|
|
|
56
56
|
Requires-Dist: idna==3.11
|
|
57
57
|
Requires-Dist: incremental==24.7.2
|
|
58
58
|
Requires-Dist: kombu==5.5.4
|
|
59
|
-
Requires-Dist: libipld==3.
|
|
60
|
-
Requires-Dist: Markdown==3.
|
|
59
|
+
Requires-Dist: libipld==3.2.0
|
|
60
|
+
Requires-Dist: Markdown==3.9
|
|
61
61
|
Requires-Dist: mdx_truly_sane_lists==1.3
|
|
62
62
|
Requires-Dist: mfrc522==0.0.7; sys_platform == "linux"
|
|
63
63
|
Requires-Dist: outcome==1.3.0.post0
|
|
64
64
|
Requires-Dist: packaging==25.0
|
|
65
65
|
Requires-Dist: pillow==11.3.0
|
|
66
66
|
Requires-Dist: prompt_toolkit==3.0.51
|
|
67
|
-
Requires-Dist: psutil==7.1.
|
|
67
|
+
Requires-Dist: psutil==7.1.2
|
|
68
68
|
Requires-Dist: psycopg==3.2.9
|
|
69
69
|
Requires-Dist: psycopg-binary==3.2.12
|
|
70
70
|
Requires-Dist: pyasn1==0.6.1
|
|
@@ -79,7 +79,7 @@ Requires-Dist: python-crontab==3.3.0
|
|
|
79
79
|
Requires-Dist: python-dateutil==2.9.0.post0
|
|
80
80
|
Requires-Dist: python-dotenv==1.1.1
|
|
81
81
|
Requires-Dist: qrcode==8.2
|
|
82
|
-
Requires-Dist: redis==
|
|
82
|
+
Requires-Dist: redis==7.0.1
|
|
83
83
|
Requires-Dist: reportlab==4.2.2
|
|
84
84
|
Requires-Dist: requests==2.32.5
|
|
85
85
|
Requires-Dist: selenium==4.34.2
|
|
@@ -103,7 +103,7 @@ Requires-Dist: typing_extensions==4.14.1
|
|
|
103
103
|
Requires-Dist: tzdata==2025.2
|
|
104
104
|
Requires-Dist: urllib3==2.5.0
|
|
105
105
|
Requires-Dist: vine==5.1.0
|
|
106
|
-
Requires-Dist: wcwidth==0.2.
|
|
106
|
+
Requires-Dist: wcwidth==0.2.14
|
|
107
107
|
Requires-Dist: webencodings==0.5.1
|
|
108
108
|
Requires-Dist: websocket-client==1.8.0
|
|
109
109
|
Requires-Dist: websockets==13.1
|
|
@@ -149,7 +149,6 @@ tests/test_email_transaction.py
|
|
|
149
149
|
tests/test_env_refresh_clean.py
|
|
150
150
|
tests/test_env_refresh_pip.py
|
|
151
151
|
tests/test_env_refresh_unlink.py
|
|
152
|
-
tests/test_environment_network_setup_form.py
|
|
153
152
|
tests/test_experience_admin_group.py
|
|
154
153
|
tests/test_fixture_presence.py
|
|
155
154
|
tests/test_footer_no_references.py
|
|
@@ -185,6 +184,7 @@ tests/test_power_admin_group.py
|
|
|
185
184
|
tests/test_profile_inline_deletion.py
|
|
186
185
|
tests/test_pypi_check.py
|
|
187
186
|
tests/test_pypi_token.py
|
|
187
|
+
tests/test_readme_assets.py
|
|
188
188
|
tests/test_readme_editor.py
|
|
189
189
|
tests/test_readme_language.py
|
|
190
190
|
tests/test_reference_qr_code.py
|
|
@@ -13,14 +13,14 @@ celery==5.5.3
|
|
|
13
13
|
certifi==2025.7.14
|
|
14
14
|
cffi==2.0.0
|
|
15
15
|
channels==4.1.0
|
|
16
|
-
charset-normalizer==3.4.
|
|
16
|
+
charset-normalizer==3.4.4
|
|
17
17
|
click==8.2.1
|
|
18
18
|
click-didyoumean==0.3.1
|
|
19
19
|
click-plugins==1.1.1.2
|
|
20
20
|
click-repl==0.3.0
|
|
21
21
|
colorama==0.4.6
|
|
22
22
|
constantly==23.10.4
|
|
23
|
-
cron-descriptor==
|
|
23
|
+
cron-descriptor==2.0.6
|
|
24
24
|
cryptography==45.0.5
|
|
25
25
|
daphne==4.2.1
|
|
26
26
|
diff-match-patch==20241021
|
|
@@ -42,14 +42,14 @@ hyperlink==21.0.0
|
|
|
42
42
|
idna==3.11
|
|
43
43
|
incremental==24.7.2
|
|
44
44
|
kombu==5.5.4
|
|
45
|
-
libipld==3.
|
|
46
|
-
Markdown==3.
|
|
45
|
+
libipld==3.2.0
|
|
46
|
+
Markdown==3.9
|
|
47
47
|
mdx_truly_sane_lists==1.3
|
|
48
48
|
outcome==1.3.0.post0
|
|
49
49
|
packaging==25.0
|
|
50
50
|
pillow==11.3.0
|
|
51
51
|
prompt_toolkit==3.0.51
|
|
52
|
-
psutil==7.1.
|
|
52
|
+
psutil==7.1.2
|
|
53
53
|
psycopg==3.2.9
|
|
54
54
|
psycopg-binary==3.2.12
|
|
55
55
|
pyasn1==0.6.1
|
|
@@ -64,7 +64,7 @@ python-crontab==3.3.0
|
|
|
64
64
|
python-dateutil==2.9.0.post0
|
|
65
65
|
python-dotenv==1.1.1
|
|
66
66
|
qrcode==8.2
|
|
67
|
-
redis==
|
|
67
|
+
redis==7.0.1
|
|
68
68
|
reportlab==4.2.2
|
|
69
69
|
requests==2.32.5
|
|
70
70
|
selenium==4.34.2
|
|
@@ -88,7 +88,7 @@ typing_extensions==4.14.1
|
|
|
88
88
|
tzdata==2025.2
|
|
89
89
|
urllib3==2.5.0
|
|
90
90
|
vine==5.1.0
|
|
91
|
-
wcwidth==0.2.
|
|
91
|
+
wcwidth==0.2.14
|
|
92
92
|
webencodings==0.5.1
|
|
93
93
|
websocket-client==1.8.0
|
|
94
94
|
websockets==13.1
|
|
@@ -662,4 +662,8 @@ CELERY_BEAT_SCHEDULE = {
|
|
|
662
662
|
"task": "core.tasks.heartbeat",
|
|
663
663
|
"schedule": crontab(minute="*/5"),
|
|
664
664
|
},
|
|
665
|
+
"ocpp_configuration_check": {
|
|
666
|
+
"task": "ocpp.tasks.schedule_daily_charge_point_configuration_checks",
|
|
667
|
+
"schedule": crontab(minute=0, hour=0),
|
|
668
|
+
},
|
|
665
669
|
}
|
|
@@ -134,6 +134,11 @@ urlpatterns = [
|
|
|
134
134
|
core_views.todo_done,
|
|
135
135
|
name="todo-done",
|
|
136
136
|
),
|
|
137
|
+
path(
|
|
138
|
+
"admin/core/todos/<int:pk>/delete/",
|
|
139
|
+
core_views.todo_delete,
|
|
140
|
+
name="todo-delete",
|
|
141
|
+
),
|
|
137
142
|
path(
|
|
138
143
|
"admin/core/todos/<int:pk>/snapshot/",
|
|
139
144
|
core_views.todo_snapshot,
|
|
@@ -83,6 +83,7 @@ from .models import (
|
|
|
83
83
|
OdooProfile,
|
|
84
84
|
OpenPayProfile,
|
|
85
85
|
EmailInbox,
|
|
86
|
+
GoogleCalendarProfile,
|
|
86
87
|
SocialProfile,
|
|
87
88
|
EmailCollector,
|
|
88
89
|
Package,
|
|
@@ -1005,6 +1006,41 @@ class OpenPayProfileAdminForm(forms.ModelForm):
|
|
|
1005
1006
|
)
|
|
1006
1007
|
|
|
1007
1008
|
|
|
1009
|
+
class GoogleCalendarProfileAdminForm(forms.ModelForm):
|
|
1010
|
+
"""Admin form for :class:`core.models.GoogleCalendarProfile`."""
|
|
1011
|
+
|
|
1012
|
+
api_key = forms.CharField(
|
|
1013
|
+
widget=forms.PasswordInput(render_value=True),
|
|
1014
|
+
required=False,
|
|
1015
|
+
help_text="Leave blank to keep the current key.",
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
class Meta:
|
|
1019
|
+
model = GoogleCalendarProfile
|
|
1020
|
+
fields = "__all__"
|
|
1021
|
+
|
|
1022
|
+
def __init__(self, *args, **kwargs):
|
|
1023
|
+
super().__init__(*args, **kwargs)
|
|
1024
|
+
if self.instance.pk:
|
|
1025
|
+
self.fields["api_key"].initial = ""
|
|
1026
|
+
self.initial["api_key"] = ""
|
|
1027
|
+
else:
|
|
1028
|
+
self.fields["api_key"].required = True
|
|
1029
|
+
|
|
1030
|
+
def clean_api_key(self):
|
|
1031
|
+
key = self.cleaned_data.get("api_key")
|
|
1032
|
+
if not key and self.instance.pk:
|
|
1033
|
+
return keep_existing("api_key")
|
|
1034
|
+
return key
|
|
1035
|
+
|
|
1036
|
+
def _post_clean(self):
|
|
1037
|
+
super()._post_clean()
|
|
1038
|
+
_restore_sigil_values(
|
|
1039
|
+
self,
|
|
1040
|
+
["calendar_id", "api_key", "display_name", "timezone"],
|
|
1041
|
+
)
|
|
1042
|
+
|
|
1043
|
+
|
|
1008
1044
|
class MaskedPasswordFormMixin:
|
|
1009
1045
|
"""Mixin that hides stored passwords while allowing updates."""
|
|
1010
1046
|
|
|
@@ -1222,6 +1258,15 @@ class OpenPayProfileInlineForm(ProfileFormMixin, OpenPayProfileAdminForm):
|
|
|
1222
1258
|
return cleaned
|
|
1223
1259
|
|
|
1224
1260
|
|
|
1261
|
+
class GoogleCalendarProfileInlineForm(
|
|
1262
|
+
ProfileFormMixin, GoogleCalendarProfileAdminForm
|
|
1263
|
+
):
|
|
1264
|
+
profile_fields = GoogleCalendarProfile.profile_fields
|
|
1265
|
+
|
|
1266
|
+
class Meta(GoogleCalendarProfileAdminForm.Meta):
|
|
1267
|
+
exclude = ("user", "group")
|
|
1268
|
+
|
|
1269
|
+
|
|
1225
1270
|
class EmailInboxInlineForm(ProfileFormMixin, EmailInboxAdminForm):
|
|
1226
1271
|
profile_fields = EmailInbox.profile_fields
|
|
1227
1272
|
|
|
@@ -1346,6 +1391,16 @@ PROFILE_INLINE_CONFIG = {
|
|
|
1346
1391
|
),
|
|
1347
1392
|
"readonly_fields": ("verified_on", "verification_reference"),
|
|
1348
1393
|
},
|
|
1394
|
+
GoogleCalendarProfile: {
|
|
1395
|
+
"form": GoogleCalendarProfileInlineForm,
|
|
1396
|
+
"fields": (
|
|
1397
|
+
"display_name",
|
|
1398
|
+
"calendar_id",
|
|
1399
|
+
"api_key",
|
|
1400
|
+
"max_events",
|
|
1401
|
+
"timezone",
|
|
1402
|
+
),
|
|
1403
|
+
},
|
|
1349
1404
|
EmailInbox: {
|
|
1350
1405
|
"form": EmailInboxInlineForm,
|
|
1351
1406
|
"fields": (
|
|
@@ -1817,6 +1872,44 @@ class OpenPayProfileAdmin(ProfileAdminMixin, SaveBeforeChangeAction, EntityModel
|
|
|
1817
1872
|
verify_credentials_action.short_description = _("Test credentials")
|
|
1818
1873
|
|
|
1819
1874
|
|
|
1875
|
+
class GoogleCalendarProfileAdmin(
|
|
1876
|
+
ProfileAdminMixin, SaveBeforeChangeAction, EntityModelAdmin
|
|
1877
|
+
):
|
|
1878
|
+
form = GoogleCalendarProfileAdminForm
|
|
1879
|
+
list_display = ("owner", "calendar_identifier", "max_events")
|
|
1880
|
+
search_fields = (
|
|
1881
|
+
"display_name",
|
|
1882
|
+
"calendar_id",
|
|
1883
|
+
"user__username",
|
|
1884
|
+
"group__name",
|
|
1885
|
+
)
|
|
1886
|
+
changelist_actions = ["my_profile"]
|
|
1887
|
+
change_actions = ["my_profile_action"]
|
|
1888
|
+
fieldsets = (
|
|
1889
|
+
(_("Owner"), {"fields": ("user", "group")}),
|
|
1890
|
+
(
|
|
1891
|
+
_("Calendar"),
|
|
1892
|
+
{
|
|
1893
|
+
"fields": (
|
|
1894
|
+
"display_name",
|
|
1895
|
+
"calendar_id",
|
|
1896
|
+
"api_key",
|
|
1897
|
+
"max_events",
|
|
1898
|
+
"timezone",
|
|
1899
|
+
)
|
|
1900
|
+
},
|
|
1901
|
+
),
|
|
1902
|
+
)
|
|
1903
|
+
|
|
1904
|
+
@admin.display(description=_("Owner"))
|
|
1905
|
+
def owner(self, obj):
|
|
1906
|
+
return obj.owner_display()
|
|
1907
|
+
|
|
1908
|
+
@admin.display(description=_("Calendar"))
|
|
1909
|
+
def calendar_identifier(self, obj):
|
|
1910
|
+
display = obj.get_display_name()
|
|
1911
|
+
return display or obj.resolved_calendar_id()
|
|
1912
|
+
|
|
1820
1913
|
class EmailSearchForm(forms.Form):
|
|
1821
1914
|
subject = forms.CharField(
|
|
1822
1915
|
required=False, widget=forms.TextInput(attrs={"style": "width: 40em;"})
|
|
@@ -2416,8 +2509,30 @@ class ProductAdmin(EntityModelAdmin):
|
|
|
2416
2509
|
],
|
|
2417
2510
|
limit=0,
|
|
2418
2511
|
)
|
|
2419
|
-
except Exception:
|
|
2512
|
+
except Exception as exc:
|
|
2513
|
+
logger.exception(
|
|
2514
|
+
"Failed to fetch Odoo products for user %s (profile_id=%s, host=%s, database=%s)",
|
|
2515
|
+
getattr(getattr(request, "user", None), "pk", None),
|
|
2516
|
+
getattr(profile, "pk", None),
|
|
2517
|
+
getattr(profile, "host", None),
|
|
2518
|
+
getattr(profile, "database", None),
|
|
2519
|
+
)
|
|
2420
2520
|
context["error"] = _("Unable to fetch products from Odoo.")
|
|
2521
|
+
if getattr(request.user, "is_superuser", False):
|
|
2522
|
+
fault = getattr(exc, "faultString", "")
|
|
2523
|
+
message = str(exc)
|
|
2524
|
+
details = [
|
|
2525
|
+
f"Host: {getattr(profile, 'host', '')}",
|
|
2526
|
+
f"Database: {getattr(profile, 'database', '')}",
|
|
2527
|
+
f"User ID: {getattr(profile, 'odoo_uid', '')}",
|
|
2528
|
+
]
|
|
2529
|
+
if fault and fault != message:
|
|
2530
|
+
details.append(f"Fault: {fault}")
|
|
2531
|
+
if message:
|
|
2532
|
+
details.append(f"Exception: {type(exc).__name__}: {message}")
|
|
2533
|
+
else:
|
|
2534
|
+
details.append(f"Exception type: {type(exc).__name__}")
|
|
2535
|
+
context["debug_error"] = "\n".join(details)
|
|
2421
2536
|
return context, []
|
|
2422
2537
|
|
|
2423
2538
|
context["has_credentials"] = True
|
|
@@ -2697,7 +2812,7 @@ class RFIDAdmin(EntityModelAdmin, ImportExportModelAdmin):
|
|
|
2697
2812
|
"user_data_flag",
|
|
2698
2813
|
"color",
|
|
2699
2814
|
"kind",
|
|
2700
|
-
"
|
|
2815
|
+
"endianness_short",
|
|
2701
2816
|
"released",
|
|
2702
2817
|
"allowed",
|
|
2703
2818
|
"last_seen_on",
|
|
@@ -2762,6 +2877,14 @@ class RFIDAdmin(EntityModelAdmin, ImportExportModelAdmin):
|
|
|
2762
2877
|
def user_data_flag(self, obj):
|
|
2763
2878
|
return getattr(obj, "is_user_data", False)
|
|
2764
2879
|
|
|
2880
|
+
@admin.display(description=_("End"), ordering="endianness")
|
|
2881
|
+
def endianness_short(self, obj):
|
|
2882
|
+
labels = {
|
|
2883
|
+
RFID.BIG_ENDIAN: _("Big"),
|
|
2884
|
+
RFID.LITTLE_ENDIAN: _("Little"),
|
|
2885
|
+
}
|
|
2886
|
+
return labels.get(obj.endianness, obj.get_endianness_display())
|
|
2887
|
+
|
|
2765
2888
|
def scan_rfids(self, request, queryset):
|
|
2766
2889
|
return redirect("admin:core_rfid_scan")
|
|
2767
2890
|
|
|
@@ -3715,9 +3838,9 @@ class PackageReleaseAdmin(SaveBeforeChangeAction, EntityModelAdmin):
|
|
|
3715
3838
|
self.message_user(request, str(exc), messages.ERROR)
|
|
3716
3839
|
return
|
|
3717
3840
|
releases = resp.json().get("releases", {})
|
|
3718
|
-
created = 0
|
|
3719
3841
|
updated = 0
|
|
3720
3842
|
restored = 0
|
|
3843
|
+
missing: list[str] = []
|
|
3721
3844
|
|
|
3722
3845
|
for version, files in releases.items():
|
|
3723
3846
|
release_on = self._release_on_from_files(files)
|
|
@@ -3742,23 +3865,11 @@ class PackageReleaseAdmin(SaveBeforeChangeAction, EntityModelAdmin):
|
|
|
3742
3865
|
if update_fields:
|
|
3743
3866
|
release.save(update_fields=update_fields)
|
|
3744
3867
|
continue
|
|
3745
|
-
|
|
3746
|
-
package=package,
|
|
3747
|
-
release_manager=package.release_manager,
|
|
3748
|
-
version=version,
|
|
3749
|
-
revision="",
|
|
3750
|
-
pypi_url=f"https://pypi.org/project/{package.name}/{version}/",
|
|
3751
|
-
release_on=release_on,
|
|
3752
|
-
)
|
|
3753
|
-
created += 1
|
|
3868
|
+
missing.append(version)
|
|
3754
3869
|
|
|
3755
|
-
if
|
|
3870
|
+
if updated or restored:
|
|
3756
3871
|
PackageRelease.dump_fixture()
|
|
3757
3872
|
message_parts = []
|
|
3758
|
-
if created:
|
|
3759
|
-
message_parts.append(
|
|
3760
|
-
f"Created {created} release{'s' if created != 1 else ''} from PyPI"
|
|
3761
|
-
)
|
|
3762
3873
|
if updated:
|
|
3763
3874
|
message_parts.append(
|
|
3764
3875
|
f"Updated release date for {updated} release"
|
|
@@ -3769,8 +3880,17 @@ class PackageReleaseAdmin(SaveBeforeChangeAction, EntityModelAdmin):
|
|
|
3769
3880
|
f"Restored {restored} release{'s' if restored != 1 else ''}"
|
|
3770
3881
|
)
|
|
3771
3882
|
self.message_user(request, "; ".join(message_parts), messages.SUCCESS)
|
|
3772
|
-
|
|
3773
|
-
self.message_user(request, "No
|
|
3883
|
+
elif not missing:
|
|
3884
|
+
self.message_user(request, "No matching releases found", messages.INFO)
|
|
3885
|
+
|
|
3886
|
+
if missing:
|
|
3887
|
+
versions = ", ".join(sorted(missing))
|
|
3888
|
+
count = len(missing)
|
|
3889
|
+
message = (
|
|
3890
|
+
"Manual creation required for "
|
|
3891
|
+
f"{count} release{'s' if count != 1 else ''}: {versions}"
|
|
3892
|
+
)
|
|
3893
|
+
self.message_user(request, message, messages.WARNING)
|
|
3774
3894
|
|
|
3775
3895
|
refresh_from_pypi.label = "Refresh from PyPI"
|
|
3776
3896
|
refresh_from_pypi.short_description = "Refresh from PyPI"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
from django.contrib import admin
|
|
6
|
+
from django.template.response import TemplateResponse
|
|
7
|
+
from django.urls import path
|
|
8
|
+
from django.utils.translation import gettext_lazy as _
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _get_django_settings():
|
|
12
|
+
return sorted(
|
|
13
|
+
[(name, getattr(settings, name)) for name in dir(settings) if name.isupper()]
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _environment_view(request):
|
|
18
|
+
env_vars = sorted(os.environ.items())
|
|
19
|
+
context = admin.site.each_context(request)
|
|
20
|
+
context.update(
|
|
21
|
+
{
|
|
22
|
+
"title": _("Environment"),
|
|
23
|
+
"env_vars": env_vars,
|
|
24
|
+
"environment_tasks": [],
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
return TemplateResponse(request, "admin/environment.html", context)
|
|
28
|
+
|
|
29
|
+
def _config_view(request):
|
|
30
|
+
context = admin.site.each_context(request)
|
|
31
|
+
context.update(
|
|
32
|
+
{
|
|
33
|
+
"title": _("Django Settings"),
|
|
34
|
+
"django_settings": _get_django_settings(),
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
return TemplateResponse(request, "admin/config.html", context)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def patch_admin_environment_view() -> None:
|
|
41
|
+
"""Register the Environment and Config admin views on the main admin site."""
|
|
42
|
+
original_get_urls = admin.site.get_urls
|
|
43
|
+
|
|
44
|
+
def get_urls():
|
|
45
|
+
urls = original_get_urls()
|
|
46
|
+
custom = [
|
|
47
|
+
path(
|
|
48
|
+
"environment/",
|
|
49
|
+
admin.site.admin_view(_environment_view),
|
|
50
|
+
name="environment",
|
|
51
|
+
),
|
|
52
|
+
path(
|
|
53
|
+
"config/",
|
|
54
|
+
admin.site.admin_view(_config_view),
|
|
55
|
+
name="config",
|
|
56
|
+
),
|
|
57
|
+
]
|
|
58
|
+
return custom + urls
|
|
59
|
+
|
|
60
|
+
admin.site.get_urls = get_urls
|