aa-structures 2.13.0__tar.gz → 2.14.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aa_structures-2.13.0 → aa_structures-2.14.1}/PKG-INFO +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/__init__.py +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/admin.py +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/app_settings.py +4 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/constants.py +1 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_timers.py +53 -6
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_types.py +1 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/managers.py +13 -2
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/owners.py +82 -12
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/structures_1.py +5 -0
- aa_structures-2.13.0/structures/templates/structures/partials/structures/poco_list.html → aa_structures-2.14.1/structures/templates/structures/partials/structures/orbital_list.html +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/starbase_list.html +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/public.html +2 -2
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/structures.html +5 -5
- aa_structures-2.13.0/structures/tests/core/test_notifications_timerboard.py → aa_structures-2.14.1/structures/tests/core/test_notifications_timers.py +6 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/test_tasks.py +102 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/test_views.py +1 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_2.py +14 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_5.py +135 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_structures.py +49 -42
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_managers_1.py +11 -1
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/factories.py +21 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/helpers.py +6 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_structures.py +12 -4
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/structures.py +6 -6
- {aa_structures-2.13.0 → aa_structures-2.14.1}/LICENSE +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/README.md +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/pyproject.toml +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/apps.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/auth_hooks.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/billing_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/corporate_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/helpers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/main.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/moonmining_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/orbital_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/skyhook_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/sov_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/structures_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/tower_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/war_embeds.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/serializers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/sovereignty.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/starbases.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/forms.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/helpers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/de/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/de/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/django.pot +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/en/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/en/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/es/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/es/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/fr_FR/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/it_IT/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ja/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ja/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ko_KR/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ru/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ru/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/uk/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/uk/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/zh_Hans/LC_MESSAGES/django.po +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_load_eve.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_preload_eveuniverse.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_update_poco_planets.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0001_initial_new.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0002_remove_eveuniverse_relation_names.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0003_add_localization_and_unique_key.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0004_improve_localization.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0005_add_notification_types.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0006_add_ownercharacter_disabled.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0007_add_notificationtypes_skyhook_metenox.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0008_add_notificationtypes_skyhook_metenox.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/eveuniverse.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/notifications.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/structures_2.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/providers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/global.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/main.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/public.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/statistics.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/structures.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/bars-rotate-fade-black-36.svg +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/bars-rotate-fade-white-36.svg +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/eve_symbol_128.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0r.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0s.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1r.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2r.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3r.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4s.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5s.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/blank.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/circle.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/dustwheel.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/h.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/l.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/m.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/noship.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/r.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_blue.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_darkred.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_default.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_revelations.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/structures_logo.png +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/global.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/public.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/statistics.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/structures.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/dataTables.rowGroup.min.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/datetime.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/filterDropDown.min.js +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/rowGroup.bootstrap.min.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/rowGroup.dataTables.min.css +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tasks.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/base.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/fitting_assets.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/fitting_gfx.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/poco_details.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/starbase_detail.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/structure_details.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/tab_general_detail.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/tab_services_detail.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/menu.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/public/poco_list.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/statistics/structure_summary.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/active_tags.html +0 -0
- /aa_structures-2.13.0/structures/templates/structures/partials/structures/jump_gates_list.html → /aa_structures-2.14.1/structures/templates/structures/partials/structures/jump_gate_list.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/structure_list.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/statistics.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/detail_title.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_asset.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_item.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_tax_item.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_title.html +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templatetags/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templatetags/structures.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/test_helpers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/test_main.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_notification_structuretimers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_notification_types.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_serializers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_sovereignty.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_starbases.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_eveuniverse.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_1.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_2.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_3.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_discord.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_1.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_3.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_4.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_6.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_admin.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_helpers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_managers_2.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_tasks.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/create_eveuniverse.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/entities.json +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/esi_data.json +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/eveuniverse.json +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_notifications.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_notifications_2.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_structures.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/load_eveuniverse.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/tasks_loadtest.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/test_generate_structures.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_public.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_service_status.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_statistics.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/utils.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/urls.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/common.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/public.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/statistics.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/status.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/core.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/managers.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/models.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/__init__.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/test_core.py +0 -0
- {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/test_utils.py +0 -0
@@ -324,7 +324,7 @@ class NotificationBaseAdmin(admin.ModelAdmin):
|
|
324
324
|
message = format_lazy("{first} {second}", first=first, second=second)
|
325
325
|
else:
|
326
326
|
message = first
|
327
|
-
message = format_lazy(
|
327
|
+
message = format_lazy(first)
|
328
328
|
self.message_user(request, message)
|
329
329
|
|
330
330
|
|
@@ -49,6 +49,10 @@ STRUCTURES_FEATURE_REFUELED_NOTIFICATIONS = clean_setting(
|
|
49
49
|
)
|
50
50
|
"""Enable / disable refueled notifications feature."""
|
51
51
|
|
52
|
+
STRUCTURES_FEATURE_SKYHOOKS = clean_setting("STRUCTURES_FEATURE_SKYHOOKS", False)
|
53
|
+
"""Show skyhooks in structures list."""
|
54
|
+
|
55
|
+
|
52
56
|
STRUCTURES_FEATURE_STARBASES = clean_setting("STRUCTURES_FEATURE_STARBASES", True)
|
53
57
|
"""Enable / disable starbases feature."""
|
54
58
|
|
@@ -53,7 +53,9 @@ def add_or_remove_timer(notif: Notification) -> bool:
|
|
53
53
|
elif notif.notif_type == NotificationType.SOV_STRUCTURE_REINFORCED:
|
54
54
|
timer_processed = _gen_timer_sov_reinforcements(notif)
|
55
55
|
elif notif.notif_type == NotificationType.ORBITAL_REINFORCED:
|
56
|
-
timer_processed =
|
56
|
+
timer_processed = _gen_timer_customs_office_reinforcements(notif)
|
57
|
+
elif notif.notif_type == NotificationType.SKYHOOK_LOST_SHIELDS:
|
58
|
+
timer_processed = _gen_timer_skyhook_reinforcements(notif)
|
57
59
|
elif notif.notif_type in [
|
58
60
|
NotificationType.MOONMINING_EXTRACTION_STARTED,
|
59
61
|
NotificationType.MOONMINING_EXTRACTION_CANCELLED,
|
@@ -65,9 +67,7 @@ def add_or_remove_timer(notif: Notification) -> bool:
|
|
65
67
|
elif notif.notif_type == NotificationType.TOWER_REINFORCED_EXTRA:
|
66
68
|
timer_processed = _gen_timer_tower_reinforcements(notif)
|
67
69
|
else:
|
68
|
-
raise NotImplementedError(
|
69
|
-
f"Unsupported notification type for timers: {notif.notif_type}"
|
70
|
-
)
|
70
|
+
raise NotImplementedError(notif.notif_type)
|
71
71
|
if timer_processed:
|
72
72
|
logger.info("%s: Created timer for notification", notif.notification_id)
|
73
73
|
notif.is_timer_added = True
|
@@ -181,8 +181,8 @@ def _gen_timer_sov_reinforcements(notif: Notification) -> bool:
|
|
181
181
|
return timer_processed
|
182
182
|
|
183
183
|
|
184
|
-
def
|
185
|
-
"""Generate timer for
|
184
|
+
def _gen_timer_customs_office_reinforcements(notif: Notification) -> bool:
|
185
|
+
"""Generate timer for customs office reinforcements."""
|
186
186
|
|
187
187
|
solar_system = notif.eve_solar_system()
|
188
188
|
planet = notif.eve_planet()
|
@@ -231,6 +231,53 @@ def _gen_timer_orbital_reinforcements(notif: Notification) -> bool:
|
|
231
231
|
return timer_processed
|
232
232
|
|
233
233
|
|
234
|
+
def _gen_timer_skyhook_reinforcements(notif: Notification) -> bool:
|
235
|
+
"""Generate timer for skyhook reinforcements."""
|
236
|
+
|
237
|
+
solar_system = notif.eve_solar_system("solarsystemID")
|
238
|
+
structure_type = notif.eve_structure_type("typeID")
|
239
|
+
planet = notif.eve_planet()
|
240
|
+
eve_time = ldap_time_2_datetime(notif.parsed_text()["timestamp"])
|
241
|
+
timer_processed = False
|
242
|
+
|
243
|
+
if AuthTimer:
|
244
|
+
AuthTimer.objects.create(
|
245
|
+
details=gettext("Final timer"),
|
246
|
+
system=solar_system.name,
|
247
|
+
planet_moon=planet.name,
|
248
|
+
structure="POCO", # Auth timer does not support the Skyhook type yet
|
249
|
+
objective="Friendly",
|
250
|
+
eve_time=eve_time,
|
251
|
+
eve_corp=notif.owner.corporation,
|
252
|
+
corp_timer=STRUCTURES_TIMERS_ARE_CORP_RESTRICTED,
|
253
|
+
)
|
254
|
+
timer_processed = True
|
255
|
+
|
256
|
+
if Timer:
|
257
|
+
visibility = (
|
258
|
+
Timer.Visibility.CORPORATION
|
259
|
+
if STRUCTURES_TIMERS_ARE_CORP_RESTRICTED
|
260
|
+
else Timer.Visibility.UNRESTRICTED
|
261
|
+
)
|
262
|
+
Timer.objects.create(
|
263
|
+
eve_solar_system=solar_system,
|
264
|
+
structure_type=structure_type,
|
265
|
+
timer_type=Timer.Type.FINAL,
|
266
|
+
objective=Timer.Objective.FRIENDLY,
|
267
|
+
date=eve_time,
|
268
|
+
location_details=planet.name,
|
269
|
+
eve_corporation=notif.owner.corporation,
|
270
|
+
eve_alliance=notif.owner.corporation.alliance,
|
271
|
+
visibility=visibility,
|
272
|
+
structure_name=structure_type.name,
|
273
|
+
owner_name=notif.owner.corporation.corporation_name,
|
274
|
+
details_notes=_timer_details_notes(notif),
|
275
|
+
)
|
276
|
+
timer_processed = True
|
277
|
+
|
278
|
+
return timer_processed
|
279
|
+
|
280
|
+
|
234
281
|
def _gen_timer_moon_extraction(notif: Notification) -> bool:
|
235
282
|
"""Generate timer for moon mining extractions."""
|
236
283
|
solar_system = notif.eve_solar_system()
|
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
# pylint: disable=missing-class-docstring
|
4
4
|
|
5
|
+
from __future__ import annotations
|
6
|
+
|
5
7
|
import datetime as dt
|
6
8
|
import itertools
|
7
|
-
from typing import Any, Iterable, Optional, Set, Tuple
|
9
|
+
from typing import TYPE_CHECKING, Any, Iterable, Optional, Set, Tuple
|
8
10
|
|
9
11
|
from django.contrib.auth.models import User
|
10
12
|
from django.db import models, transaction
|
@@ -24,6 +26,9 @@ from .core.notification_types import NotificationType
|
|
24
26
|
from .providers import esi
|
25
27
|
from .webhooks.managers import WebhookBaseManager
|
26
28
|
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
from .models import Owner
|
31
|
+
|
27
32
|
logger = LoggerAddTag(get_extension_logger(__name__), __title__)
|
28
33
|
|
29
34
|
|
@@ -231,6 +236,10 @@ class StructureQuerySet(models.QuerySet):
|
|
231
236
|
"""Filter for starbases."""
|
232
237
|
return self.filter(eve_type__eve_group__eve_category=EveCategoryId.STARBASE)
|
233
238
|
|
239
|
+
def filter_skyhooks(self) -> models.QuerySet:
|
240
|
+
"""Filter for skyhooks."""
|
241
|
+
return self.filter(eve_type=EveTypeId.ORBITAL_SKYHOOK)
|
242
|
+
|
234
243
|
def ids(self) -> Set[int]:
|
235
244
|
"""Return ids as set."""
|
236
245
|
return set(self.values_list("id", flat=True))
|
@@ -380,7 +389,9 @@ class StructureManagerBase(models.Manager):
|
|
380
389
|
obj, created = self.update_or_create_from_dict(structure=structure, owner=owner)
|
381
390
|
return obj, created
|
382
391
|
|
383
|
-
def update_or_create_from_dict(
|
392
|
+
def update_or_create_from_dict(
|
393
|
+
self, structure: dict, owner: Owner
|
394
|
+
) -> Tuple[Any, bool]:
|
384
395
|
"""update or create structure from given dict"""
|
385
396
|
|
386
397
|
eve_type: EveType = EveType.objects.get_or_create_esi(id=structure["type_id"])[
|
@@ -37,6 +37,7 @@ from structures.app_settings import (
|
|
37
37
|
STRUCTURES_DEVELOPER_MODE,
|
38
38
|
STRUCTURES_ESI_DIRECTOR_ERROR_MAX_RETRIES,
|
39
39
|
STRUCTURES_FEATURE_CUSTOMS_OFFICES,
|
40
|
+
STRUCTURES_FEATURE_SKYHOOKS,
|
40
41
|
STRUCTURES_FEATURE_STARBASES,
|
41
42
|
STRUCTURES_HOURS_UNTIL_STALE_NOTIFICATION,
|
42
43
|
STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES,
|
@@ -545,14 +546,14 @@ class Owner(models.Model):
|
|
545
546
|
)
|
546
547
|
|
547
548
|
def _remove_structures_not_returned_from_esi(
|
548
|
-
self,
|
549
|
+
self, existing_structures: models.QuerySet, new_structures: Iterable[dict]
|
549
550
|
):
|
550
551
|
"""Remove structures no longer returned from ESI."""
|
551
|
-
ids_local = {x.id for x in
|
552
|
+
ids_local = {x.id for x in existing_structures}
|
552
553
|
ids_from_esi = {x["structure_id"] for x in new_structures}
|
553
554
|
ids_to_remove = ids_local - ids_from_esi
|
554
555
|
if len(ids_to_remove) > 0:
|
555
|
-
|
556
|
+
existing_structures.filter(id__in=ids_to_remove).delete()
|
556
557
|
logger.info(
|
557
558
|
"Removed %d structures which apparently no longer exist.",
|
558
559
|
len(ids_to_remove),
|
@@ -591,7 +592,7 @@ class Owner(models.Model):
|
|
591
592
|
is_ok = True
|
592
593
|
# fetch main list of structure for this corporation
|
593
594
|
try:
|
594
|
-
structures = (
|
595
|
+
structures: List[dict] = (
|
595
596
|
esi.client.Corporation.get_corporations_corporation_id_structures(
|
596
597
|
corporation_id=self.corporation.corporation_id,
|
597
598
|
token=token.valid_access_token(),
|
@@ -619,9 +620,19 @@ class Owner(models.Model):
|
|
619
620
|
)
|
620
621
|
).results()
|
621
622
|
except OSError as ex:
|
622
|
-
|
623
|
-
|
624
|
-
|
623
|
+
if isinstance(ex, HTTPForbidden):
|
624
|
+
logger.error(
|
625
|
+
"Failed to fetch structure with ID #%d belonging to %s, "
|
626
|
+
"because the character '%s' is missing "
|
627
|
+
"docking rights for it.",
|
628
|
+
structure["structure_id"],
|
629
|
+
self,
|
630
|
+
token.character_name,
|
631
|
+
)
|
632
|
+
else:
|
633
|
+
self._report_esi_issue(
|
634
|
+
f"fetch structure #{structure['structure_id']}", ex, token
|
635
|
+
)
|
625
636
|
structure["name"] = "(no data)"
|
626
637
|
is_ok = False
|
627
638
|
else:
|
@@ -650,7 +661,7 @@ class Owner(models.Model):
|
|
650
661
|
self._store_raw_data("structures", structures)
|
651
662
|
|
652
663
|
self._remove_structures_not_returned_from_esi(
|
653
|
-
|
664
|
+
existing_structures=self.structures.filter_upwell_structures(),
|
654
665
|
new_structures=structures,
|
655
666
|
)
|
656
667
|
return is_ok
|
@@ -701,7 +712,7 @@ class Owner(models.Model):
|
|
701
712
|
return False
|
702
713
|
|
703
714
|
self._remove_structures_not_returned_from_esi(
|
704
|
-
|
715
|
+
existing_structures=self.structures.filter_customs_offices(),
|
705
716
|
new_structures=structures.values(),
|
706
717
|
)
|
707
718
|
return True
|
@@ -868,7 +879,7 @@ class Owner(models.Model):
|
|
868
879
|
return False
|
869
880
|
|
870
881
|
self._remove_structures_not_returned_from_esi(
|
871
|
-
|
882
|
+
existing_structures=self.structures.filter_starbases(),
|
872
883
|
new_structures=structures,
|
873
884
|
)
|
874
885
|
character.reset_error_counter()
|
@@ -1214,15 +1225,18 @@ class Owner(models.Model):
|
|
1214
1225
|
def update_asset_esi(self, user: Optional[User] = None):
|
1215
1226
|
"""Update assets from ESI."""
|
1216
1227
|
token = self.fetch_token()
|
1217
|
-
assets_data = self.
|
1228
|
+
assets_data = self._fetch_owner_assets_from_esi(token)
|
1218
1229
|
self._store_items_for_upwell_structures(assets_data)
|
1219
1230
|
self._store_items_for_starbases(assets_data)
|
1231
|
+
if STRUCTURES_FEATURE_SKYHOOKS:
|
1232
|
+
self._update_skyhooks_from_assets(assets_data)
|
1233
|
+
self._resolve_skyhook_planets()
|
1220
1234
|
if user:
|
1221
1235
|
self._send_report_to_user(
|
1222
1236
|
topic="assets", topic_count=self.structures.count(), user=user
|
1223
1237
|
)
|
1224
1238
|
|
1225
|
-
def
|
1239
|
+
def _fetch_owner_assets_from_esi(self, token: Token) -> dict:
|
1226
1240
|
assets_raw = esi.client.Assets.get_corporations_corporation_id_assets(
|
1227
1241
|
corporation_id=self.corporation.corporation_id,
|
1228
1242
|
token=token.valid_access_token(),
|
@@ -1306,6 +1320,62 @@ class Owner(models.Model):
|
|
1306
1320
|
)
|
1307
1321
|
structure.update_items(structure_items)
|
1308
1322
|
|
1323
|
+
def _update_skyhooks_from_assets(self, assets_data: dict):
|
1324
|
+
skyhooks = {
|
1325
|
+
item_id: item
|
1326
|
+
for item_id, item in assets_data.items()
|
1327
|
+
if item["type_id"] == EveTypeId.ORBITAL_SKYHOOK
|
1328
|
+
and item["location_type"] == "solar_system"
|
1329
|
+
and item["location_flag"] == "AutoFit"
|
1330
|
+
and item["is_singleton"]
|
1331
|
+
and item["position"]
|
1332
|
+
}
|
1333
|
+
structures = []
|
1334
|
+
for item in skyhooks.values():
|
1335
|
+
structures.append(
|
1336
|
+
{
|
1337
|
+
"corporation_id": self.corporation.corporation_id,
|
1338
|
+
"type_id": item["type_id"],
|
1339
|
+
"position": item["position"],
|
1340
|
+
"structure_id": item["item_id"],
|
1341
|
+
"system_id": item["location_id"],
|
1342
|
+
}
|
1343
|
+
)
|
1344
|
+
|
1345
|
+
for s in structures:
|
1346
|
+
Structure.objects.update_or_create_from_dict(s, self)
|
1347
|
+
|
1348
|
+
self._remove_structures_not_returned_from_esi(
|
1349
|
+
existing_structures=self.structures.filter_skyhooks(),
|
1350
|
+
new_structures=structures,
|
1351
|
+
)
|
1352
|
+
|
1353
|
+
def _resolve_skyhook_planets(self):
|
1354
|
+
"""Add planets to all unresolved Skyhooks."""
|
1355
|
+
s: Structure
|
1356
|
+
for s in self.structures.filter_skyhooks().filter(
|
1357
|
+
eve_planet__isnull=True,
|
1358
|
+
position_x__isnull=False,
|
1359
|
+
position_y__isnull=False,
|
1360
|
+
position_z__isnull=False,
|
1361
|
+
):
|
1362
|
+
try:
|
1363
|
+
celestial = s.eve_solar_system.nearest_celestial(
|
1364
|
+
x=s.position_x,
|
1365
|
+
y=s.position_y,
|
1366
|
+
z=s.position_z,
|
1367
|
+
group_id=EveGroupId.PLANET,
|
1368
|
+
)
|
1369
|
+
except OSError:
|
1370
|
+
continue
|
1371
|
+
|
1372
|
+
if not celestial or not isinstance(celestial.eve_object, EvePlanet):
|
1373
|
+
continue
|
1374
|
+
|
1375
|
+
s.eve_planet = celestial.eve_object
|
1376
|
+
s.name = celestial.eve_type.name
|
1377
|
+
s.save()
|
1378
|
+
|
1309
1379
|
@staticmethod
|
1310
1380
|
def get_esi_scopes() -> List[str]:
|
1311
1381
|
"""Return all required ESI scopes."""
|
@@ -464,6 +464,11 @@ class Structure(models.Model): # pylint: disable = too-many-public-methods
|
|
464
464
|
"""Return True if this structure is a starbase, else False."""
|
465
465
|
return starbases.is_starbase(self.eve_type)
|
466
466
|
|
467
|
+
@property
|
468
|
+
def is_skyhook(self) -> bool:
|
469
|
+
"""Return True if this structure is a skyhook, else False."""
|
470
|
+
return self.eve_type_id == EveTypeId.ORBITAL_SKYHOOK
|
471
|
+
|
467
472
|
@cached_property
|
468
473
|
def is_upwell_structure(self) -> bool:
|
469
474
|
"""Return True if this structure is an upwell structure, else False."""
|
@@ -28,7 +28,7 @@
|
|
28
28
|
<ul id="public-tabs" class="nav nav-tabs" role="tablist">
|
29
29
|
|
30
30
|
<li role="presentation" class="active">
|
31
|
-
<a href="#pocos" aria-controls="
|
31
|
+
<a href="#pocos" aria-controls="orbitals" role="tab" data-toggle="tab">
|
32
32
|
{% translate "Customs Offices" %} <small>({{ pocos_count|default:"-" }})</small>
|
33
33
|
</a>
|
34
34
|
</li>
|
@@ -39,7 +39,7 @@
|
|
39
39
|
<div class="panel-body">
|
40
40
|
<div class="tab-content">
|
41
41
|
|
42
|
-
<div role="tabpanel" class="tab-pane active" id="
|
42
|
+
<div role="tabpanel" class="tab-pane active" id="orbitals">
|
43
43
|
{% include "structures/partials/public/poco_list.html" %}
|
44
44
|
</div>
|
45
45
|
|
{aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/structures.html
RENAMED
@@ -48,8 +48,8 @@
|
|
48
48
|
</li>
|
49
49
|
|
50
50
|
<li role="presentation">
|
51
|
-
<a href="#
|
52
|
-
{% trans "
|
51
|
+
<a href="#orbitals" aria-controls="orbitals" role="tab" data-toggle="tab">
|
52
|
+
{% trans "Orbitals" %} <small>({{ orbitals_count|default:"-" }})</small>
|
53
53
|
</a>
|
54
54
|
</li>
|
55
55
|
|
@@ -77,8 +77,8 @@
|
|
77
77
|
{% include "structures/partials/structures/structure_list.html" %}
|
78
78
|
</div>
|
79
79
|
|
80
|
-
<div role="tabpanel" class="tab-pane" id="
|
81
|
-
{% include "structures/partials/structures/
|
80
|
+
<div role="tabpanel" class="tab-pane" id="orbitals">
|
81
|
+
{% include "structures/partials/structures/orbital_list.html" %}
|
82
82
|
</div>
|
83
83
|
|
84
84
|
<div role="tabpanel" class="tab-pane" id="starbases">
|
@@ -87,7 +87,7 @@
|
|
87
87
|
|
88
88
|
{% if show_jump_gates_tab %}
|
89
89
|
<div role="tabpanel" class="tab-pane" id="jump-gates">
|
90
|
-
{% include "structures/partials/structures/
|
90
|
+
{% include "structures/partials/structures/jump_gate_list.html" %}
|
91
91
|
</div>
|
92
92
|
{% endif %}
|
93
93
|
|
@@ -4,6 +4,7 @@ from app_utils.django import app_labels
|
|
4
4
|
from app_utils.testing import NoSocketsTestCase
|
5
5
|
|
6
6
|
from structures.core import notification_timers
|
7
|
+
from structures.core.notification_types import NotificationType
|
7
8
|
from structures.models import Notification
|
8
9
|
from structures.tests.testdata.factories import (
|
9
10
|
GeneratedNotificationFactory,
|
@@ -107,7 +108,11 @@ if "timerboard" in app_labels():
|
|
107
108
|
@patch(MODULE_PATH + ".STRUCTURES_MOON_EXTRACTION_TIMERS_ENABLED", True)
|
108
109
|
def test_run_all(self):
|
109
110
|
for obj in Notification.objects.all():
|
110
|
-
|
111
|
+
timer_types = NotificationType.relevant_for_timerboard()
|
112
|
+
with self.subTest(notif_type=obj.notif_type):
|
113
|
+
is_timer = obj.notif_type in timer_types
|
114
|
+
is_added = obj.add_or_remove_timer()
|
115
|
+
self.assertEqual(is_timer, is_added)
|
111
116
|
|
112
117
|
@patch(MODULE_PATH + ".STRUCTURES_TIMERS_ARE_CORP_RESTRICTED", False)
|
113
118
|
def test_corp_restriction_1(self):
|
@@ -7,7 +7,7 @@ import yaml
|
|
7
7
|
|
8
8
|
from django.test import TestCase, override_settings
|
9
9
|
from django.utils.timezone import now
|
10
|
-
from eveuniverse.models import EveSolarSystem
|
10
|
+
from eveuniverse.models import EvePlanet, EveSolarSystem
|
11
11
|
|
12
12
|
from app_utils.django import app_labels
|
13
13
|
from app_utils.esi import EsiStatus
|
@@ -22,11 +22,13 @@ from structures.tests.testdata.factories import (
|
|
22
22
|
NotificationFactory,
|
23
23
|
OwnerFactory,
|
24
24
|
RawNotificationFactory,
|
25
|
+
SkyhookFactory,
|
25
26
|
StarbaseFactory,
|
26
27
|
StructureFactory,
|
27
28
|
WebhookFactory,
|
28
29
|
datetime_to_esi,
|
29
30
|
)
|
31
|
+
from structures.tests.testdata.helpers import NearestCelestial
|
30
32
|
from structures.tests.testdata.load_eveuniverse import load_eveuniverse
|
31
33
|
|
32
34
|
if "structuretimers" in app_labels():
|
@@ -613,3 +615,102 @@ class TestTasks(TestCase):
|
|
613
615
|
self.assertEqual(len(embeds), 1)
|
614
616
|
embed = embeds[0]
|
615
617
|
self.assertIn("Territorial Claim Unit", embed.title)
|
618
|
+
|
619
|
+
@patch(OWNERS_PATH + ".STRUCTURES_FEATURE_SKYHOOKS", True)
|
620
|
+
def test_should_fetch_new_skyhooks_from_esi(
|
621
|
+
self, mock_esi_2, mock_esi, mock_execute
|
622
|
+
):
|
623
|
+
# given
|
624
|
+
owner = OwnerFactory()
|
625
|
+
structure = SkyhookFactory(owner=owner)
|
626
|
+
eve_planet = EvePlanet.objects.get(id=40161469)
|
627
|
+
corporation_id = owner.corporation.corporation_id
|
628
|
+
endpoints = [
|
629
|
+
EsiEndpoint(
|
630
|
+
"Assets",
|
631
|
+
"get_corporations_corporation_id_assets",
|
632
|
+
"corporation_id",
|
633
|
+
needs_token=True,
|
634
|
+
data={
|
635
|
+
str(corporation_id): [
|
636
|
+
{
|
637
|
+
"is_singleton": True,
|
638
|
+
"item_id": structure.id,
|
639
|
+
"location_flag": "AutoFit",
|
640
|
+
"location_id": 30002537,
|
641
|
+
"location_type": "solar_system",
|
642
|
+
"quantity": 1,
|
643
|
+
"type_id": 81080,
|
644
|
+
},
|
645
|
+
]
|
646
|
+
},
|
647
|
+
),
|
648
|
+
EsiEndpoint(
|
649
|
+
"Assets",
|
650
|
+
"post_corporations_corporation_id_assets_names",
|
651
|
+
"corporation_id",
|
652
|
+
needs_token=True,
|
653
|
+
data={str(corporation_id): []},
|
654
|
+
),
|
655
|
+
EsiEndpoint(
|
656
|
+
"Assets",
|
657
|
+
"post_corporations_corporation_id_assets_locations",
|
658
|
+
"corporation_id",
|
659
|
+
needs_token=True,
|
660
|
+
data={
|
661
|
+
str(corporation_id): [
|
662
|
+
{"item_id": structure.id, "position": {"x": 1, "y": 2, "z": 3}}
|
663
|
+
]
|
664
|
+
},
|
665
|
+
),
|
666
|
+
EsiEndpoint(
|
667
|
+
"Corporation",
|
668
|
+
"get_corporations_corporation_id_starbases",
|
669
|
+
"corporation_id",
|
670
|
+
needs_token=True,
|
671
|
+
data={str(corporation_id): []},
|
672
|
+
),
|
673
|
+
EsiEndpoint(
|
674
|
+
"Corporation",
|
675
|
+
"get_corporations_corporation_id_structures",
|
676
|
+
"corporation_id",
|
677
|
+
needs_token=True,
|
678
|
+
data={str(corporation_id): []},
|
679
|
+
),
|
680
|
+
EsiEndpoint(
|
681
|
+
"Planetary_Interaction",
|
682
|
+
"get_corporations_corporation_id_customs_offices",
|
683
|
+
"corporation_id",
|
684
|
+
needs_token=True,
|
685
|
+
data={str(corporation_id): []},
|
686
|
+
),
|
687
|
+
EsiEndpoint(
|
688
|
+
"Sovereignty",
|
689
|
+
"get_sovereignty_map",
|
690
|
+
needs_token=False,
|
691
|
+
data=[],
|
692
|
+
),
|
693
|
+
EsiEndpoint(
|
694
|
+
"Universe",
|
695
|
+
"get_universe_structures_structure_id",
|
696
|
+
"structure_id",
|
697
|
+
needs_token=True,
|
698
|
+
data={},
|
699
|
+
),
|
700
|
+
]
|
701
|
+
mock_esi.client = mock_esi_2.client = EsiClientStub.create_from_endpoints(
|
702
|
+
endpoints
|
703
|
+
)
|
704
|
+
structure_id = structure.id
|
705
|
+
structure.delete()
|
706
|
+
# when
|
707
|
+
|
708
|
+
with patch(OWNERS_PATH + ".EveSolarSystem.nearest_celestial") as m:
|
709
|
+
m.return_value = NearestCelestial(
|
710
|
+
eve_object=eve_planet,
|
711
|
+
distance=35_000_000,
|
712
|
+
eve_type=eve_planet.eve_type,
|
713
|
+
)
|
714
|
+
tasks.update_all_structures.delay()
|
715
|
+
# then
|
716
|
+
self.assertTrue(owner.structures.filter(id=structure_id).exists())
|
@@ -46,7 +46,7 @@ class TestStructureListView(TestCase):
|
|
46
46
|
# then
|
47
47
|
self.assertEqual(response.status_code, 200)
|
48
48
|
self.assertEqual(response.context["structures_count"], 2)
|
49
|
-
self.assertEqual(response.context["
|
49
|
+
self.assertEqual(response.context["orbitals_count"], 1)
|
50
50
|
self.assertEqual(response.context["starbases_count"], 1)
|
51
51
|
self.assertEqual(response.context["jump_gates_count"], 1)
|
52
52
|
self.assertIn("data_export", response.context)
|
@@ -376,6 +376,20 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
|
|
376
376
|
structure = Structure.objects.get(id=1000000000002)
|
377
377
|
self.assertEqual(structure.name, "(no data)")
|
378
378
|
|
379
|
+
def test_update_will_not_break_on_403_error_from_structure_info(self, mock_esi):
|
380
|
+
# given
|
381
|
+
new_endpoint = EsiEndpoint(
|
382
|
+
"Universe", "get_universe_structures_structure_id", http_error_code=403
|
383
|
+
)
|
384
|
+
mock_esi.client = self.esi_client_stub.replace_endpoints([new_endpoint])
|
385
|
+
owner = OwnerFactory(user=self.user, structures_last_update_at=None)
|
386
|
+
# when
|
387
|
+
owner.update_structures_esi()
|
388
|
+
# then
|
389
|
+
self.assertFalse(owner.is_structure_sync_fresh)
|
390
|
+
structure = Structure.objects.get(id=1000000000002)
|
391
|
+
self.assertEqual(structure.name, "(no data)")
|
392
|
+
|
379
393
|
@patch(MODULE_PATH + ".Structure.objects.update_or_create_from_dict")
|
380
394
|
def test_update_will_not_break_on_http_error_when_creating_structures(
|
381
395
|
self, mock_create_structure, mock_esi
|