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
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Third Party
|
|
2
|
+
from ninja import schema
|
|
3
|
+
|
|
4
|
+
# Django
|
|
5
|
+
from django.utils.html import format_html
|
|
6
|
+
from django.utils.translation import gettext_lazy as _
|
|
7
|
+
|
|
8
|
+
# Alliance Auth
|
|
9
|
+
from allianceauth.services.hooks import get_extension_logger
|
|
10
|
+
|
|
11
|
+
# Alliance Auth (External Libs)
|
|
12
|
+
from eveuniverse.models import EveType
|
|
13
|
+
|
|
14
|
+
# AA Ledger
|
|
15
|
+
from ledger import __title__
|
|
16
|
+
from ledger.helpers.eveonline import get_icon_render_url
|
|
17
|
+
from ledger.models.planetary import CharacterPlanetDetails
|
|
18
|
+
from ledger.providers import AppLogger
|
|
19
|
+
|
|
20
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProductSchema(schema.Schema):
|
|
24
|
+
item_id: int
|
|
25
|
+
item_name: str
|
|
26
|
+
item_quantity: int | None = None
|
|
27
|
+
icon: str | None = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class FactorySchema(schema.Schema):
|
|
31
|
+
factory_name: str
|
|
32
|
+
products: list[ProductSchema]
|
|
33
|
+
is_active: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ProduceSchema(schema.Schema):
|
|
37
|
+
factory_name: str
|
|
38
|
+
input_products: list[ProductSchema]
|
|
39
|
+
output_product: ProductSchema | None = None
|
|
40
|
+
is_active: str
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class StorageSchema(schema.Schema):
|
|
44
|
+
factory_name: str
|
|
45
|
+
product: ProductSchema
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_factories_info(planet_details: CharacterPlanetDetails) -> list[FactorySchema]:
|
|
49
|
+
"""
|
|
50
|
+
Get the factories information for a planet.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
planet_details (CharacterPlanetDetails): The planetary details object.
|
|
54
|
+
Returns:
|
|
55
|
+
list[FactorySchema]: A list with the factory information for the Planet.
|
|
56
|
+
"""
|
|
57
|
+
response_factories_list: list[FactorySchema] = []
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
factories = planet_details.factories.values()
|
|
61
|
+
except AttributeError:
|
|
62
|
+
return response_factories_list
|
|
63
|
+
|
|
64
|
+
for factory_info in factories:
|
|
65
|
+
factory_name = factory_info.get("facility_name") or _("No facility")
|
|
66
|
+
# Only process Processors
|
|
67
|
+
if factory_info.get("facility_type") != "Processors":
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
# Skip if no ressources
|
|
71
|
+
ressources = factory_info.get("ressources", None) or None
|
|
72
|
+
if ressources is None:
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
ressource_types = get_resource_type(ressources)
|
|
76
|
+
ressource_list = []
|
|
77
|
+
|
|
78
|
+
# Build Ressource List from Factories
|
|
79
|
+
for product in ressource_types.values():
|
|
80
|
+
product = ProductSchema(
|
|
81
|
+
item_id=product["item_id"],
|
|
82
|
+
item_name=product["item_name"],
|
|
83
|
+
icon=get_icon_render_url(
|
|
84
|
+
type_id=product["item_id"],
|
|
85
|
+
type_name=product["item_name"],
|
|
86
|
+
as_html=True,
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
ressource_list.append(product)
|
|
90
|
+
|
|
91
|
+
# Populate Product if exists
|
|
92
|
+
if factory_info.get("output_product", None) is not None:
|
|
93
|
+
output_product = ProductSchema(
|
|
94
|
+
item_id=factory_info["output_product"]["item_id"],
|
|
95
|
+
item_name=factory_info["output_product"]["item_name"],
|
|
96
|
+
icon=get_icon_render_url(
|
|
97
|
+
type_id=factory_info["output_product"]["item_id"],
|
|
98
|
+
type_name=factory_info["output_product"]["item_name"],
|
|
99
|
+
as_html=True,
|
|
100
|
+
),
|
|
101
|
+
)
|
|
102
|
+
ressource_list.append(output_product)
|
|
103
|
+
|
|
104
|
+
is_active = factory_info.get("is_active", False)
|
|
105
|
+
|
|
106
|
+
response_factories_list.append(
|
|
107
|
+
FactorySchema(
|
|
108
|
+
factory_name=factory_name,
|
|
109
|
+
products=ressource_list,
|
|
110
|
+
is_active=generate_is_active_icon(is_active),
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
return response_factories_list
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_factory_info(planet_details: CharacterPlanetDetails) -> list[FactorySchema]:
|
|
117
|
+
"""
|
|
118
|
+
Get the factory information for a planet.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
planet_details (CharacterPlanetDetails): The planetary details object.
|
|
122
|
+
Returns:
|
|
123
|
+
list[FactorySchema]: A list with the factory information for the Planet.
|
|
124
|
+
"""
|
|
125
|
+
response_factories_list: list[FactorySchema] = []
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
factories = planet_details.factories.values()
|
|
129
|
+
except AttributeError:
|
|
130
|
+
return response_factories_list
|
|
131
|
+
|
|
132
|
+
for factory_info in factories:
|
|
133
|
+
factory_name = factory_info.get("facility_name") or _("No facility")
|
|
134
|
+
# Only process Processors
|
|
135
|
+
if factory_info.get("facility_type") != "Processors":
|
|
136
|
+
continue
|
|
137
|
+
|
|
138
|
+
ressource_types = get_resource_type(factory_info["ressources"])
|
|
139
|
+
input_products_list = []
|
|
140
|
+
|
|
141
|
+
# Build Ressource List from Factories
|
|
142
|
+
for input_ressource in ressource_types.values():
|
|
143
|
+
input_ressource = ProductSchema(
|
|
144
|
+
item_id=input_ressource["item_id"],
|
|
145
|
+
item_name=input_ressource["item_name"],
|
|
146
|
+
icon=get_icon_render_url(
|
|
147
|
+
type_id=input_ressource["item_id"],
|
|
148
|
+
type_name=input_ressource["item_name"],
|
|
149
|
+
as_html=True,
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
input_products_list.append(input_ressource)
|
|
153
|
+
|
|
154
|
+
output_product = None
|
|
155
|
+
# Get Output Product if exists
|
|
156
|
+
if factory_info.get("output_product", None) is not None:
|
|
157
|
+
output_product = ProductSchema(
|
|
158
|
+
item_id=factory_info["output_product"]["item_id"],
|
|
159
|
+
item_name=factory_info["output_product"]["item_name"],
|
|
160
|
+
icon=get_icon_render_url(
|
|
161
|
+
type_id=factory_info["output_product"]["item_id"],
|
|
162
|
+
type_name=factory_info["output_product"]["item_name"],
|
|
163
|
+
as_html=True,
|
|
164
|
+
),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
is_active = factory_info.get("is_active", False)
|
|
168
|
+
|
|
169
|
+
response_factories_list.append(
|
|
170
|
+
ProduceSchema(
|
|
171
|
+
factory_name=factory_name,
|
|
172
|
+
input_products=input_products_list,
|
|
173
|
+
output_product=output_product,
|
|
174
|
+
is_active=generate_is_active_icon(is_active),
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
return response_factories_list
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def get_storage_info(planet_details: CharacterPlanetDetails) -> list[StorageSchema]:
|
|
181
|
+
"""
|
|
182
|
+
Get the storage information for a planet.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
planet_details (CharacterPlanetDetails): The planetary details object.
|
|
186
|
+
Returns:
|
|
187
|
+
list[StorageSchema]: A list with the storage information for the Planet.
|
|
188
|
+
"""
|
|
189
|
+
response_storage_list: list[StorageSchema] = []
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
factories = planet_details.factories.values()
|
|
193
|
+
except AttributeError:
|
|
194
|
+
return response_storage_list
|
|
195
|
+
|
|
196
|
+
for factory in factories:
|
|
197
|
+
factory_name = factory.get("facility_name") or _("No facility")
|
|
198
|
+
|
|
199
|
+
# Storage Info
|
|
200
|
+
storage = factory.get("storage", {}) or {}
|
|
201
|
+
for type_id, stored in storage.items():
|
|
202
|
+
# Get Eve Type
|
|
203
|
+
type_data = EveType.objects.get_or_create_esi(id=type_id)[0]
|
|
204
|
+
|
|
205
|
+
# Get Amount if Available
|
|
206
|
+
amount = (
|
|
207
|
+
stored.get("amount")
|
|
208
|
+
or stored.get("quantity")
|
|
209
|
+
or stored.get("item_quantity")
|
|
210
|
+
or stored.get("stored")
|
|
211
|
+
or 0
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# Store Storage Information
|
|
215
|
+
response_storage_list.append(
|
|
216
|
+
StorageSchema(
|
|
217
|
+
factory_name=factory_name,
|
|
218
|
+
product=ProductSchema(
|
|
219
|
+
item_id=type_id,
|
|
220
|
+
item_name=type_data.name,
|
|
221
|
+
item_quantity=int(amount) if amount is not None else None,
|
|
222
|
+
icon=get_icon_render_url(
|
|
223
|
+
type_id=type_id, type_name=type_data.name, as_html=True
|
|
224
|
+
),
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
return response_storage_list
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def generate_is_active_icon(is_active: bool) -> str:
|
|
232
|
+
"""
|
|
233
|
+
Generate an HTML icon representing the active status.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
is_active (bool): The active status.
|
|
237
|
+
Returns:
|
|
238
|
+
str: HTML string representing the active status icon.
|
|
239
|
+
"""
|
|
240
|
+
color = "danger"
|
|
241
|
+
if is_active:
|
|
242
|
+
color = "success"
|
|
243
|
+
return format_html(
|
|
244
|
+
'<span class="fs-5 text-{}" data-bs-tooltip="aa-ledger" title="{}">⬤</span>',
|
|
245
|
+
color,
|
|
246
|
+
_("Active" if is_active else "Inactive"),
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def generate_is_notification_icon(is_notification: bool) -> str:
|
|
251
|
+
"""
|
|
252
|
+
Generate an HTML icon representing the notification status.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
is_notification (bool): The notification status.
|
|
256
|
+
Returns:
|
|
257
|
+
str: HTML string representing the notification status icon.
|
|
258
|
+
"""
|
|
259
|
+
color = "danger"
|
|
260
|
+
if is_notification:
|
|
261
|
+
color = "success"
|
|
262
|
+
return format_html(
|
|
263
|
+
'<i class="fa-solid fa-bullhorn text-{}" style="margin-left: 5px;" data-bs-tooltip="aa-ledger" title="{}"></i>',
|
|
264
|
+
color,
|
|
265
|
+
_("Active" if is_notification else "Inactive"),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def get_resource_type(ressources):
|
|
270
|
+
"""
|
|
271
|
+
Get the resource types.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
ressources (list): List of resource dictionaries.
|
|
275
|
+
Returns:
|
|
276
|
+
dict: Dictionary of unique resource types.
|
|
277
|
+
"""
|
|
278
|
+
resource_types = {}
|
|
279
|
+
for ressource in ressources:
|
|
280
|
+
# Create a new entry if item_id not in resource_types
|
|
281
|
+
if ressource["item_id"] not in resource_types:
|
|
282
|
+
resource_types[ressource["item_id"]] = {
|
|
283
|
+
"item_id": ressource["item_id"],
|
|
284
|
+
"item_name": ressource["item_name"],
|
|
285
|
+
}
|
|
286
|
+
return resource_types
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def allocate_overall_progress(planet_details: CharacterPlanetDetails) -> float | None:
|
|
290
|
+
"""
|
|
291
|
+
Calculate the overall progress percentage of all extractors on the planet.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
planet_details (CharacterPlanetDetails): The planetary details object.
|
|
295
|
+
Returns:
|
|
296
|
+
float | None: The overall progress percentage, or None if no extractors are present.
|
|
297
|
+
"""
|
|
298
|
+
progress_sum = 0.0
|
|
299
|
+
valid_extractors = 0
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
factories = planet_details.factories.values()
|
|
303
|
+
except AttributeError:
|
|
304
|
+
return None
|
|
305
|
+
|
|
306
|
+
for factory in factories:
|
|
307
|
+
extractor = factory.get("extractor", {})
|
|
308
|
+
|
|
309
|
+
# Skip if no extractor present
|
|
310
|
+
if not extractor:
|
|
311
|
+
continue
|
|
312
|
+
|
|
313
|
+
# Get Progress from Extractors
|
|
314
|
+
progress = extractor.get("progress_percentage")
|
|
315
|
+
if progress is not None:
|
|
316
|
+
progress_sum += float(progress)
|
|
317
|
+
valid_extractors += 1
|
|
318
|
+
continue
|
|
319
|
+
|
|
320
|
+
if valid_extractors == 0:
|
|
321
|
+
return None
|
|
322
|
+
|
|
323
|
+
return round(progress_sum / valid_extractors, 2)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def generate_progressbar(percentage: float | None) -> str:
|
|
327
|
+
"""
|
|
328
|
+
Generate a progress bar based on the percentage.
|
|
329
|
+
|
|
330
|
+
This function creates an HTML representation of a progress bar
|
|
331
|
+
with a colored percentage display.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
percentage (float): The percentage to display in the progress bar.
|
|
335
|
+
Returns:
|
|
336
|
+
str: HTML string representing the progress bar.
|
|
337
|
+
"""
|
|
338
|
+
if percentage is None:
|
|
339
|
+
return str(_("No active extractors"))
|
|
340
|
+
|
|
341
|
+
if percentage > 50:
|
|
342
|
+
progress_value = f'<span class="text-white)">{percentage}%</span>'
|
|
343
|
+
else:
|
|
344
|
+
progress_value = f'<span class="text-dark">{percentage}%</span>'
|
|
345
|
+
|
|
346
|
+
progressbar = f"""
|
|
347
|
+
<div class="progress-outer flex-grow-1 me-2">
|
|
348
|
+
<div class="progress" style="position: relative;">
|
|
349
|
+
<div class="progress-bar progress-bar-warning progress-bar-striped active" role="progressbar" style="width: {percentage}%; box-shadow: -1px 3px 5px rgba(0, 180, 231, 0.9);"></div>
|
|
350
|
+
<div class="fw-bold fs-6 text-center position-absolute top-50 start-50 translate-middle">{progress_value}</div>
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
"""
|
|
354
|
+
return progressbar
|
ledger/api/planetary.py
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Third Party
|
|
2
|
+
from ninja import NinjaAPI, schema
|
|
3
|
+
|
|
4
|
+
# Django
|
|
5
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
6
|
+
from django.db.models import Q
|
|
7
|
+
from django.utils.translation import gettext_lazy as _
|
|
8
|
+
|
|
9
|
+
# Alliance Auth
|
|
10
|
+
from allianceauth.services.hooks import get_extension_logger
|
|
11
|
+
|
|
12
|
+
# AA Ledger
|
|
13
|
+
from ledger import __title__
|
|
14
|
+
from ledger.api.helpers.core import get_alts_queryset, get_characterowner_or_none
|
|
15
|
+
from ledger.api.helpers.icons import (
|
|
16
|
+
get_extractor_info_button,
|
|
17
|
+
get_factory_info_button,
|
|
18
|
+
get_toggle_notification_button,
|
|
19
|
+
)
|
|
20
|
+
from ledger.api.helpers.planetary_helper import (
|
|
21
|
+
FactorySchema,
|
|
22
|
+
ProduceSchema,
|
|
23
|
+
StorageSchema,
|
|
24
|
+
allocate_overall_progress,
|
|
25
|
+
generate_is_active_icon,
|
|
26
|
+
generate_is_notification_icon,
|
|
27
|
+
generate_progressbar,
|
|
28
|
+
get_factories_info,
|
|
29
|
+
get_factory_info,
|
|
30
|
+
get_storage_info,
|
|
31
|
+
)
|
|
32
|
+
from ledger.api.schema import (
|
|
33
|
+
EveTypeSchema,
|
|
34
|
+
ExtractorSchema,
|
|
35
|
+
OwnerSchema,
|
|
36
|
+
PlanetSchema,
|
|
37
|
+
ProgressBarSchema,
|
|
38
|
+
)
|
|
39
|
+
from ledger.helpers.eveonline import (
|
|
40
|
+
get_character_portrait_url,
|
|
41
|
+
get_icon_render_url,
|
|
42
|
+
get_type_render_url,
|
|
43
|
+
)
|
|
44
|
+
from ledger.models.planetary import CharacterPlanetDetails
|
|
45
|
+
from ledger.providers import AppLogger
|
|
46
|
+
|
|
47
|
+
logger = AppLogger(get_extension_logger(__name__), __title__)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class FactoryDetailsResponse(schema.Schema):
|
|
51
|
+
owner: OwnerSchema
|
|
52
|
+
planet: PlanetSchema
|
|
53
|
+
factories: list[ProduceSchema]
|
|
54
|
+
storage: list[StorageSchema]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ExtractorDetailsResponse(schema.Schema):
|
|
58
|
+
owner: OwnerSchema
|
|
59
|
+
planet: PlanetSchema
|
|
60
|
+
extractors: list[ExtractorSchema]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PlanetaryDetailsActions(schema.Schema):
|
|
64
|
+
factory_info_button: str
|
|
65
|
+
extractor_info_button: str
|
|
66
|
+
toggle_notification_button: str
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class PlanetaryDetails(schema.Schema):
|
|
70
|
+
owner: OwnerSchema
|
|
71
|
+
planet: PlanetSchema
|
|
72
|
+
expired: str | bool
|
|
73
|
+
alarm: str | bool
|
|
74
|
+
progress_bar: str
|
|
75
|
+
factories: list[FactorySchema]
|
|
76
|
+
actions: PlanetaryDetailsActions
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class PlanetaryApiEndpoints:
|
|
80
|
+
tags = ["CharacterPlanet"]
|
|
81
|
+
|
|
82
|
+
# pylint: disable=too-many-statements
|
|
83
|
+
def __init__(self, api: NinjaAPI):
|
|
84
|
+
@api.get(
|
|
85
|
+
"character/{character_id}/planet/{planet_id}/details/",
|
|
86
|
+
response={200: list[PlanetaryDetails], 403: str},
|
|
87
|
+
tags=self.tags,
|
|
88
|
+
)
|
|
89
|
+
# pylint: disable=too-many-locals
|
|
90
|
+
def get_planetarydetails(
|
|
91
|
+
request: WSGIRequest, character_id: int, planet_id: int
|
|
92
|
+
):
|
|
93
|
+
singleview = request.GET.get("single", False)
|
|
94
|
+
perm, character = get_characterowner_or_none(request, character_id)
|
|
95
|
+
|
|
96
|
+
if not perm:
|
|
97
|
+
return 403, str(_("Permission Denied"))
|
|
98
|
+
|
|
99
|
+
if not singleview:
|
|
100
|
+
characters = get_alts_queryset(character)
|
|
101
|
+
else:
|
|
102
|
+
characters = [character]
|
|
103
|
+
|
|
104
|
+
filters = Q(planet__character__in=characters)
|
|
105
|
+
if not planet_id == 0:
|
|
106
|
+
filters &= Q(planet__id=planet_id)
|
|
107
|
+
|
|
108
|
+
planets_details = CharacterPlanetDetails.objects.filter(filters)
|
|
109
|
+
response_planetary_details_list: list[PlanetaryDetails] = []
|
|
110
|
+
|
|
111
|
+
for details in planets_details:
|
|
112
|
+
response_factories_list = get_factories_info(planet_details=details)
|
|
113
|
+
|
|
114
|
+
response_planetary_details = PlanetaryDetails(
|
|
115
|
+
owner=OwnerSchema(
|
|
116
|
+
character_id=details.planet.character.eve_character.character_id,
|
|
117
|
+
character_name=details.planet.character.eve_character.character_name,
|
|
118
|
+
icon=get_character_portrait_url(
|
|
119
|
+
character_id=details.planet.character.eve_character.character_id,
|
|
120
|
+
character_name=details.planet.character.eve_character.character_name,
|
|
121
|
+
as_html=True,
|
|
122
|
+
),
|
|
123
|
+
),
|
|
124
|
+
planet=PlanetSchema(
|
|
125
|
+
id=details.planet.eve_planet.id,
|
|
126
|
+
name=details.planet.eve_planet.name,
|
|
127
|
+
type=EveTypeSchema(
|
|
128
|
+
id=details.planet.eve_planet.eve_type.id,
|
|
129
|
+
name=details.planet.eve_planet.eve_type.name,
|
|
130
|
+
icon=get_icon_render_url(
|
|
131
|
+
type_id=details.planet.eve_planet.eve_type.id,
|
|
132
|
+
type_name=details.planet.eve_planet.eve_type.name,
|
|
133
|
+
size=32,
|
|
134
|
+
as_html=True,
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
upgrade_level=details.planet.upgrade_level,
|
|
138
|
+
num_pins=details.planet.num_pins,
|
|
139
|
+
last_update=details.planet.last_update,
|
|
140
|
+
),
|
|
141
|
+
factories=response_factories_list,
|
|
142
|
+
expired=generate_is_active_icon(
|
|
143
|
+
is_active=not details.is_expired,
|
|
144
|
+
),
|
|
145
|
+
alarm=generate_is_notification_icon(
|
|
146
|
+
is_notification=details.notification
|
|
147
|
+
),
|
|
148
|
+
progress_bar=generate_progressbar(
|
|
149
|
+
allocate_overall_progress(details)
|
|
150
|
+
),
|
|
151
|
+
actions=PlanetaryDetailsActions(
|
|
152
|
+
factory_info_button=get_factory_info_button(
|
|
153
|
+
planet_details=details
|
|
154
|
+
),
|
|
155
|
+
extractor_info_button=get_extractor_info_button(
|
|
156
|
+
planet_details=details
|
|
157
|
+
),
|
|
158
|
+
toggle_notification_button=get_toggle_notification_button(
|
|
159
|
+
planet_details=details
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
)
|
|
163
|
+
response_planetary_details_list.append(response_planetary_details)
|
|
164
|
+
return response_planetary_details_list
|
|
165
|
+
|
|
166
|
+
@api.get(
|
|
167
|
+
"character/{character_id}/planet/{planet_id}/factory/",
|
|
168
|
+
response={200: FactoryDetailsResponse, 403: dict, 404: dict},
|
|
169
|
+
tags=self.tags,
|
|
170
|
+
)
|
|
171
|
+
def get_factory_details(
|
|
172
|
+
request: WSGIRequest, character_id: int, planet_id: int
|
|
173
|
+
):
|
|
174
|
+
"""
|
|
175
|
+
Get Factory Information for a character's planet.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
request (WSGIRequest): The HTTP request object.
|
|
179
|
+
character_id (int): The ID of the character.
|
|
180
|
+
planet_id (int): The ID of the planet.
|
|
181
|
+
Returns:
|
|
182
|
+
dict: Factory details including owner, planet info, factories, and storage.
|
|
183
|
+
"""
|
|
184
|
+
perm, character = get_characterowner_or_none(request, character_id)
|
|
185
|
+
|
|
186
|
+
if not perm:
|
|
187
|
+
return 403, {"error": _("Permission Denied.")}
|
|
188
|
+
|
|
189
|
+
filters = Q(planet__character=character)
|
|
190
|
+
if planet_id != 0:
|
|
191
|
+
filters &= Q(planet__id=planet_id)
|
|
192
|
+
|
|
193
|
+
planet_details = CharacterPlanetDetails.objects.filter(filters).first()
|
|
194
|
+
|
|
195
|
+
if not planet_details:
|
|
196
|
+
return 403, {"error": _("Planet not found.")}
|
|
197
|
+
|
|
198
|
+
response_storage_list = get_storage_info(planet_details=planet_details)
|
|
199
|
+
response_factories_list = get_factory_info(planet_details=planet_details)
|
|
200
|
+
|
|
201
|
+
return FactoryDetailsResponse(
|
|
202
|
+
owner=OwnerSchema(
|
|
203
|
+
character_id=planet_details.planet.character.eve_character.character_id,
|
|
204
|
+
character_name=planet_details.planet.character.eve_character.character_name,
|
|
205
|
+
),
|
|
206
|
+
planet=PlanetSchema(
|
|
207
|
+
id=planet_details.planet.eve_planet.id,
|
|
208
|
+
name=planet_details.planet.eve_planet.name,
|
|
209
|
+
type=EveTypeSchema(
|
|
210
|
+
id=planet_details.planet.eve_planet.eve_type.id,
|
|
211
|
+
name=planet_details.planet.eve_planet.eve_type.name,
|
|
212
|
+
icon=get_type_render_url(
|
|
213
|
+
type_id=planet_details.planet.eve_planet.eve_type.id,
|
|
214
|
+
size=32,
|
|
215
|
+
as_html=True,
|
|
216
|
+
),
|
|
217
|
+
),
|
|
218
|
+
upgrade_level=planet_details.planet.upgrade_level,
|
|
219
|
+
num_pins=planet_details.planet.num_pins,
|
|
220
|
+
last_update=planet_details.planet.last_update,
|
|
221
|
+
),
|
|
222
|
+
factories=response_factories_list,
|
|
223
|
+
storage=response_storage_list,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
@api.get(
|
|
227
|
+
"character/{character_id}/planet/{planet_id}/extractor/",
|
|
228
|
+
response={200: ExtractorDetailsResponse, 403: dict, 404: dict},
|
|
229
|
+
tags=self.tags,
|
|
230
|
+
)
|
|
231
|
+
def get_extractor_details(
|
|
232
|
+
request: WSGIRequest, character_id: int, planet_id: int
|
|
233
|
+
):
|
|
234
|
+
"""
|
|
235
|
+
Get Extractor Information for a character's planet.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
request (WSGIRequest): The HTTP request object.
|
|
239
|
+
character_id (int): The ID of the character.
|
|
240
|
+
planet_id (int): The ID of the planet.
|
|
241
|
+
Returns:
|
|
242
|
+
dict: Extractor details including owner, planet info, extractors, and last update.
|
|
243
|
+
"""
|
|
244
|
+
perm, character = get_characterowner_or_none(request, character_id)
|
|
245
|
+
|
|
246
|
+
if not perm:
|
|
247
|
+
return 403, {"error": _("Permission Denied.")}
|
|
248
|
+
|
|
249
|
+
filters = Q(planet__character=character)
|
|
250
|
+
if not planet_id == 0:
|
|
251
|
+
filters &= Q(planet__id=planet_id)
|
|
252
|
+
|
|
253
|
+
planet_details = CharacterPlanetDetails.objects.filter(filters).first()
|
|
254
|
+
|
|
255
|
+
if not planet_details:
|
|
256
|
+
return 404, {"error": _("Planet not found.")}
|
|
257
|
+
|
|
258
|
+
response_extractors: list[ExtractorSchema] = []
|
|
259
|
+
|
|
260
|
+
if planet_details.factories:
|
|
261
|
+
for factory in planet_details.factories.values():
|
|
262
|
+
extractor_info = factory.get("extractor", None)
|
|
263
|
+
|
|
264
|
+
# Skip if no extractor info
|
|
265
|
+
if not extractor_info:
|
|
266
|
+
continue
|
|
267
|
+
|
|
268
|
+
extractor = ExtractorSchema(
|
|
269
|
+
item_id=extractor_info["product_type_id"],
|
|
270
|
+
item_name=extractor_info["product_type_name"],
|
|
271
|
+
icon=get_icon_render_url(
|
|
272
|
+
type_id=extractor_info["product_type_id"],
|
|
273
|
+
type_name=extractor_info["product_type_name"],
|
|
274
|
+
as_html=True,
|
|
275
|
+
),
|
|
276
|
+
install_time=extractor_info["install_time"],
|
|
277
|
+
expiry_time=extractor_info["expiry_time"],
|
|
278
|
+
progress=ProgressBarSchema(
|
|
279
|
+
percentage=str(extractor_info["progress_percentage"]),
|
|
280
|
+
html=generate_progressbar(
|
|
281
|
+
extractor_info["progress_percentage"]
|
|
282
|
+
),
|
|
283
|
+
),
|
|
284
|
+
)
|
|
285
|
+
response_extractors.append(extractor)
|
|
286
|
+
|
|
287
|
+
return ExtractorDetailsResponse(
|
|
288
|
+
owner=OwnerSchema(
|
|
289
|
+
character_id=planet_details.planet.character.eve_character.character_id,
|
|
290
|
+
character_name=planet_details.planet.character.eve_character.character_name,
|
|
291
|
+
),
|
|
292
|
+
planet=PlanetSchema(
|
|
293
|
+
id=planet_details.planet.eve_planet.id,
|
|
294
|
+
name=planet_details.planet.eve_planet.name,
|
|
295
|
+
type=EveTypeSchema(
|
|
296
|
+
id=planet_details.planet.eve_planet.eve_type.id,
|
|
297
|
+
name=planet_details.planet.eve_planet.eve_type.name,
|
|
298
|
+
icon=get_type_render_url(
|
|
299
|
+
type_id=planet_details.planet.eve_planet.eve_type.id,
|
|
300
|
+
size=32,
|
|
301
|
+
as_html=True,
|
|
302
|
+
),
|
|
303
|
+
),
|
|
304
|
+
upgrade_level=planet_details.planet.upgrade_level,
|
|
305
|
+
num_pins=planet_details.planet.num_pins,
|
|
306
|
+
last_update=planet_details.planet.last_update,
|
|
307
|
+
),
|
|
308
|
+
extractors=response_extractors,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
@api.post(
|
|
312
|
+
"character/{character_id}/planet/{planet_id}/toggle/",
|
|
313
|
+
response={200: dict, 403: dict, 404: dict},
|
|
314
|
+
tags=self.tags,
|
|
315
|
+
)
|
|
316
|
+
def toggle_planet_notification(
|
|
317
|
+
request: WSGIRequest, character_id: int, planet_id: int
|
|
318
|
+
):
|
|
319
|
+
"""
|
|
320
|
+
Toggle Notification for a character's planet.
|
|
321
|
+
|
|
322
|
+
This endpoint toggles the notification setting for a character's planet.
|
|
323
|
+
It validates the user's permission and the existence of the planet before performing the toggle action.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
request (WSGIRequest): The HTTP request object.
|
|
327
|
+
character_id (int): The ID of the character.
|
|
328
|
+
planet_id (int): The ID of the planet.
|
|
329
|
+
Returns:
|
|
330
|
+
dict: A dictionary containing the success status and message.
|
|
331
|
+
"""
|
|
332
|
+
perm, character = get_characterowner_or_none(request, character_id)
|
|
333
|
+
|
|
334
|
+
if not perm:
|
|
335
|
+
return 403, {"error": _("Permission Denied.")}
|
|
336
|
+
|
|
337
|
+
filters = Q(planet__character=character)
|
|
338
|
+
if not planet_id == 0:
|
|
339
|
+
filters &= Q(planet__id=planet_id)
|
|
340
|
+
|
|
341
|
+
planets = CharacterPlanetDetails.objects.filter(filters)
|
|
342
|
+
|
|
343
|
+
if not planets.exists():
|
|
344
|
+
return 404, {"error": _("Planet not found.")}
|
|
345
|
+
|
|
346
|
+
on_count = planets.filter(notification=True).count()
|
|
347
|
+
off_count = planets.filter(notification=False).count()
|
|
348
|
+
majority_state = on_count > off_count
|
|
349
|
+
|
|
350
|
+
for planet in planets:
|
|
351
|
+
planet.notification = not majority_state
|
|
352
|
+
planet.save()
|
|
353
|
+
msg = _("Notification toggled successfully.")
|
|
354
|
+
return {"success": True, "message": msg}
|