aa-structures 2.15.0__py3-none-any.whl → 2.16.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aa-structures
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: App for managing Eve Online structures with Alliance Auth.
5
5
  Author-email: Erik Kalkoken <kalkoken87@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -1,12 +1,12 @@
1
- structures/__init__.py,sha256=DW_FAyoVYr5DMbDmmJQ_yaBVMMVB07QHRZP71oApKTA,204
1
+ structures/__init__.py,sha256=Z3bIPmcm4sX1w_r8VxYDVpCP0rbtGGuzUzh7wP8la5c,204
2
2
  structures/admin.py,sha256=K7wh8mHFfGHONn7oLdqXsBAxq0rmYrwbZ7S3uIOuMtg,41303
3
3
  structures/app_settings.py,sha256=aWA2bTcv_vVwIyisx-G7GBSpfM6JDyt2MWcXKtHnjK0,6651
4
4
  structures/apps.py,sha256=MNZH9l3qWCwuS7OGiKGkBVrDzKoOFlqwDdEgyEFzxVA,195
5
5
  structures/auth_hooks.py,sha256=nRbrixFkAE5gphDokB1E8xhH8FY2VtXVwu0XMmSGBAw,1013
6
- structures/constants.py,sha256=12iIVgFWSNaH1iYBByrsv3OQKCnNxluuckOdrfgzWzA,995
6
+ structures/constants.py,sha256=k5rfD29ZjR7ToRmJw4WnLVd4LmoZvDw4OK5IoiiyJ6w,1063
7
7
  structures/forms.py,sha256=kXs-SGIIj-D9xtFCILKe_PMRU4eHl3-HLNWRhaZKmnQ,391
8
8
  structures/helpers.py,sha256=_dw7j7yobpcV70VwWxoQiptk69b3ksvaDlRQKHg8Kmg,2344
9
- structures/managers.py,sha256=6zGvmiP1_TZ1uZlPTxNFYgJ77JIjY3uw2PmYeyrJ10E,20063
9
+ structures/managers.py,sha256=_XZhsWb4is7LpQTUmGZwxQeJzyZnsB3n21EETgEIlzU,20062
10
10
  structures/providers.py,sha256=9QYHd8X5HwBhrbgbX3LUrXXV1KGM3hFhcxK6qIJjJtg,317
11
11
  structures/tasks.py,sha256=INZ3soMYHYfxrQsyTO-ozoxbVX6lpMnF3AUo8ybWIoA,9083
12
12
  structures/urls.py,sha256=An5v27AD_NXMNL66cMVtQNci1C_Aqry32rrvDkMpgYo,1467
@@ -65,7 +65,7 @@ structures/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
65
65
  structures/models/__init__.py,sha256=Da0-Z4BtsZ_mlnI6XtyvoE0UtTuOA0psGCuVhVPVKrM,916
66
66
  structures/models/eveuniverse.py,sha256=vTIfzZL9guEDuZHQvRdG6pI4zSEdMqfVE-2SkHdqbRo,2213
67
67
  structures/models/notifications.py,sha256=HwQc-ChdP0ULuJgxUym9_CBsCWCmcHT7whlk9tB2vzw,35364
68
- structures/models/owners.py,sha256=7CKpwHlw4Nz8lTJUgQZxI-GHon5FrlMEILxe7q7Vfgg,58391
68
+ structures/models/owners.py,sha256=Oxs9LDtoKRvpqGtvZehNDyBPKgW_UIrUntZPe6LVPzY,59611
69
69
  structures/models/structures_1.py,sha256=zk380uG2DuQ7exO7THbq5TE5Ro2jr6EyVCIxRJXHIJI,29958
70
70
  structures/models/structures_2.py,sha256=g5Pct5jNmZC-n7fnpLs5UyiP9JLrGdI1vjYucHTV_wQ,10371
71
71
  structures/static/structures/css/global.css,sha256=R4LEH9PwLoN77qkqBK7u2y_vzRC3fq8X_zKnAW7yhiA,1165
@@ -185,17 +185,18 @@ structures/tests/models/test_notifications_2.py,sha256=wBoB6lHMK4yrd63DSkZ570yXW
185
185
  structures/tests/models/test_notifications_3.py,sha256=u11s0k9EmtFgL3kyb4zDyLVliQLOps701ZgEA2T2i0Y,7257
186
186
  structures/tests/models/test_notifications_discord.py,sha256=6maDXjl2C5yH2XRgsvMtb3P-tfOdZLQDaksffiqS8OM,6312
187
187
  structures/tests/models/test_owners_1.py,sha256=o8AJasQ0-Pdb0FRFZcmNcMGjaIk8fH3OZIZw4paJiDw,24433
188
- structures/tests/models/test_owners_2.py,sha256=GZYdsFey6bQHuk9BiT1KFT_vW01mUHRtDxJRHPEmrC4,22539
188
+ structures/tests/models/test_owners_2.py,sha256=RSaeLz6S6ncoikWwDjNh6YZftpBN8TGdzAl8E2tgkqA,24527
189
189
  structures/tests/models/test_owners_3.py,sha256=cpDkfFkVvC1v4uuXha1vGUmWZ163huYTUDuZyed9Rdc,16947
190
190
  structures/tests/models/test_owners_4.py,sha256=_VP4QsPYGwBnn_bVN4aNX2ZVeJzMAzWObZrgCJkOPgY,19496
191
191
  structures/tests/models/test_owners_5.py,sha256=TIF_SqJqyGja8FBV2lQNAC4yff1usmJ4e0QW7e68zTg,36929
192
192
  structures/tests/models/test_owners_6.py,sha256=R9UE2QGwiGTWLHzzOZwGQPWJrAPwIIl7UwrHH-ki4Ak,940
193
193
  structures/tests/models/test_structures.py,sha256=iCCa0yYyPHieNfj8TQbdoIv141oLc6hlICZ6AsTnHAw,41849
194
194
  structures/tests/testdata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
- structures/tests/testdata/create_eveuniverse.py,sha256=6CYgXtJaEwxWvQFyH-P0SKsRqeMuSyJ92ZJiXe_-nuY,2256
195
+ structures/tests/testdata/constants.py,sha256=iab-9cHjAO4RBM88UeWbBypRm9qoZcViwZ8BPY17p1Q,441
196
+ structures/tests/testdata/create_eveuniverse.py,sha256=a5DHYAxxsytOeevAL53RDoeDWObKwViqfpXRlmZeOHY,2157
196
197
  structures/tests/testdata/entities.json,sha256=vmb0uhwTpD0gycGAakgYidr3qSbnHiMubAd4u7T2l70,36053
197
198
  structures/tests/testdata/esi_data.json,sha256=DX47oSlRZIPxlPueMfiNElbZbAip2cp3LAUmv8GAPJ0,13864
198
- structures/tests/testdata/eveuniverse.json,sha256=3fhD72lUNLj96wO4ASbpNcdH_8VbqcXUvKUXR6j0768,1028885
199
+ structures/tests/testdata/eveuniverse.json,sha256=7RA5qeaPYx78Mk5_zixL2XYd-Oa4omhUihjgAbgNLyc,1616628
199
200
  structures/tests/testdata/factories.py,sha256=UF7Zao2-DjVFLZLEBWaJv4Pg1uw5D6p0TO8ZKuoAI_8,25293
200
201
  structures/tests/testdata/generate_notifications.py,sha256=lhcnbsnE4O6g0OFUAYO2sCfu8vmwBcFtxn-TuTLtFnM,5417
201
202
  structures/tests/testdata/generate_notifications_2.py,sha256=mdoGXd9vgy_opmrwTr9MfGe-QieHV4BHtRA7VFzxFKM,1413
@@ -223,7 +224,7 @@ structures/webhooks/models.py,sha256=kUkt9rnRQIJIrU9Bjcs34rvkb-TMbUubHdn-kny08kI
223
224
  structures/webhooks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
224
225
  structures/webhooks/tests/test_core.py,sha256=4NcEAQgK2KhQkFOxYh2ad0S-qUWh1DNGDmLo5Mo5opI,6762
225
226
  structures/webhooks/tests/test_utils.py,sha256=ekADFv0JOEtXeqdiejbeqrABO__Q1flJHzVieQ7L9e0,459
226
- aa_structures-2.15.0.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
227
- aa_structures-2.15.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
228
- aa_structures-2.15.0.dist-info/METADATA,sha256=UZGw51TIsMgIdznKyyE9prBvlgDQQpJ3k3z4Url-DEE,5972
229
- aa_structures-2.15.0.dist-info/RECORD,,
227
+ aa_structures-2.16.0.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
228
+ aa_structures-2.16.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
229
+ aa_structures-2.16.0.dist-info/METADATA,sha256=1Aqt2HSauvphDqPjDpuv3s2Pkht-0ezvNuQWA7Op4hI,5972
230
+ aa_structures-2.16.0.dist-info/RECORD,,
structures/__init__.py CHANGED
@@ -3,5 +3,5 @@
3
3
  # pylint: disable = invalid-name
4
4
  default_app_config = "structures.apps.StructuresConfig"
5
5
 
6
- __version__ = "2.15.0"
6
+ __version__ = "2.16.0"
7
7
  __title__ = "Structures"
structures/constants.py CHANGED
@@ -16,6 +16,7 @@ class EveCategoryId(IntEnum):
16
16
  ORBITAL = 46
17
17
  STARBASE = 23
18
18
  STRUCTURE = 65
19
+ STRUCTURE_MODULE = 66
19
20
 
20
21
 
21
22
  class EveGroupId(IntEnum):
@@ -26,11 +27,13 @@ class EveGroupId(IntEnum):
26
27
  ENGINEERING_COMPLEX = 1404
27
28
  FUEL_BLOCK = 1136
28
29
  ICE_PRODUCT = 423
29
- REFINERY = 1406
30
+ MOON = 8
30
31
  PLANET = 7
32
+ QUANTUM_CORES = 4086
33
+ REFINERY = 1406
31
34
  STRUCTURE_CITADEL_SERVICE_MODULE = 1321
32
35
  UNCOMMON_MOON_ASTEROIDS = 1921
33
- QUANTUM_CORES = 4086
36
+ UPWELL_MOON_DRILL = 4744
34
37
 
35
38
 
36
39
  class EveTypeId(IntEnum):
@@ -42,8 +45,8 @@ class EveTypeId(IntEnum):
42
45
  IHUB = 32458
43
46
  JUMP_GATE = 35841
44
47
  LIQUID_OZONE = 16273
45
- ORBITAL_SKYHOOK = 81080
46
48
  NITROGEN_FUEL_BLOCK = 4051
49
+ ORBITAL_SKYHOOK = 81080
47
50
  STRONTIUM = 16275
48
51
  TCU = 32226
49
52
 
structures/managers.py CHANGED
@@ -392,7 +392,7 @@ class StructureManagerBase(models.Manager):
392
392
  def update_or_create_from_dict(
393
393
  self, structure: dict, owner: Owner
394
394
  ) -> Tuple[Any, bool]:
395
- """update or create structure from given dict"""
395
+ """Update or create a structure from a dict."""
396
396
 
397
397
  eve_type: EveType = EveType.objects.get_or_create_esi(id=structure["type_id"])[
398
398
  0
@@ -585,14 +585,10 @@ class Owner(models.Model):
585
585
  return positions
586
586
 
587
587
  def _fetch_upwell_structures(self, token: Token) -> bool:
588
- """Fetch Upwell structures from ESI for self.
589
-
590
- Return True if successful, else False.
591
- """
592
- is_ok = True
588
+ """Fetches Upwell structures from ESI an reports whether it was successful."""
593
589
  # fetch main list of structure for this corporation
594
590
  try:
595
- structures: List[dict] = (
591
+ structures = (
596
592
  esi.client.Corporation.get_corporations_corporation_id_structures(
597
593
  corporation_id=self.corporation.corporation_id,
598
594
  token=token.valid_access_token(),
@@ -604,58 +600,12 @@ class Owner(models.Model):
604
600
 
605
601
  # fetch additional information for structures
606
602
  if not structures:
603
+ is_ok = True
607
604
  logger.info("%s: No Upwell structures retrieved from ESI", self)
608
605
  else:
609
- logger.info(
610
- "%s: Fetching additional infos for %d Upwell structures from ESI",
611
- self,
612
- len(structures),
613
- )
614
- for structure in structures:
615
- try:
616
- structure_info = (
617
- esi.client.Universe.get_universe_structures_structure_id(
618
- structure_id=structure["structure_id"],
619
- token=token.valid_access_token(),
620
- )
621
- ).results()
622
- except OSError as ex:
623
- if isinstance(ex, HTTPForbidden):
624
- logger.error(
625
- "Failed to fetch structure with ID #%d belonging to %s, "
626
- "because the character '%s' is missing "
627
- "docking rights for it.",
628
- structure["structure_id"],
629
- self,
630
- token.character_name,
631
- )
632
- else:
633
- self._report_esi_issue(
634
- f"fetch structure #{structure['structure_id']}", ex, token
635
- )
636
- structure["name"] = "(no data)"
637
- is_ok = False
638
- else:
639
- structure["name"] = Structure.extract_name_from_esi_response(
640
- structure_info["name"]
641
- )
642
- structure["position"] = structure_info["position"]
643
-
644
- logger.info(
645
- "%s: Storing updates for %d upwell structures",
646
- self,
647
- len(structures),
648
- )
649
- for structure in structures:
650
- try:
651
- Structure.objects.update_or_create_from_dict(structure, self)
652
- except OSError:
653
- logger.warning(
654
- "%s: Failed to store update for structure with ID %s",
655
- self,
656
- structure["structure_id"],
657
- )
658
- is_ok = False
606
+ is_ok = self._fetch_universe_infos_for_structures(token, structures)
607
+ is_ok &= self._store_structure_updates(structures)
608
+ self._resolve_metenox_moons()
659
609
 
660
610
  if STRUCTURES_DEVELOPER_MODE:
661
611
  self._store_raw_data("structures", structures)
@@ -666,6 +616,95 @@ class Owner(models.Model):
666
616
  )
667
617
  return is_ok
668
618
 
619
+ def _fetch_universe_infos_for_structures(
620
+ self, token, structures: List[dict]
621
+ ) -> bool:
622
+ count = 0
623
+ for s in structures:
624
+ try:
625
+ structure_info = (
626
+ esi.client.Universe.get_universe_structures_structure_id(
627
+ structure_id=s["structure_id"],
628
+ token=token.valid_access_token(),
629
+ )
630
+ ).results()
631
+ except OSError as ex:
632
+ if isinstance(ex, HTTPForbidden):
633
+ logger.error(
634
+ "Failed to fetch structure with ID #%d belonging to %s, "
635
+ "because the character '%s' is missing docking rights.",
636
+ s["structure_id"],
637
+ self,
638
+ token.character_name,
639
+ )
640
+ else:
641
+ self._report_esi_issue(
642
+ f"fetch structure #{s['structure_id']}", ex, token
643
+ )
644
+ s["name"] = "(no data)"
645
+ else:
646
+ count += 1
647
+ s["name"] = Structure.extract_name_from_esi_response(
648
+ structure_info["name"]
649
+ )
650
+ s["position"] = structure_info["position"]
651
+
652
+ logger.info(
653
+ "%s: Fetched universe infos for %d / %d Upwell structures from ESI",
654
+ self,
655
+ count,
656
+ len(structures),
657
+ )
658
+ return count == len(structures)
659
+
660
+ def _store_structure_updates(self, structures: List[dict]) -> bool:
661
+ count = 0
662
+ for s in structures:
663
+ try:
664
+ Structure.objects.update_or_create_from_dict(s, self)
665
+ except OSError:
666
+ logger.warning(
667
+ "%s: Failed to store update for structure with ID %s",
668
+ self,
669
+ s["structure_id"],
670
+ )
671
+ else:
672
+ count += 1
673
+ logger.info(
674
+ "%s: Stored updates for %d/%d upwell structures",
675
+ self,
676
+ count,
677
+ len(structures),
678
+ )
679
+ return count == len(structures)
680
+
681
+ def _resolve_metenox_moons(self):
682
+ """Add moons to all unresolved metenox structures."""
683
+ s: Structure
684
+ for s in self.structures.filter(
685
+ eve_type__eve_group=EveGroupId.UPWELL_MOON_DRILL,
686
+ eve_moon__isnull=True,
687
+ position_x__isnull=False,
688
+ position_y__isnull=False,
689
+ position_z__isnull=False,
690
+ ):
691
+ try:
692
+ celestial = s.eve_solar_system.nearest_celestial(
693
+ x=s.position_x,
694
+ y=s.position_y,
695
+ z=s.position_z,
696
+ group_id=EveGroupId.MOON,
697
+ )
698
+ except OSError:
699
+ continue
700
+
701
+ if not celestial or not isinstance(celestial.eve_object, EveMoon):
702
+ continue
703
+
704
+ s.eve_moon = celestial.eve_object
705
+ s.save()
706
+ logger.info("%s: Resolved moon for Metenox: %d", self, s.name)
707
+
669
708
  def _fetch_custom_offices(self, token: Token) -> bool:
670
709
  """Fetch custom offices from ESI for this owner.
671
710
 
@@ -1375,6 +1414,7 @@ class Owner(models.Model):
1375
1414
  s.eve_planet = celestial.eve_object
1376
1415
  s.name = celestial.eve_type.name
1377
1416
  s.save()
1417
+ logger.info("%s: Resolved moon for Skyhook at: %s", self, s.eve_planet.name)
1378
1418
 
1379
1419
  @staticmethod
1380
1420
  def get_esi_scopes() -> List[str]:
@@ -2,6 +2,7 @@ import datetime as dt
2
2
  from unittest.mock import patch
3
3
 
4
4
  from django.utils.timezone import now, utc
5
+ from eveuniverse.models import EveMoon
5
6
 
6
7
  from app_utils.esi_testing import EsiClientStub, EsiEndpoint
7
8
  from app_utils.testing import NoSocketsTestCase
@@ -10,6 +11,7 @@ from structures.constants import EveCorporationId
10
11
  from structures.core.notification_types import NotificationType
11
12
  from structures.models import Structure, StructureService
12
13
  from structures.tests import to_json
14
+ from structures.tests.testdata.constants import EveMoonId, EveSolarSystemId, EveTypeId
13
15
  from structures.tests.testdata.factories import (
14
16
  EveEntityCorporationFactory,
15
17
  FuelAlertConfigFactory,
@@ -20,6 +22,7 @@ from structures.tests.testdata.factories import (
20
22
  UserMainDefaultOwnerFactory,
21
23
  WebhookFactory,
22
24
  )
25
+ from structures.tests.testdata.helpers import NearestCelestial
23
26
  from structures.tests.testdata.load_eveuniverse import load_eveuniverse
24
27
 
25
28
  MODULE_PATH = "structures.models.owners"
@@ -40,54 +43,6 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
40
43
  id=EveCorporationId.DED, name="DED"
41
44
  ) # for notifications
42
45
  cls.endpoints = [
43
- EsiEndpoint(
44
- "Assets",
45
- "get_corporations_corporation_id_assets",
46
- "corporation_id",
47
- needs_token=True,
48
- data={
49
- str(cls.corporation_id): [
50
- {
51
- "is_singleton": False,
52
- "item_id": 1300000001001,
53
- "location_flag": "QuantumCoreRoom",
54
- "location_id": 1000000000001,
55
- "location_type": "item",
56
- "quantity": 1,
57
- "type_id": 56201, # Astrahus Upwell Quantum Core
58
- },
59
- {
60
- "is_singleton": True,
61
- "item_id": 1300000001002,
62
- "location_flag": "ServiceSlot0",
63
- "location_id": 1000000000001,
64
- "location_type": "item",
65
- "quantity": 1,
66
- "type_id": 35894, # Standup Cloning Center I
67
- },
68
- {
69
- "is_singleton": True,
70
- "item_id": 1300000002001,
71
- "location_flag": "ServiceSlot0",
72
- "location_id": 1000000000002,
73
- "location_type": "item",
74
- "quantity": 1,
75
- "type_id": 35894, # Standup Cloning Center I
76
- },
77
- ],
78
- "2102": [
79
- {
80
- "is_singleton": False,
81
- "item_id": 1300000003001,
82
- "location_flag": "StructureFuel",
83
- "location_id": 1000000000004,
84
- "location_type": "item",
85
- "quantity": 5000,
86
- "type_id": 16273, # Liquid Ozone
87
- }
88
- ],
89
- },
90
- ),
91
46
  EsiEndpoint(
92
47
  "Corporation",
93
48
  "get_corporations_corporation_id_structures",
@@ -110,8 +65,8 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
110
65
  "state_timer_end": None,
111
66
  "state_timer_start": None,
112
67
  "structure_id": 1000000000002,
113
- "system_id": 30002537,
114
- "type_id": 35835, # Athanor
68
+ "system_id": EveSolarSystemId.AMAMAKE,
69
+ "type_id": EveTypeId.ATHANOR,
115
70
  "unanchors_at": None,
116
71
  },
117
72
  {
@@ -131,8 +86,8 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
131
86
  2020, 4, 5, 6, 30, tzinfo=utc
132
87
  ),
133
88
  "structure_id": 1000000000001,
134
- "system_id": 30002537,
135
- "type_id": 35832, # Astrahus
89
+ "system_id": EveSolarSystemId.AMAMAKE,
90
+ "type_id": EveTypeId.ASTRAHUS,
136
91
  "unanchors_at": dt.datetime(2020, 5, 5, 6, 30, tzinfo=utc),
137
92
  },
138
93
  {
@@ -148,7 +103,7 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
148
103
  "state_timer_start": None,
149
104
  "structure_id": 1000000000003,
150
105
  "system_id": 30000476,
151
- "type_id": 35832, # Astrahus
106
+ "type_id": EveTypeId.ASTRAHUS,
152
107
  "unanchors_at": None,
153
108
  },
154
109
  ],
@@ -168,8 +123,8 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
168
123
  "y": 7310316270.0,
169
124
  "z": -163686684205.0,
170
125
  },
171
- "solar_system_id": 30002537,
172
- "type_id": 35832, # Astrahus
126
+ "solar_system_id": EveSolarSystemId.AMAMAKE,
127
+ "type_id": EveTypeId.ASTRAHUS,
173
128
  },
174
129
  "1000000000002": {
175
130
  "corporation_id": cls.corporation_id,
@@ -179,8 +134,8 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
179
134
  "y": -130157937025.56424,
180
135
  "z": -442026427345.6355,
181
136
  },
182
- "solar_system_id": 30002537,
183
- "type_id": 35835, # Athanor
137
+ "solar_system_id": EveSolarSystemId.AMAMAKE,
138
+ "type_id": EveTypeId.ATHANOR,
184
139
  },
185
140
  "1000000000003": {
186
141
  "corporation_id": cls.corporation_id,
@@ -191,7 +146,7 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
191
146
  "z": -442026427345.6355,
192
147
  },
193
148
  "solar_system_id": 30000476,
194
- "type_id": 35832, # Astrahus
149
+ "type_id": EveTypeId.ASTRAHUS,
195
150
  },
196
151
  },
197
152
  ),
@@ -221,7 +176,7 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
221
176
  self.assertEqual(structure.position_x, 55028384780.0)
222
177
  self.assertEqual(structure.position_y, 7310316270.0)
223
178
  self.assertEqual(structure.position_z, -163686684205.0)
224
- self.assertEqual(structure.eve_solar_system_id, 30002537)
179
+ self.assertEqual(structure.eve_solar_system_id, EveSolarSystemId.AMAMAKE)
225
180
  self.assertEqual(structure.eve_type_id, 35832)
226
181
  self.assertEqual(
227
182
  int(structure.owner.corporation.corporation_id), self.corporation_id
@@ -550,3 +505,92 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
550
505
  owner.update_structures_esi()
551
506
  # then
552
507
  self.assertEqual(structure.structure_fuel_alerts.count(), 0)
508
+
509
+
510
+ @patch(MODULE_PATH + ".STRUCTURES_FEATURE_STARBASES", False)
511
+ @patch(MODULE_PATH + ".STRUCTURES_FEATURE_CUSTOMS_OFFICES", False)
512
+ @patch(MODULE_PATH + ".esi")
513
+ class TestUpdateSpecificUpwellStructuresEsi(NoSocketsTestCase):
514
+ @classmethod
515
+ def setUpClass(cls):
516
+ super().setUpClass()
517
+ load_eveuniverse()
518
+ cls.user = UserMainDefaultOwnerFactory()
519
+ cls.owner = OwnerFactory(user=cls.user, structures_last_update_at=None)
520
+ cls.corporation_id = cls.owner.corporation.corporation_id
521
+ EveEntityCorporationFactory(
522
+ id=EveCorporationId.DED, name="DED"
523
+ ) # for notifications
524
+
525
+ def test_can_update_metenox(self, mock_esi):
526
+ structure_id = 1000000000111
527
+ type_id = EveTypeId.METENOX
528
+ solar_system_id = EveSolarSystemId.AMAMAKE
529
+ endpoints = [
530
+ EsiEndpoint(
531
+ "Corporation",
532
+ "get_corporations_corporation_id_structures",
533
+ "corporation_id",
534
+ needs_token=True,
535
+ data={
536
+ str(self.corporation_id): [
537
+ {
538
+ "corporation_id": self.corporation_id,
539
+ "fuel_expires": dt.datetime(2020, 3, 5, 5, tzinfo=utc),
540
+ "next_reinforce_apply": None,
541
+ "next_reinforce_hour": None,
542
+ "profile_id": 101853,
543
+ "reinforce_hour": 18,
544
+ "services": [
545
+ {"name": "Moon Drill", "state": "online"},
546
+ ],
547
+ "state": "shield_vulnerable",
548
+ "state_timer_end": dt.datetime(2020, 4, 5, 7, tzinfo=utc),
549
+ "state_timer_start": dt.datetime(
550
+ 2020, 4, 5, 6, 30, tzinfo=utc
551
+ ),
552
+ "structure_id": structure_id,
553
+ "system_id": solar_system_id,
554
+ "type_id": type_id,
555
+ "unanchors_at": dt.datetime(2020, 5, 5, 6, 30, tzinfo=utc),
556
+ },
557
+ ],
558
+ },
559
+ ),
560
+ EsiEndpoint(
561
+ "Universe",
562
+ "get_universe_structures_structure_id",
563
+ "structure_id",
564
+ needs_token=True,
565
+ data={
566
+ str(structure_id): {
567
+ "corporation_id": self.corporation_id,
568
+ "name": "Amamake - Mining",
569
+ "position": {
570
+ "x": 55028384780.0,
571
+ "y": 7310316270.0,
572
+ "z": -163686684205.0,
573
+ },
574
+ "solar_system_id": solar_system_id,
575
+ "type_id": type_id,
576
+ },
577
+ },
578
+ ),
579
+ ]
580
+ # given
581
+ mock_esi.client = EsiClientStub.create_from_endpoints(endpoints)
582
+ owner = OwnerFactory(user=self.user, structures_last_update_at=None)
583
+ moon = EveMoon.objects.get(id=EveMoonId.AMAMAKE_P2_M1)
584
+ # when
585
+ with patch(MODULE_PATH + ".EveSolarSystem.nearest_celestial") as m:
586
+ m.return_value = NearestCelestial(None, moon, 100)
587
+ owner.update_structures_esi()
588
+ # then
589
+ owner.refresh_from_db()
590
+ self.assertTrue(owner.is_structure_sync_fresh)
591
+ s = Structure.objects.get(id=structure_id)
592
+ self.assertEqual(s.name, "Mining")
593
+ self.assertEqual(s.eve_solar_system.id, EveSolarSystemId.AMAMAKE)
594
+ services = set(s.services.values_list("name", flat=True))
595
+ self.assertSetEqual({"Moon Drill"}, services)
596
+ self.assertEqual(s.eve_moon, moon)
@@ -0,0 +1,22 @@
1
+ from enum import IntEnum
2
+
3
+
4
+ class EveTypeId(IntEnum):
5
+ """An EVE type ID."""
6
+
7
+ ASTRAHUS = 35832
8
+ ASTRAHUS_UPWELL_QUANTUM_CORE = 56201
9
+ ATHANOR = 35835
10
+ LIQUID_OZONE = 16273
11
+ METENOX = 81826
12
+ STANDUP_CLONING_CENTER_I = 35894
13
+ STANDUP_METENOX_MOON_DRILL = 82941
14
+ INTEGRATED_MOON_DRILL_ARMATURE = 81920
15
+
16
+
17
+ class EveMoonId(IntEnum):
18
+ AMAMAKE_P2_M1 = 40161465
19
+
20
+
21
+ class EveSolarSystemId(IntEnum):
22
+ AMAMAKE = 30002537
@@ -18,7 +18,7 @@ class CreateEveUniverseTestData(TestCase):
18
18
  ),
19
19
  ModelSpec(
20
20
  "EveCategory",
21
- ids=[EveCategoryId.ORBITAL],
21
+ ids=[EveCategoryId.ORBITAL, EveCategoryId.STRUCTURE_MODULE],
22
22
  include_children=True,
23
23
  ),
24
24
  ModelSpec(
@@ -40,12 +40,10 @@ class CreateEveUniverseTestData(TestCase):
40
40
  EveGroupId.FUEL_BLOCK,
41
41
  EveGroupId.ICE_PRODUCT,
42
42
  EveGroupId.QUANTUM_CORES,
43
- EveGroupId.STRUCTURE_CITADEL_SERVICE_MODULE,
44
43
  EveGroupId.UNCOMMON_MOON_ASTEROIDS,
45
44
  ],
46
45
  include_children=True,
47
46
  ),
48
- ModelSpec("EveType", ids=[], include_children=False),
49
47
  ModelSpec(
50
48
  "EveSolarSystem",
51
49
  ids=[30002506, 31000005, 30002537, 30000474, 30000476],