aa-ledger 1.0.4__py3-none-any.whl → 2.0.0__py3-none-any.whl
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_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/METADATA +5 -6
- aa_ledger-2.0.0.dist-info/RECORD +267 -0
- ledger/__init__.py +2 -2
- ledger/admin.py +23 -18
- ledger/api/__init__.py +23 -7
- ledger/api/{ledger/admin.py → admin.py} +25 -31
- ledger/api/alliance.py +755 -0
- ledger/api/character.py +786 -0
- ledger/api/corporation.py +1141 -0
- ledger/api/{helpers.py → helpers/core.py} +33 -33
- ledger/api/helpers/icons.py +372 -0
- ledger/api/helpers/planetary_helper.py +354 -0
- ledger/api/planetary.py +354 -0
- ledger/api/schema.py +240 -15
- ledger/app_settings.py +11 -27
- ledger/auth_hooks.py +2 -2
- ledger/constants.py +50 -177
- ledger/decorators.py +2 -46
- ledger/forms.py +133 -39
- ledger/helpers/billboard.py +194 -144
- ledger/helpers/cache.py +105 -0
- ledger/helpers/discord.py +2 -4
- ledger/helpers/eveonline.py +160 -0
- ledger/helpers/ledger_data.py +23 -0
- ledger/helpers/ref_type.py +53 -78
- ledger/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- ledger/locale/cs_CZ/LC_MESSAGES/django.po +349 -193
- ledger/locale/de/LC_MESSAGES/django.mo +0 -0
- ledger/locale/de/LC_MESSAGES/django.po +528 -379
- ledger/locale/django.pot +721 -546
- ledger/locale/es/LC_MESSAGES/django.mo +0 -0
- ledger/locale/es/LC_MESSAGES/django.po +349 -194
- ledger/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- ledger/locale/fr_FR/LC_MESSAGES/django.po +349 -193
- ledger/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- ledger/locale/it_IT/LC_MESSAGES/django.po +349 -193
- ledger/locale/ja/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ja/LC_MESSAGES/django.po +348 -193
- ledger/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ko_KR/LC_MESSAGES/django.po +349 -193
- ledger/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- ledger/locale/nl_NL/LC_MESSAGES/django.po +349 -193
- ledger/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- ledger/locale/pl_PL/LC_MESSAGES/django.po +350 -193
- ledger/locale/ru/LC_MESSAGES/django.mo +0 -0
- ledger/locale/ru/LC_MESSAGES/django.po +348 -193
- ledger/locale/sk/LC_MESSAGES/django.mo +0 -0
- ledger/locale/sk/LC_MESSAGES/django.po +348 -193
- ledger/locale/uk/LC_MESSAGES/django.mo +0 -0
- ledger/locale/uk/LC_MESSAGES/django.po +348 -193
- ledger/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- ledger/locale/zh_Hans/LC_MESSAGES/django.po +348 -193
- ledger/managers/character_audit_manager.py +28 -20
- ledger/managers/character_journal_manager.py +185 -357
- ledger/managers/character_mining_manager.py +52 -26
- ledger/managers/character_planetary_manager.py +178 -136
- ledger/managers/corporation_audit_manager.py +36 -27
- ledger/managers/corporation_journal_manager.py +92 -56
- ledger/managers/general_manager.py +8 -7
- ledger/migrations/0018_remove_characterplanet_ledger_char_planet__58a5b6_idx_and_more.py +44 -0
- ledger/migrations/0019_rename_characteraudit_characterowner_and_more.py +48 -0
- ledger/models/__init__.py +5 -11
- ledger/models/characteraudit.py +101 -109
- ledger/models/corporationaudit.py +94 -49
- ledger/models/general.py +105 -211
- ledger/models/helpers/update_manager.py +302 -0
- ledger/models/planetary.py +60 -205
- ledger/providers.py +101 -0
- ledger/static/ledger/css/{ledger.css → aa-ledger.css} +54 -28
- ledger/static/ledger/js/aa-ledger.js +124 -0
- ledger/static/ledger/js/charts.js +25 -1
- ledger/static/ledger/js/view-alliance-ledger.js +383 -0
- ledger/static/ledger/js/view-character-ledger.js +388 -0
- ledger/static/ledger/js/view-corporation-ledger.js +402 -0
- ledger/static/ledger/js/view-planetary.js +492 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/flow.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/index.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/percent.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Animated.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Dark.js +2 -0
- ledger/static/ledger/libs/amCharts/5.14.4/js/xy.js +2 -0
- ledger/static/ledger/libs/datatables/2.3.5/css/dataTables.bootstrap5.css +610 -0
- ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.bootstrap5.js +122 -0
- ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.js +14127 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.css +516 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.dataTables.css +529 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.js +73 -0
- ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.js +3090 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.css +20 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.js +1203 -0
- ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.js +59 -0
- ledger/tasks.py +157 -141
- ledger/templates/ledger/base.html +59 -21
- ledger/templates/ledger/bundles/aa-ledger-css.html +3 -0
- ledger/templates/ledger/bundles/aa-ledger-js.html +3 -0
- ledger/templates/ledger/bundles/view-alliance-ledger-js.html +14 -0
- ledger/templates/ledger/bundles/view-character-ledger-js.html +15 -0
- ledger/templates/ledger/bundles/view-character-planetary-css.html +3 -0
- ledger/templates/ledger/bundles/view-character-planetary-js.html +4 -0
- ledger/templates/ledger/bundles/view-corporation-ledger-js.html +15 -0
- ledger/templates/ledger/partials/modal/confirm.html +0 -1
- ledger/templates/ledger/partials/modal/request-accept-delete-alliance.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-delete-character.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-delete-corporation.html +38 -0
- ledger/templates/ledger/partials/modal/request-accept-switch-notification.html +38 -0
- ledger/templates/ledger/partials/modal/request-view-alliance-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-character-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-corporation-details.html +26 -0
- ledger/templates/ledger/partials/modal/request-view-extractor.html +32 -0
- ledger/templates/ledger/partials/modal/request-view-factory.html +31 -0
- ledger/templates/ledger/partials/{menu → navigation}/administration.html +8 -0
- ledger/templates/ledger/partials/{menu → navigation}/navigation.html +2 -2
- ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance_corporations.html +3 -3
- ledger/templates/ledger/partials/view-alliance-administration/dashboard.html +81 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-billboard.html +25 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-alliance-ledger/alliance-table.html +24 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-alliance-ledger/information/summary.html +19 -0
- ledger/templates/ledger/partials/{administration → view-character-administration}/character.html +1 -9
- ledger/templates/ledger/partials/{administration → view-character-administration}/dashboard.html +0 -34
- ledger/templates/ledger/partials/view-character-ledger/character-billboard.html +25 -0
- ledger/templates/ledger/partials/view-character-ledger/character-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-character-ledger/character-table.html +25 -0
- ledger/templates/ledger/partials/view-character-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-character-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-character-ledger/information/summary.html +19 -0
- ledger/templates/ledger/partials/view-character-planetary/extractor-table.html +24 -0
- ledger/templates/ledger/partials/view-character-planetary/factory-table.html +24 -0
- ledger/templates/ledger/partials/view-character-planetary/planetary-table.html +22 -0
- ledger/templates/ledger/partials/view-character-planetary/storage-table.html +23 -0
- ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation.html +5 -13
- ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation_characters.html +1 -1
- ledger/templates/ledger/partials/view-corporation-administration/dashboard.html +81 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-billboard.html +25 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-ledger-details.html +21 -0
- ledger/templates/ledger/partials/view-corporation-ledger/corporation-table.html +26 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/daily.html +18 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/hourly.html +18 -0
- ledger/templates/ledger/partials/view-corporation-ledger/information/summary.html +19 -0
- ledger/templates/ledger/view-administration.html +62 -0
- ledger/templates/ledger/view-alliance-administration.html +49 -0
- ledger/templates/ledger/view-alliance-ledger.html +72 -0
- ledger/templates/ledger/view-alliance-overview.html +131 -0
- ledger/templates/ledger/view-character-administration.html +42 -0
- ledger/templates/ledger/view-character-ledger.html +73 -0
- ledger/templates/ledger/view-character-overview.html +135 -0
- ledger/templates/ledger/view-character-planetary-overview.html +135 -0
- ledger/templates/ledger/view-character-planetary.html +73 -0
- ledger/templates/ledger/view-corporation-administration.html +42 -0
- ledger/templates/ledger/view-corporation-ledger.html +73 -0
- ledger/templates/ledger/view-corporation-overview.html +131 -0
- ledger/templatetags/ledger.py +3 -5
- ledger/tests/__init__.py +187 -0
- ledger/tests/test_admin.py +164 -68
- ledger/tests/test_auth_hook.py +31 -13
- ledger/tests/test_decarators.py +14 -79
- ledger/tests/test_discord_installed.py +0 -1
- ledger/tests/test_helpers/test_ledger_data.py +19 -0
- ledger/tests/test_managers/test_character_audit_manager.py +111 -69
- ledger/tests/test_managers/test_character_journal_manager.py +48 -208
- ledger/tests/test_managers/test_character_mining_manager.py +37 -16
- ledger/tests/test_managers/test_corporation_division_manager.py +66 -28
- ledger/tests/test_managers/test_corporation_journal_manager.py +39 -42
- ledger/tests/test_managers/test_general_manager.py +78 -18
- ledger/tests/test_managers/test_planetary_manager.py +73 -32
- ledger/tests/test_models/test_characteraudit.py +58 -74
- ledger/tests/test_models/test_characterminingledger.py +20 -26
- ledger/tests/test_models/test_characterwalletjournal.py +10 -33
- ledger/tests/test_models/test_corporationaudit.py +41 -35
- ledger/tests/test_models/test_corporationwalletjournal.py +35 -32
- ledger/tests/test_models/test_general.py +44 -11
- ledger/tests/test_models/test_planetary.py +14 -80
- ledger/tests/test_templatetags.py +2 -7
- ledger/tests/test_views/corporation/test_add_corp.py +16 -35
- ledger/tests/test_views/corporation/test_delete_corporation.py +66 -42
- ledger/tests/test_views/test_access.py +512 -545
- ledger/tests/test_views/test_add_ally.py +57 -46
- ledger/tests/test_views/test_add_char.py +21 -33
- ledger/tests/test_views/test_delete_character.py +24 -21
- ledger/tests/testdata/README_ESI_STUB.md +430 -0
- ledger/tests/testdata/esi_stub_openapi.py +511 -0
- ledger/tests/testdata/integrations/__init__.py +0 -0
- ledger/tests/testdata/{load_eveuniverse.py → integrations/eveuniverse.py} +0 -1
- ledger/tests/testdata/integrations/planetary.py +13 -0
- ledger/tests/testdata/json/factory.json +281 -0
- ledger/tests/testdata/json/inactive.json +281 -0
- ledger/tests/testdata/json/pins.json +175 -272
- ledger/tests/testdata/json/route.json +95 -528
- ledger/tests/testdata/test_esi_stub.py +468 -0
- ledger/tests/testdata/utils.py +601 -0
- ledger/thirdparty/charlink_hook.py +60 -30
- ledger/urls.py +0 -135
- ledger/views/alliance/add_ally.py +2 -4
- ledger/views/alliance/alliance_ledger.py +64 -147
- ledger/views/character/add_char.py +8 -10
- ledger/views/character/character_ledger.py +60 -126
- ledger/views/character/planetary.py +5 -98
- ledger/views/corporation/add_corp.py +10 -12
- ledger/views/corporation/corporation_ledger.py +65 -327
- ledger/views/index.py +92 -30
- aa_ledger-1.0.4.dist-info/RECORD +0 -236
- ledger/api/api_helper/planetary_helper.py +0 -107
- ledger/api/ledger/__init__.py +0 -7
- ledger/api/ledger/planetary.py +0 -231
- ledger/helpers/alliance.py +0 -317
- ledger/helpers/character.py +0 -251
- ledger/helpers/core.py +0 -665
- ledger/helpers/corporation.py +0 -427
- ledger/helpers/data_exporter.py +0 -452
- ledger/static/ledger/js/planetary-confirm.js +0 -66
- ledger/static/ledger/js/planetary.js +0 -143
- ledger/templates/ledger/admin.html +0 -43
- ledger/templates/ledger/allyledger/admin/alliance_administration.html +0 -46
- ledger/templates/ledger/allyledger/admin/alliance_overview.html +0 -108
- ledger/templates/ledger/allyledger/alliance_ledger.html +0 -86
- ledger/templates/ledger/bundles/character-ledger-bundles.html +0 -66
- ledger/templates/ledger/bundles/corporation-ledger-bundles.html +0 -75
- ledger/templates/ledger/bundles/ledger-bundles.html +0 -23
- ledger/templates/ledger/bundles/ledger-css.html +0 -3
- ledger/templates/ledger/bundles/planetary-bundles.html +0 -50
- ledger/templates/ledger/bundles/table-css.html +0 -3
- ledger/templates/ledger/charledger/admin/character_administration.html +0 -39
- ledger/templates/ledger/charledger/admin/character_overview.html +0 -106
- ledger/templates/ledger/charledger/character_ledger.html +0 -94
- ledger/templates/ledger/charledger/planetary/admin/planetary_overview.html +0 -123
- ledger/templates/ledger/charledger/planetary/planetary_ledger.html +0 -54
- ledger/templates/ledger/corpledger/admin/corporation_administration.html +0 -39
- ledger/templates/ledger/corpledger/admin/corporation_overview.html +0 -108
- ledger/templates/ledger/corpledger/corporation_ledger.html +0 -129
- ledger/templates/ledger/data-export.html +0 -78
- ledger/templates/ledger/error.html +0 -31
- ledger/templates/ledger/partials/form/error-message.html +0 -1
- ledger/templates/ledger/partials/information/daily.html +0 -56
- ledger/templates/ledger/partials/information/day.html +0 -48
- ledger/templates/ledger/partials/information/error.html +0 -8
- ledger/templates/ledger/partials/information/hourly.html +0 -53
- ledger/templates/ledger/partials/information/summary.html +0 -88
- ledger/templates/ledger/partials/information/view_character_content.html +0 -35
- ledger/templates/ledger/partials/modal/switchalarm_confirm.html +0 -39
- ledger/templates/ledger/partials/modal/view_extractor.html +0 -48
- ledger/templates/ledger/partials/modal/view_factory.html +0 -123
- ledger/templates/ledger/partials/table/char-ledger.html +0 -85
- ledger/templates/ledger/partials/table/corp-ledger.html +0 -66
- ledger/templates/ledger/partials/table/planetary.html +0 -18
- ledger/templates/ledger/partials/thirdparty/billboard.html +0 -22
- ledger/templates/ledger/partials/view/card.html +0 -160
- ledger/templates/ledger/permission.html +0 -2
- ledger/tests/test_helpers/test_billboard.py +0 -11
- ledger/tests/test_helpers/test_data_exporter.py +0 -207
- ledger/tests/test_tasks.py +0 -282
- ledger/tests/test_view_helpers/test_core.py +0 -47
- ledger/tests/test_views/corporation/test_corporation.py +0 -267
- ledger/tests/test_views/test_planetary.py +0 -137
- ledger/tests/testdata/esi_stub.py +0 -109
- ledger/tests/testdata/esi_stub_migration.py +0 -80
- ledger/tests/testdata/generate_characteraudit.py +0 -106
- ledger/tests/testdata/generate_corporationaudit.py +0 -74
- ledger/tests/testdata/generate_events.py +0 -31
- ledger/tests/testdata/generate_miningledger.py +0 -13
- ledger/tests/testdata/generate_planets.py +0 -48
- ledger/tests/testdata/generate_walletjournal.py +0 -42
- ledger/tests/testdata/json/czarno-pins.json +0 -240
- ledger/tests/testdata/json/czarno-routes.json +0 -165
- ledger/tests/testdata/json/pins2.json +0 -538
- {aa_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/WHEEL +0 -0
- {aa_ledger-1.0.4.dist-info → aa_ledger-2.0.0.dist-info}/licenses/LICENSE +0 -0
- /ledger/{tests/test_view_helpers → api/helpers}/__init__.py +0 -0
- /ledger/templates/ledger/bundles/{ally-administration-bundles.html → view-alliance-administration-js.html} +0 -0
- /ledger/templates/ledger/bundles/{char-administration-bundles.html → view-character-administration-js.html} +0 -0
- /ledger/templates/ledger/bundles/{corp-administration-bundles.html → view-corporation-administration-js.html} +0 -0
- /ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance.html +0 -0
- /ledger/tests/testdata/{esi.json → esi_test_data.json} +0 -0
- /ledger/tests/testdata/{allianceauth.json → integrations/allianceauth.json} +0 -0
- /ledger/tests/testdata/{load_allianceauth.py → integrations/allianceauth.py} +0 -0
- /ledger/tests/testdata/{eveentity.json → integrations/eveentity.json} +0 -0
- /ledger/tests/testdata/{load_eveentity.py → integrations/eveentity.py} +0 -0
- /ledger/tests/testdata/{eveuniverse.json → integrations/eveuniverse.json} +0 -0
- /ledger/tests/testdata/{planetary.json → integrations/planetary.json} +0 -0
|
@@ -4,22 +4,22 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
# Django
|
|
5
5
|
from django.db import models, transaction
|
|
6
6
|
from django.utils import timezone
|
|
7
|
+
from django.utils.dateparse import parse_datetime
|
|
7
8
|
|
|
8
9
|
# Alliance Auth
|
|
9
10
|
from allianceauth.services.hooks import get_extension_logger
|
|
10
11
|
from esi.exceptions import HTTPNotModified
|
|
11
12
|
|
|
12
13
|
# Alliance Auth (External Libs)
|
|
13
|
-
from app_utils.logging import LoggerAddTag
|
|
14
14
|
from eveuniverse.models import EvePlanet, EveType
|
|
15
15
|
|
|
16
16
|
# AA Ledger
|
|
17
17
|
from ledger import __title__
|
|
18
18
|
from ledger.app_settings import LEDGER_BULK_BATCH_SIZE
|
|
19
|
-
from ledger.constants import COMMAND_CENTER, EXTRACTOR_CONTROL_UNIT, SPACEPORTS
|
|
20
19
|
from ledger.decorators import log_timing
|
|
21
|
-
from ledger.models.characteraudit import
|
|
22
|
-
from ledger.
|
|
20
|
+
from ledger.models.characteraudit import CharacterOwner
|
|
21
|
+
from ledger.models.helpers.update_manager import CharacterUpdateSection
|
|
22
|
+
from ledger.providers import AppLogger, esi
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING: # pragma: no cover
|
|
25
25
|
# Alliance Auth
|
|
@@ -28,9 +28,10 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
28
28
|
|
|
29
29
|
# AA Ledger
|
|
30
30
|
from ledger.models.general import UpdateSectionResult
|
|
31
|
-
from ledger.models.planetary import CharacterPlanet
|
|
31
|
+
from ledger.models.planetary import CharacterPlanet as PlanetContext
|
|
32
|
+
from ledger.models.planetary import CharacterPlanetDetails as PlanetDetailsContext
|
|
32
33
|
|
|
33
|
-
logger =
|
|
34
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
def to_json_serializable(data):
|
|
@@ -45,50 +46,46 @@ def to_json_serializable(data):
|
|
|
45
46
|
return data
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
class
|
|
49
|
-
pass
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class PlanetaryManagerBase(models.Manager):
|
|
49
|
+
class CharacterPlanetManager(models.Manager["PlanetContext"]):
|
|
53
50
|
@log_timing(logger)
|
|
54
51
|
def update_or_create_esi(
|
|
55
|
-
self,
|
|
52
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
56
53
|
) -> "UpdateSectionResult":
|
|
57
54
|
"""Update or Create a planets entry from ESI data."""
|
|
58
|
-
return
|
|
59
|
-
section=
|
|
55
|
+
return owner.update_manager.update_section_if_changed(
|
|
56
|
+
section=CharacterUpdateSection.PLANETS,
|
|
60
57
|
fetch_func=self._fetch_esi_data,
|
|
61
58
|
force_refresh=force_refresh,
|
|
62
59
|
)
|
|
63
60
|
|
|
64
61
|
def _fetch_esi_data(
|
|
65
|
-
self,
|
|
62
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
66
63
|
) -> None:
|
|
67
64
|
"""Fetch planetary entries from ESI data."""
|
|
68
65
|
req_scopes = ["esi-planets.manage_planets.v1"]
|
|
69
|
-
token =
|
|
66
|
+
token = owner.get_token(scopes=req_scopes)
|
|
70
67
|
|
|
71
68
|
# Make the ESI request
|
|
72
69
|
operation = esi.client.Planetary_Interaction.GetCharactersCharacterIdPlanets(
|
|
73
|
-
character_id=
|
|
70
|
+
character_id=owner.eve_character.character_id,
|
|
74
71
|
token=token,
|
|
75
72
|
)
|
|
76
73
|
|
|
77
74
|
planets_items = operation.results(force_refresh=force_refresh)
|
|
78
75
|
|
|
79
|
-
self._update_or_create_objs(
|
|
76
|
+
self._update_or_create_objs(owner=owner, objs=planets_items)
|
|
80
77
|
|
|
81
78
|
@transaction.atomic()
|
|
82
79
|
def _update_or_create_objs(
|
|
83
|
-
self,
|
|
80
|
+
self, owner: CharacterOwner, objs: list["PlanetGetItem"]
|
|
84
81
|
) -> None:
|
|
85
82
|
"""Update or Create planets entries from objs data."""
|
|
86
83
|
# pylint: disable=import-outside-toplevel
|
|
87
84
|
# AA Ledger
|
|
88
85
|
from ledger.models.planetary import CharacterPlanetDetails
|
|
89
86
|
|
|
90
|
-
_current_planets = self.filter(character=
|
|
91
|
-
"
|
|
87
|
+
_current_planets = self.filter(character=owner).values_list(
|
|
88
|
+
"eve_planet_id", flat=True
|
|
92
89
|
)
|
|
93
90
|
|
|
94
91
|
_planets_ids = []
|
|
@@ -100,16 +97,16 @@ class PlanetaryManagerBase(models.Manager):
|
|
|
100
97
|
_planets_ids.append(eve_planet.id)
|
|
101
98
|
|
|
102
99
|
try:
|
|
103
|
-
e_planet = self.get(character=
|
|
100
|
+
e_planet = self.get(character=owner, eve_planet=eve_planet)
|
|
104
101
|
prim_key = e_planet.id
|
|
105
102
|
except self.model.DoesNotExist:
|
|
106
103
|
prim_key = None
|
|
107
104
|
|
|
108
105
|
planet = self.model(
|
|
109
106
|
id=prim_key,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
name=eve_planet.name,
|
|
108
|
+
character=owner,
|
|
109
|
+
eve_planet=eve_planet,
|
|
113
110
|
upgrade_level=planet.upgrade_level,
|
|
114
111
|
num_pins=planet.num_pins,
|
|
115
112
|
)
|
|
@@ -130,39 +127,22 @@ class PlanetaryManagerBase(models.Manager):
|
|
|
130
127
|
|
|
131
128
|
# Delete Planets that are no longer in the list
|
|
132
129
|
obsolete_planets = set(_current_planets) - set(_planets_ids)
|
|
133
|
-
self.filter(character=
|
|
130
|
+
self.filter(character=owner, eve_planet_id__in=obsolete_planets).delete()
|
|
134
131
|
# Delete Planet Details that are no longer in the list
|
|
135
132
|
CharacterPlanetDetails.objects.filter(
|
|
136
|
-
planet__character=
|
|
133
|
+
planet__character=owner, planet__eve_planet_id__in=obsolete_planets
|
|
137
134
|
).delete()
|
|
138
135
|
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
144
|
-
def get_or_create_facilitys(self, planet: "CharacterPlanet"):
|
|
145
|
-
"""Get or Create Facilitys for a given Planet"""
|
|
146
|
-
return self._get_or_create_facilitys(planet=planet)
|
|
147
|
-
|
|
148
|
-
def _get_or_create_facilitys(self, planet: "CharacterPlanet"):
|
|
149
|
-
try:
|
|
150
|
-
facilitys = self.get(planet=planet)
|
|
151
|
-
facility = facilitys.facilitys
|
|
152
|
-
created = False
|
|
153
|
-
return facility, created
|
|
154
|
-
except self.model.DoesNotExist:
|
|
155
|
-
facility, created = self.update_or_create_facilitys(planet=planet)
|
|
156
|
-
return facility, created
|
|
157
|
-
|
|
137
|
+
class PlanetDetailsQuerySet(models.QuerySet):
|
|
158
138
|
def update_or_create_layout(
|
|
159
139
|
self,
|
|
160
|
-
|
|
161
|
-
planet: "
|
|
140
|
+
owner: CharacterOwner,
|
|
141
|
+
planet: "PlanetDetailsContext",
|
|
162
142
|
objs: list["PlanetDetailsItem"],
|
|
163
143
|
):
|
|
164
144
|
"""Update or Create Layout for a given Planet"""
|
|
165
|
-
return self._update_or_create(
|
|
145
|
+
return self._update_or_create(owner=owner, planet=planet, objs=objs)
|
|
166
146
|
|
|
167
147
|
def _convert_to_dict(
|
|
168
148
|
self,
|
|
@@ -176,13 +156,14 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
176
156
|
|
|
177
157
|
def _update_or_create(
|
|
178
158
|
self,
|
|
179
|
-
|
|
180
|
-
planet: "
|
|
159
|
+
owner: CharacterOwner,
|
|
160
|
+
planet: "PlanetDetailsContext",
|
|
181
161
|
objs: list["PlanetDetailsItem"],
|
|
182
|
-
):
|
|
162
|
+
) -> tuple["PlanetDetailsContext", bool]:
|
|
183
163
|
"""Update or Create Layout for a given Planet"""
|
|
184
164
|
if not isinstance(objs, list):
|
|
185
165
|
objs = [objs]
|
|
166
|
+
|
|
186
167
|
for result in objs:
|
|
187
168
|
links = self._convert_to_dict(result.links)
|
|
188
169
|
pins = self._convert_to_dict(result.pins)
|
|
@@ -190,66 +171,147 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
190
171
|
|
|
191
172
|
planetdetails, created = self.update_or_create(
|
|
192
173
|
planet=planet,
|
|
193
|
-
character=
|
|
174
|
+
character=owner,
|
|
194
175
|
defaults={
|
|
195
176
|
"links": links,
|
|
196
177
|
"pins": pins,
|
|
197
178
|
"routes": routes,
|
|
198
|
-
"
|
|
179
|
+
"factories": None,
|
|
199
180
|
},
|
|
200
181
|
)
|
|
201
182
|
|
|
202
|
-
self.
|
|
183
|
+
self._update_factory(planetdetails)
|
|
203
184
|
|
|
204
|
-
logger.debug("Planet %s
|
|
185
|
+
logger.debug("Planet %s Factories Updated", planetdetails)
|
|
205
186
|
|
|
206
187
|
return planetdetails, created
|
|
207
188
|
|
|
208
|
-
def
|
|
209
|
-
facility_info = self.get_facility_info(planet)
|
|
210
|
-
planet.facilitys = facility_info
|
|
211
|
-
planet.save()
|
|
212
|
-
return planet
|
|
189
|
+
def _update_factory(self, planet: "PlanetDetailsContext"):
|
|
213
190
|
|
|
214
|
-
|
|
215
|
-
def get_facility_info(self, planet: "CharacterPlanetDetails"):
|
|
216
|
-
facility_info = {}
|
|
191
|
+
factory_dict = {}
|
|
217
192
|
|
|
218
193
|
# Process pins
|
|
219
194
|
for pin in planet.pins:
|
|
220
195
|
pin_id = pin["pin_id"]
|
|
221
196
|
item_type, _ = EveType.objects.get_or_create_esi(id=pin["type_id"])
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
197
|
+
|
|
198
|
+
# Skip Command Center
|
|
199
|
+
if pin["type_id"] in EveType.objects.filter(eve_group_id=1027).values_list(
|
|
200
|
+
"id", flat=True
|
|
226
201
|
):
|
|
227
202
|
continue
|
|
228
|
-
|
|
203
|
+
|
|
204
|
+
# Create Facility Pin Entry
|
|
205
|
+
factory_dict[pin_id] = {
|
|
229
206
|
"facility_id": pin["type_id"],
|
|
230
207
|
"facility_name": item_type.name,
|
|
231
|
-
"
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
},
|
|
208
|
+
"facility_type": (
|
|
209
|
+
item_type.eve_group.name if item_type.eve_group else "N/A"
|
|
210
|
+
),
|
|
211
|
+
"ressources": [],
|
|
236
212
|
}
|
|
237
213
|
|
|
238
|
-
|
|
214
|
+
# Spaceport and Storage Facility
|
|
215
|
+
if pin["type_id"] in EveType.objects.filter(
|
|
216
|
+
eve_group_id__in=[1029, 1030]
|
|
217
|
+
).values_list("id", flat=True):
|
|
218
|
+
factory_dict[pin_id]["storage"] = {}
|
|
219
|
+
self._storage_info(pin, factory_dict[pin_id])
|
|
239
220
|
|
|
240
|
-
|
|
221
|
+
# Extractor
|
|
222
|
+
if pin["type_id"] in EveType.objects.filter(eve_group_id=1063).values_list(
|
|
223
|
+
"id", flat=True
|
|
224
|
+
):
|
|
225
|
+
factory_dict[pin_id]["extractor"] = {}
|
|
226
|
+
self._extractor_info(pin, factory_dict[pin_id])
|
|
241
227
|
|
|
242
|
-
|
|
228
|
+
self._factory_production_chain(planet, factory_dict)
|
|
243
229
|
|
|
244
|
-
|
|
245
|
-
|
|
230
|
+
planet.factories = factory_dict
|
|
231
|
+
planet.save()
|
|
232
|
+
return planet
|
|
233
|
+
|
|
234
|
+
def _storage_info(self, pin: dict, facility_dict: dict):
|
|
235
|
+
"""Update per-facility dict and add all Storage Information."""
|
|
236
|
+
for content in pin.get("contents", []):
|
|
237
|
+
item_type, _ = EveType.objects.get_or_create_esi(id=content["type_id"])
|
|
238
|
+
|
|
239
|
+
item_type_id = content["type_id"]
|
|
240
|
+
item_amount = content["amount"]
|
|
241
|
+
|
|
242
|
+
if item_type_id in facility_dict["storage"]:
|
|
243
|
+
facility_dict["storage"][item_type_id]["amount"] += item_amount
|
|
244
|
+
else:
|
|
245
|
+
facility_dict["storage"][item_type_id] = {
|
|
246
|
+
"item_id": item_type_id,
|
|
247
|
+
"item_name": item_type.name,
|
|
248
|
+
"amount": item_amount,
|
|
249
|
+
}
|
|
250
|
+
return facility_dict
|
|
251
|
+
|
|
252
|
+
def _extractor_info(self, pin: dict, factory_dict: dict):
|
|
253
|
+
"""Update dict and add all Extractor Information to the given dict"""
|
|
254
|
+
# Update Extractor Information (ensure None is treated as empty dict)
|
|
255
|
+
extractor_details = pin.get("extractor_details") or {}
|
|
256
|
+
product_type_id = extractor_details.get("product_type_id")
|
|
257
|
+
product_type_name = "N/A"
|
|
258
|
+
|
|
259
|
+
# Get Product Eve Type
|
|
260
|
+
if product_type_id:
|
|
261
|
+
item_type, _ = EveType.objects.get_or_create_esi(id=product_type_id)
|
|
262
|
+
product_type_name = item_type.name
|
|
263
|
+
|
|
264
|
+
# Use timezone-aware datetimes and compute elapsed/total seconds
|
|
265
|
+
current_time = timezone.now()
|
|
266
|
+
|
|
267
|
+
install_time = None
|
|
268
|
+
if pin.get("install_time") is not None:
|
|
269
|
+
install_time = parse_datetime(pin.get("install_time"))
|
|
270
|
+
expiry_time = None
|
|
271
|
+
if pin.get("expiry_time") is not None:
|
|
272
|
+
expiry_time = parse_datetime(pin.get("expiry_time"))
|
|
273
|
+
|
|
274
|
+
# Create Extractor Info Entry on the per-facility dict
|
|
275
|
+
factory_dict["extractor"] = {
|
|
276
|
+
"head_count": extractor_details.get("head_count"),
|
|
277
|
+
"product_type_id": product_type_id,
|
|
278
|
+
"product_type_name": product_type_name,
|
|
279
|
+
"install_time": str(install_time),
|
|
280
|
+
"expiry_time": str(expiry_time),
|
|
281
|
+
"cycle_time": extractor_details.get("cycle_time"),
|
|
282
|
+
"progress_percentage": None,
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
is_running = False
|
|
286
|
+
# Calculate progress as percentage (0-100) based on elapsed time
|
|
287
|
+
if install_time and expiry_time:
|
|
288
|
+
total_seconds = (expiry_time - install_time).total_seconds()
|
|
289
|
+
if total_seconds > 0:
|
|
290
|
+
elapsed_seconds = (current_time - install_time).total_seconds()
|
|
291
|
+
progress = (elapsed_seconds / total_seconds) * 100.0
|
|
292
|
+
progress = max(0.0, min(progress, 100.0))
|
|
293
|
+
factory_dict["extractor"]["progress_percentage"] = round(progress, 2)
|
|
294
|
+
|
|
295
|
+
# Extractor is running
|
|
296
|
+
if progress < 100.0:
|
|
297
|
+
is_running = True
|
|
298
|
+
|
|
299
|
+
# Store is_running status
|
|
300
|
+
factory_dict["extractor"]["is_running"] = is_running
|
|
301
|
+
|
|
302
|
+
# pylint: disable=too-many-locals
|
|
303
|
+
def _factory_production_chain(
|
|
304
|
+
self, planet: "PlanetDetailsContext", factory_dict: dict
|
|
246
305
|
):
|
|
247
306
|
"""Update dict and add all Production Information to the given dict"""
|
|
307
|
+
item_ids = set()
|
|
308
|
+
for facility in factory_dict.values():
|
|
309
|
+
for storage_item in facility.get("storage", {}).values():
|
|
310
|
+
item_ids.add(storage_item["item_id"])
|
|
248
311
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
]
|
|
312
|
+
extractor_product = facility.get("extractor", {}).get("product_type_id")
|
|
313
|
+
if extractor_product:
|
|
314
|
+
item_ids.add(extractor_product)
|
|
253
315
|
|
|
254
316
|
for route in planet.routes:
|
|
255
317
|
destination_pin_id = route["destination_pin_id"]
|
|
@@ -258,69 +320,54 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
258
320
|
id=route["content_type_id"]
|
|
259
321
|
)
|
|
260
322
|
|
|
261
|
-
if destination_pin_id in
|
|
323
|
+
if destination_pin_id in factory_dict:
|
|
262
324
|
req_quantity = route["quantity"]
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
)
|
|
266
|
-
|
|
325
|
+
storage = factory_dict[destination_pin_id].get("storage", {})
|
|
326
|
+
current_quantity = storage.get(content_type.id, {}).get("amount", 0)
|
|
327
|
+
missing_quantity = max((req_quantity - current_quantity), 0)
|
|
328
|
+
|
|
267
329
|
still_producing = (
|
|
268
|
-
content_type.id in
|
|
269
|
-
if not planet.is_expired
|
|
270
|
-
else False
|
|
330
|
+
content_type.id in item_ids if not planet.is_expired else False
|
|
271
331
|
)
|
|
272
332
|
|
|
333
|
+
is_active = still_producing and missing_quantity > 0
|
|
334
|
+
|
|
273
335
|
resource = {
|
|
274
336
|
"item_id": content_type.id,
|
|
275
337
|
"item_name": content_type.name,
|
|
276
338
|
"req_quantity": req_quantity,
|
|
277
339
|
"current_quantity": current_quantity,
|
|
278
|
-
"missing_quantity":
|
|
279
|
-
"
|
|
340
|
+
"missing_quantity": missing_quantity,
|
|
341
|
+
"is_active": is_active,
|
|
280
342
|
}
|
|
281
|
-
|
|
343
|
+
factory_dict[destination_pin_id]["ressources"].append(resource)
|
|
282
344
|
|
|
283
|
-
if source_pin_id in
|
|
284
|
-
|
|
345
|
+
if source_pin_id in factory_dict:
|
|
346
|
+
factory_dict[source_pin_id]["output_product"] = {
|
|
285
347
|
"item_id": content_type.id,
|
|
286
348
|
"item_name": content_type.name,
|
|
287
349
|
"output_quantity": route["quantity"],
|
|
288
350
|
}
|
|
289
|
-
return
|
|
290
|
-
|
|
291
|
-
def _facility_produce_depend(self, planet, facility_info):
|
|
292
|
-
"""Check if Facility is Producing"""
|
|
293
|
-
for facility in facility_info.values():
|
|
294
|
-
for resource in facility["resources"]:
|
|
295
|
-
self._facility_still_producing(planet, resource, facility_info)
|
|
296
|
-
return facility_info
|
|
297
|
-
|
|
298
|
-
def _facility_still_producing(self, planet, resource, facility_info) -> bool:
|
|
299
|
-
"""Check if ressource exist in Production Chain and change State"""
|
|
300
|
-
for other_facility in facility_info.values():
|
|
301
|
-
if (
|
|
302
|
-
"output_product" in other_facility
|
|
303
|
-
and other_facility["output_product"]["item_id"] == resource["item_id"]
|
|
304
|
-
and not planet.is_expired
|
|
305
|
-
):
|
|
306
|
-
if other_facility["output_product"]["output_quantity"] > 0:
|
|
307
|
-
resource["still_producing"] = True
|
|
351
|
+
return factory_dict
|
|
308
352
|
|
|
309
353
|
|
|
310
|
-
class
|
|
354
|
+
class PlanetDetailsManager(models.Manager["PlanetDetailsContext"]):
|
|
355
|
+
def get_queryset(self):
|
|
356
|
+
return PlanetDetailsQuerySet(self.model, using=self._db)
|
|
357
|
+
|
|
311
358
|
@log_timing(logger)
|
|
312
359
|
def update_or_create_esi(
|
|
313
|
-
self,
|
|
360
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
314
361
|
) -> "UpdateSectionResult":
|
|
315
362
|
"""Update or Create a planets details entry from ESI data."""
|
|
316
|
-
return
|
|
317
|
-
section=
|
|
363
|
+
return owner.update_manager.update_section_if_changed(
|
|
364
|
+
section=CharacterUpdateSection.PLANETS_DETAILS,
|
|
318
365
|
fetch_func=self._fetch_esi_data,
|
|
319
366
|
force_refresh=force_refresh,
|
|
320
367
|
)
|
|
321
368
|
|
|
322
369
|
def _fetch_esi_data(
|
|
323
|
-
self,
|
|
370
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
324
371
|
) -> None:
|
|
325
372
|
"""Fetch planets details entries from ESI data."""
|
|
326
373
|
# pylint: disable=import-outside-toplevel
|
|
@@ -329,17 +376,17 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
329
376
|
|
|
330
377
|
req_scopes = ["esi-planets.manage_planets.v1"]
|
|
331
378
|
|
|
332
|
-
token =
|
|
379
|
+
token = owner.get_token(scopes=req_scopes)
|
|
333
380
|
|
|
334
|
-
planets_ids = CharacterPlanet.objects.filter(character=
|
|
335
|
-
"
|
|
381
|
+
planets_ids = CharacterPlanet.objects.filter(character=owner).values_list(
|
|
382
|
+
"eve_planet_id", flat=True
|
|
336
383
|
)
|
|
337
384
|
is_updated = False
|
|
338
385
|
|
|
339
386
|
for planet_id in planets_ids:
|
|
340
387
|
# Make the ESI request
|
|
341
388
|
operation = esi.client.Planetary_Interaction.GetCharactersCharacterIdPlanetsPlanetId(
|
|
342
|
-
character_id=
|
|
389
|
+
character_id=owner.eve_character.character_id,
|
|
343
390
|
planet_id=planet_id,
|
|
344
391
|
token=token,
|
|
345
392
|
)
|
|
@@ -351,7 +398,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
351
398
|
continue
|
|
352
399
|
|
|
353
400
|
self._update_or_create_objs(
|
|
354
|
-
|
|
401
|
+
owner=owner,
|
|
355
402
|
objs=planets_details_items,
|
|
356
403
|
planet_id=planet_id,
|
|
357
404
|
)
|
|
@@ -362,7 +409,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
362
409
|
@transaction.atomic()
|
|
363
410
|
def _update_or_create_objs(
|
|
364
411
|
self,
|
|
365
|
-
|
|
412
|
+
owner: CharacterOwner,
|
|
366
413
|
objs: list["PlanetDetailsItem"],
|
|
367
414
|
planet_id: int,
|
|
368
415
|
) -> None:
|
|
@@ -373,18 +420,18 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
373
420
|
|
|
374
421
|
try:
|
|
375
422
|
character_planet = CharacterPlanet.objects.get(
|
|
376
|
-
character=
|
|
423
|
+
character=owner, eve_planet_id=planet_id
|
|
377
424
|
)
|
|
378
425
|
except CharacterPlanet.DoesNotExist:
|
|
379
426
|
logger.warning(
|
|
380
427
|
"Planet %s not found for character %s",
|
|
381
428
|
planet_id,
|
|
382
|
-
|
|
429
|
+
owner.eve_character.character_name,
|
|
383
430
|
)
|
|
384
431
|
return
|
|
385
432
|
|
|
386
|
-
planet_details, created = self.update_or_create_layout(
|
|
387
|
-
|
|
433
|
+
planet_details, created = self.get_queryset().update_or_create_layout(
|
|
434
|
+
owner=owner,
|
|
388
435
|
planet=character_planet,
|
|
389
436
|
objs=objs,
|
|
390
437
|
)
|
|
@@ -394,7 +441,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
394
441
|
if planet_details.is_expired and planet_details.last_alert is None:
|
|
395
442
|
logger.debug(
|
|
396
443
|
"Planet %s Extractor Heads Expired for: %s",
|
|
397
|
-
planet_details.planet.
|
|
444
|
+
planet_details.planet.eve_planet.name,
|
|
398
445
|
planet_details.planet.character.eve_character.character_name,
|
|
399
446
|
)
|
|
400
447
|
planet_details.last_alert = timezone.now()
|
|
@@ -408,14 +455,9 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
408
455
|
logger.debug(
|
|
409
456
|
"Notification Reseted for %s Planet: %s",
|
|
410
457
|
planet_details.planet.character.eve_character.character_name,
|
|
411
|
-
planet_details.planet.
|
|
458
|
+
planet_details.planet.eve_planet.name,
|
|
412
459
|
)
|
|
413
460
|
planet_details.last_alert = None
|
|
414
461
|
planet_details.notification_sent = False
|
|
415
462
|
|
|
416
463
|
planet_details.save()
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
PlanetaryDetailsManager = PlanetaryDetailsManagerBase.from_queryset(
|
|
420
|
-
PlanetaryDetailsQuerySet
|
|
421
|
-
)
|