aa-ledger 1.0.3__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.3.dist-info → aa_ledger-2.0.0.dist-info}/METADATA +6 -6
- aa_ledger-2.0.0.dist-info/RECORD +267 -0
- {aa_ledger-1.0.3.dist-info → aa_ledger-2.0.0.dist-info}/WHEEL +1 -1
- 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 +18 -26
- 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 +717 -553
- 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 +187 -358
- ledger/managers/character_mining_manager.py +64 -30
- ledger/managers/character_planetary_manager.py +185 -138
- ledger/managers/corporation_audit_manager.py +36 -27
- ledger/managers/corporation_journal_manager.py +94 -57
- ledger/managers/general_manager.py +12 -8
- 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 -146
- 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.3.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.3.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,21 +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
|
-
from ledger.
|
|
18
|
+
from ledger.app_settings import LEDGER_BULK_BATCH_SIZE
|
|
19
19
|
from ledger.decorators import log_timing
|
|
20
|
-
from ledger.models.characteraudit import
|
|
21
|
-
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
|
|
22
23
|
|
|
23
24
|
if TYPE_CHECKING: # pragma: no cover
|
|
24
25
|
# Alliance Auth
|
|
@@ -27,9 +28,10 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
27
28
|
|
|
28
29
|
# AA Ledger
|
|
29
30
|
from ledger.models.general import UpdateSectionResult
|
|
30
|
-
from ledger.models.planetary import CharacterPlanet
|
|
31
|
+
from ledger.models.planetary import CharacterPlanet as PlanetContext
|
|
32
|
+
from ledger.models.planetary import CharacterPlanetDetails as PlanetDetailsContext
|
|
31
33
|
|
|
32
|
-
logger =
|
|
34
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
def to_json_serializable(data):
|
|
@@ -44,50 +46,46 @@ def to_json_serializable(data):
|
|
|
44
46
|
return data
|
|
45
47
|
|
|
46
48
|
|
|
47
|
-
class
|
|
48
|
-
pass
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class PlanetaryManagerBase(models.Manager):
|
|
49
|
+
class CharacterPlanetManager(models.Manager["PlanetContext"]):
|
|
52
50
|
@log_timing(logger)
|
|
53
51
|
def update_or_create_esi(
|
|
54
|
-
self,
|
|
52
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
55
53
|
) -> "UpdateSectionResult":
|
|
56
54
|
"""Update or Create a planets entry from ESI data."""
|
|
57
|
-
return
|
|
58
|
-
section=
|
|
55
|
+
return owner.update_manager.update_section_if_changed(
|
|
56
|
+
section=CharacterUpdateSection.PLANETS,
|
|
59
57
|
fetch_func=self._fetch_esi_data,
|
|
60
58
|
force_refresh=force_refresh,
|
|
61
59
|
)
|
|
62
60
|
|
|
63
61
|
def _fetch_esi_data(
|
|
64
|
-
self,
|
|
62
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
65
63
|
) -> None:
|
|
66
64
|
"""Fetch planetary entries from ESI data."""
|
|
67
65
|
req_scopes = ["esi-planets.manage_planets.v1"]
|
|
68
|
-
token =
|
|
66
|
+
token = owner.get_token(scopes=req_scopes)
|
|
69
67
|
|
|
70
68
|
# Make the ESI request
|
|
71
69
|
operation = esi.client.Planetary_Interaction.GetCharactersCharacterIdPlanets(
|
|
72
|
-
character_id=
|
|
70
|
+
character_id=owner.eve_character.character_id,
|
|
73
71
|
token=token,
|
|
74
72
|
)
|
|
75
73
|
|
|
76
74
|
planets_items = operation.results(force_refresh=force_refresh)
|
|
77
75
|
|
|
78
|
-
self._update_or_create_objs(
|
|
76
|
+
self._update_or_create_objs(owner=owner, objs=planets_items)
|
|
79
77
|
|
|
80
78
|
@transaction.atomic()
|
|
81
79
|
def _update_or_create_objs(
|
|
82
|
-
self,
|
|
80
|
+
self, owner: CharacterOwner, objs: list["PlanetGetItem"]
|
|
83
81
|
) -> None:
|
|
84
82
|
"""Update or Create planets entries from objs data."""
|
|
85
83
|
# pylint: disable=import-outside-toplevel
|
|
86
84
|
# AA Ledger
|
|
87
85
|
from ledger.models.planetary import CharacterPlanetDetails
|
|
88
86
|
|
|
89
|
-
_current_planets = self.filter(character=
|
|
90
|
-
"
|
|
87
|
+
_current_planets = self.filter(character=owner).values_list(
|
|
88
|
+
"eve_planet_id", flat=True
|
|
91
89
|
)
|
|
92
90
|
|
|
93
91
|
_planets_ids = []
|
|
@@ -99,16 +97,16 @@ class PlanetaryManagerBase(models.Manager):
|
|
|
99
97
|
_planets_ids.append(eve_planet.id)
|
|
100
98
|
|
|
101
99
|
try:
|
|
102
|
-
e_planet = self.get(character=
|
|
100
|
+
e_planet = self.get(character=owner, eve_planet=eve_planet)
|
|
103
101
|
prim_key = e_planet.id
|
|
104
102
|
except self.model.DoesNotExist:
|
|
105
103
|
prim_key = None
|
|
106
104
|
|
|
107
105
|
planet = self.model(
|
|
108
106
|
id=prim_key,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
name=eve_planet.name,
|
|
108
|
+
character=owner,
|
|
109
|
+
eve_planet=eve_planet,
|
|
112
110
|
upgrade_level=planet.upgrade_level,
|
|
113
111
|
num_pins=planet.num_pins,
|
|
114
112
|
)
|
|
@@ -119,45 +117,32 @@ class PlanetaryManagerBase(models.Manager):
|
|
|
119
117
|
_planets_update.append(planet)
|
|
120
118
|
|
|
121
119
|
if _planets_new:
|
|
122
|
-
self.bulk_create(_planets_new)
|
|
120
|
+
self.bulk_create(_planets_new, batch_size=LEDGER_BULK_BATCH_SIZE)
|
|
123
121
|
if _planets_update:
|
|
124
|
-
self.bulk_update(
|
|
122
|
+
self.bulk_update(
|
|
123
|
+
_planets_update,
|
|
124
|
+
fields=["upgrade_level", "num_pins"],
|
|
125
|
+
batch_size=LEDGER_BULK_BATCH_SIZE,
|
|
126
|
+
)
|
|
125
127
|
|
|
126
128
|
# Delete Planets that are no longer in the list
|
|
127
129
|
obsolete_planets = set(_current_planets) - set(_planets_ids)
|
|
128
|
-
self.filter(character=
|
|
130
|
+
self.filter(character=owner, eve_planet_id__in=obsolete_planets).delete()
|
|
129
131
|
# Delete Planet Details that are no longer in the list
|
|
130
132
|
CharacterPlanetDetails.objects.filter(
|
|
131
|
-
planet__character=
|
|
133
|
+
planet__character=owner, planet__eve_planet_id__in=obsolete_planets
|
|
132
134
|
).delete()
|
|
133
135
|
|
|
134
136
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
139
|
-
def get_or_create_facilitys(self, planet: "CharacterPlanet"):
|
|
140
|
-
"""Get or Create Facilitys for a given Planet"""
|
|
141
|
-
return self._get_or_create_facilitys(planet=planet)
|
|
142
|
-
|
|
143
|
-
def _get_or_create_facilitys(self, planet: "CharacterPlanet"):
|
|
144
|
-
try:
|
|
145
|
-
facilitys = self.get(planet=planet)
|
|
146
|
-
facility = facilitys.facilitys
|
|
147
|
-
created = False
|
|
148
|
-
return facility, created
|
|
149
|
-
except self.model.DoesNotExist:
|
|
150
|
-
facility, created = self.update_or_create_facilitys(planet=planet)
|
|
151
|
-
return facility, created
|
|
152
|
-
|
|
137
|
+
class PlanetDetailsQuerySet(models.QuerySet):
|
|
153
138
|
def update_or_create_layout(
|
|
154
139
|
self,
|
|
155
|
-
|
|
156
|
-
planet: "
|
|
140
|
+
owner: CharacterOwner,
|
|
141
|
+
planet: "PlanetDetailsContext",
|
|
157
142
|
objs: list["PlanetDetailsItem"],
|
|
158
143
|
):
|
|
159
144
|
"""Update or Create Layout for a given Planet"""
|
|
160
|
-
return self._update_or_create(
|
|
145
|
+
return self._update_or_create(owner=owner, planet=planet, objs=objs)
|
|
161
146
|
|
|
162
147
|
def _convert_to_dict(
|
|
163
148
|
self,
|
|
@@ -171,13 +156,14 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
171
156
|
|
|
172
157
|
def _update_or_create(
|
|
173
158
|
self,
|
|
174
|
-
|
|
175
|
-
planet: "
|
|
159
|
+
owner: CharacterOwner,
|
|
160
|
+
planet: "PlanetDetailsContext",
|
|
176
161
|
objs: list["PlanetDetailsItem"],
|
|
177
|
-
):
|
|
162
|
+
) -> tuple["PlanetDetailsContext", bool]:
|
|
178
163
|
"""Update or Create Layout for a given Planet"""
|
|
179
164
|
if not isinstance(objs, list):
|
|
180
165
|
objs = [objs]
|
|
166
|
+
|
|
181
167
|
for result in objs:
|
|
182
168
|
links = self._convert_to_dict(result.links)
|
|
183
169
|
pins = self._convert_to_dict(result.pins)
|
|
@@ -185,66 +171,147 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
185
171
|
|
|
186
172
|
planetdetails, created = self.update_or_create(
|
|
187
173
|
planet=planet,
|
|
188
|
-
character=
|
|
174
|
+
character=owner,
|
|
189
175
|
defaults={
|
|
190
176
|
"links": links,
|
|
191
177
|
"pins": pins,
|
|
192
178
|
"routes": routes,
|
|
193
|
-
"
|
|
179
|
+
"factories": None,
|
|
194
180
|
},
|
|
195
181
|
)
|
|
196
182
|
|
|
197
|
-
self.
|
|
183
|
+
self._update_factory(planetdetails)
|
|
198
184
|
|
|
199
|
-
logger.debug("Planet %s
|
|
185
|
+
logger.debug("Planet %s Factories Updated", planetdetails)
|
|
200
186
|
|
|
201
187
|
return planetdetails, created
|
|
202
188
|
|
|
203
|
-
def
|
|
204
|
-
facility_info = self.get_facility_info(planet)
|
|
205
|
-
planet.facilitys = facility_info
|
|
206
|
-
planet.save()
|
|
207
|
-
return planet
|
|
189
|
+
def _update_factory(self, planet: "PlanetDetailsContext"):
|
|
208
190
|
|
|
209
|
-
|
|
210
|
-
def get_facility_info(self, planet: "CharacterPlanetDetails"):
|
|
211
|
-
facility_info = {}
|
|
191
|
+
factory_dict = {}
|
|
212
192
|
|
|
213
193
|
# Process pins
|
|
214
194
|
for pin in planet.pins:
|
|
215
195
|
pin_id = pin["pin_id"]
|
|
216
196
|
item_type, _ = EveType.objects.get_or_create_esi(id=pin["type_id"])
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
197
|
+
|
|
198
|
+
# Skip Command Center
|
|
199
|
+
if pin["type_id"] in EveType.objects.filter(eve_group_id=1027).values_list(
|
|
200
|
+
"id", flat=True
|
|
221
201
|
):
|
|
222
202
|
continue
|
|
223
|
-
|
|
203
|
+
|
|
204
|
+
# Create Facility Pin Entry
|
|
205
|
+
factory_dict[pin_id] = {
|
|
224
206
|
"facility_id": pin["type_id"],
|
|
225
207
|
"facility_name": item_type.name,
|
|
226
|
-
"
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
},
|
|
208
|
+
"facility_type": (
|
|
209
|
+
item_type.eve_group.name if item_type.eve_group else "N/A"
|
|
210
|
+
),
|
|
211
|
+
"ressources": [],
|
|
231
212
|
}
|
|
232
213
|
|
|
233
|
-
|
|
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])
|
|
234
220
|
|
|
235
|
-
|
|
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])
|
|
227
|
+
|
|
228
|
+
self._factory_production_chain(planet, factory_dict)
|
|
229
|
+
|
|
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"])
|
|
236
238
|
|
|
237
|
-
|
|
239
|
+
item_type_id = content["type_id"]
|
|
240
|
+
item_amount = content["amount"]
|
|
238
241
|
|
|
239
|
-
|
|
240
|
-
|
|
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
|
|
241
305
|
):
|
|
242
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"])
|
|
243
311
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
]
|
|
312
|
+
extractor_product = facility.get("extractor", {}).get("product_type_id")
|
|
313
|
+
if extractor_product:
|
|
314
|
+
item_ids.add(extractor_product)
|
|
248
315
|
|
|
249
316
|
for route in planet.routes:
|
|
250
317
|
destination_pin_id = route["destination_pin_id"]
|
|
@@ -253,69 +320,54 @@ class PlanetaryDetailsQuerySet(models.QuerySet):
|
|
|
253
320
|
id=route["content_type_id"]
|
|
254
321
|
)
|
|
255
322
|
|
|
256
|
-
if destination_pin_id in
|
|
323
|
+
if destination_pin_id in factory_dict:
|
|
257
324
|
req_quantity = route["quantity"]
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)
|
|
261
|
-
|
|
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
|
+
|
|
262
329
|
still_producing = (
|
|
263
|
-
content_type.id in
|
|
264
|
-
if not planet.is_expired
|
|
265
|
-
else False
|
|
330
|
+
content_type.id in item_ids if not planet.is_expired else False
|
|
266
331
|
)
|
|
267
332
|
|
|
333
|
+
is_active = still_producing and missing_quantity > 0
|
|
334
|
+
|
|
268
335
|
resource = {
|
|
269
336
|
"item_id": content_type.id,
|
|
270
337
|
"item_name": content_type.name,
|
|
271
338
|
"req_quantity": req_quantity,
|
|
272
339
|
"current_quantity": current_quantity,
|
|
273
|
-
"missing_quantity":
|
|
274
|
-
"
|
|
340
|
+
"missing_quantity": missing_quantity,
|
|
341
|
+
"is_active": is_active,
|
|
275
342
|
}
|
|
276
|
-
|
|
343
|
+
factory_dict[destination_pin_id]["ressources"].append(resource)
|
|
277
344
|
|
|
278
|
-
if source_pin_id in
|
|
279
|
-
|
|
345
|
+
if source_pin_id in factory_dict:
|
|
346
|
+
factory_dict[source_pin_id]["output_product"] = {
|
|
280
347
|
"item_id": content_type.id,
|
|
281
348
|
"item_name": content_type.name,
|
|
282
349
|
"output_quantity": route["quantity"],
|
|
283
350
|
}
|
|
284
|
-
return
|
|
285
|
-
|
|
286
|
-
def _facility_produce_depend(self, planet, facility_info):
|
|
287
|
-
"""Check if Facility is Producing"""
|
|
288
|
-
for facility in facility_info.values():
|
|
289
|
-
for resource in facility["resources"]:
|
|
290
|
-
self._facility_still_producing(planet, resource, facility_info)
|
|
291
|
-
return facility_info
|
|
292
|
-
|
|
293
|
-
def _facility_still_producing(self, planet, resource, facility_info) -> bool:
|
|
294
|
-
"""Check if ressource exist in Production Chain and change State"""
|
|
295
|
-
for other_facility in facility_info.values():
|
|
296
|
-
if (
|
|
297
|
-
"output_product" in other_facility
|
|
298
|
-
and other_facility["output_product"]["item_id"] == resource["item_id"]
|
|
299
|
-
and not planet.is_expired
|
|
300
|
-
):
|
|
301
|
-
if other_facility["output_product"]["output_quantity"] > 0:
|
|
302
|
-
resource["still_producing"] = True
|
|
351
|
+
return factory_dict
|
|
352
|
+
|
|
303
353
|
|
|
354
|
+
class PlanetDetailsManager(models.Manager["PlanetDetailsContext"]):
|
|
355
|
+
def get_queryset(self):
|
|
356
|
+
return PlanetDetailsQuerySet(self.model, using=self._db)
|
|
304
357
|
|
|
305
|
-
class PlanetaryDetailsManagerBase(models.Manager):
|
|
306
358
|
@log_timing(logger)
|
|
307
359
|
def update_or_create_esi(
|
|
308
|
-
self,
|
|
360
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
309
361
|
) -> "UpdateSectionResult":
|
|
310
362
|
"""Update or Create a planets details entry from ESI data."""
|
|
311
|
-
return
|
|
312
|
-
section=
|
|
363
|
+
return owner.update_manager.update_section_if_changed(
|
|
364
|
+
section=CharacterUpdateSection.PLANETS_DETAILS,
|
|
313
365
|
fetch_func=self._fetch_esi_data,
|
|
314
366
|
force_refresh=force_refresh,
|
|
315
367
|
)
|
|
316
368
|
|
|
317
369
|
def _fetch_esi_data(
|
|
318
|
-
self,
|
|
370
|
+
self, owner: CharacterOwner, force_refresh: bool = False
|
|
319
371
|
) -> None:
|
|
320
372
|
"""Fetch planets details entries from ESI data."""
|
|
321
373
|
# pylint: disable=import-outside-toplevel
|
|
@@ -324,17 +376,17 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
324
376
|
|
|
325
377
|
req_scopes = ["esi-planets.manage_planets.v1"]
|
|
326
378
|
|
|
327
|
-
token =
|
|
379
|
+
token = owner.get_token(scopes=req_scopes)
|
|
328
380
|
|
|
329
|
-
planets_ids = CharacterPlanet.objects.filter(character=
|
|
330
|
-
"
|
|
381
|
+
planets_ids = CharacterPlanet.objects.filter(character=owner).values_list(
|
|
382
|
+
"eve_planet_id", flat=True
|
|
331
383
|
)
|
|
332
384
|
is_updated = False
|
|
333
385
|
|
|
334
386
|
for planet_id in planets_ids:
|
|
335
387
|
# Make the ESI request
|
|
336
388
|
operation = esi.client.Planetary_Interaction.GetCharactersCharacterIdPlanetsPlanetId(
|
|
337
|
-
character_id=
|
|
389
|
+
character_id=owner.eve_character.character_id,
|
|
338
390
|
planet_id=planet_id,
|
|
339
391
|
token=token,
|
|
340
392
|
)
|
|
@@ -346,7 +398,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
346
398
|
continue
|
|
347
399
|
|
|
348
400
|
self._update_or_create_objs(
|
|
349
|
-
|
|
401
|
+
owner=owner,
|
|
350
402
|
objs=planets_details_items,
|
|
351
403
|
planet_id=planet_id,
|
|
352
404
|
)
|
|
@@ -357,7 +409,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
357
409
|
@transaction.atomic()
|
|
358
410
|
def _update_or_create_objs(
|
|
359
411
|
self,
|
|
360
|
-
|
|
412
|
+
owner: CharacterOwner,
|
|
361
413
|
objs: list["PlanetDetailsItem"],
|
|
362
414
|
planet_id: int,
|
|
363
415
|
) -> None:
|
|
@@ -368,18 +420,18 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
368
420
|
|
|
369
421
|
try:
|
|
370
422
|
character_planet = CharacterPlanet.objects.get(
|
|
371
|
-
character=
|
|
423
|
+
character=owner, eve_planet_id=planet_id
|
|
372
424
|
)
|
|
373
425
|
except CharacterPlanet.DoesNotExist:
|
|
374
426
|
logger.warning(
|
|
375
427
|
"Planet %s not found for character %s",
|
|
376
428
|
planet_id,
|
|
377
|
-
|
|
429
|
+
owner.eve_character.character_name,
|
|
378
430
|
)
|
|
379
431
|
return
|
|
380
432
|
|
|
381
|
-
planet_details, created = self.update_or_create_layout(
|
|
382
|
-
|
|
433
|
+
planet_details, created = self.get_queryset().update_or_create_layout(
|
|
434
|
+
owner=owner,
|
|
383
435
|
planet=character_planet,
|
|
384
436
|
objs=objs,
|
|
385
437
|
)
|
|
@@ -389,7 +441,7 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
389
441
|
if planet_details.is_expired and planet_details.last_alert is None:
|
|
390
442
|
logger.debug(
|
|
391
443
|
"Planet %s Extractor Heads Expired for: %s",
|
|
392
|
-
planet_details.planet.
|
|
444
|
+
planet_details.planet.eve_planet.name,
|
|
393
445
|
planet_details.planet.character.eve_character.character_name,
|
|
394
446
|
)
|
|
395
447
|
planet_details.last_alert = timezone.now()
|
|
@@ -403,14 +455,9 @@ class PlanetaryDetailsManagerBase(models.Manager):
|
|
|
403
455
|
logger.debug(
|
|
404
456
|
"Notification Reseted for %s Planet: %s",
|
|
405
457
|
planet_details.planet.character.eve_character.character_name,
|
|
406
|
-
planet_details.planet.
|
|
458
|
+
planet_details.planet.eve_planet.name,
|
|
407
459
|
)
|
|
408
460
|
planet_details.last_alert = None
|
|
409
461
|
planet_details.notification_sent = False
|
|
410
462
|
|
|
411
463
|
planet_details.save()
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
PlanetaryDetailsManager = PlanetaryDetailsManagerBase.from_queryset(
|
|
415
|
-
PlanetaryDetailsQuerySet
|
|
416
|
-
)
|