aa-structures 2.12.0__py3-none-any.whl → 2.14.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_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/METADATA +1 -1
- {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/RECORD +37 -34
- structures/__init__.py +1 -1
- structures/admin.py +1 -1
- structures/app_settings.py +4 -0
- structures/constants.py +1 -0
- structures/core/notification_embeds/main.py +58 -31
- structures/core/notification_embeds/orbital_embeds.py +1 -1
- structures/core/notification_embeds/skyhook_embeds.py +89 -0
- structures/core/notification_embeds/structures_embeds.py +23 -12
- structures/core/notification_embeds/tower_embeds.py +1 -1
- structures/core/notification_timers.py +53 -6
- structures/core/notification_types.py +58 -36
- structures/managers.py +22 -8
- structures/migrations/0007_add_notificationtypes_skyhook_metenox.py +149 -0
- structures/migrations/0008_add_notificationtypes_skyhook_metenox.py +149 -0
- structures/models/owners.py +68 -8
- structures/models/structures_1.py +5 -0
- structures/templates/structures/public.html +2 -2
- structures/templates/structures/structures.html +3 -3
- structures/tests/core/test_notification_types.py +16 -0
- structures/tests/core/{test_notifications_timerboard.py → test_notifications_timers.py} +6 -1
- structures/tests/integration/test_tasks.py +102 -1
- structures/tests/integration/test_views.py +1 -1
- structures/tests/models/test_owners_5.py +135 -1
- structures/tests/models/test_structures.py +49 -42
- structures/tests/test_managers_1.py +11 -1
- structures/tests/testdata/create_eveuniverse.py +6 -1
- structures/tests/testdata/entities.json +71 -1
- structures/tests/testdata/eveuniverse.json +6306 -5145
- structures/tests/testdata/factories.py +21 -0
- structures/tests/testdata/generate_notifications.py +142 -157
- structures/tests/testdata/helpers.py +6 -0
- structures/tests/views/test_structures.py +12 -4
- structures/views/structures.py +6 -6
- {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/LICENSE +0 -0
- {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/WHEEL +0 -0
@@ -476,6 +476,27 @@ class PocoDetailsFactory(
|
|
476
476
|
standing_level = PocoDetails.StandingLevel.BAD
|
477
477
|
|
478
478
|
|
479
|
+
class SkyhookFactory(StructureFactory):
|
480
|
+
class Params:
|
481
|
+
eve_planet_name = "Amamake V"
|
482
|
+
|
483
|
+
has_fitting = None
|
484
|
+
has_core = None
|
485
|
+
state = Structure.State.NA
|
486
|
+
|
487
|
+
@factory.lazy_attribute
|
488
|
+
def eve_planet(self):
|
489
|
+
return EvePlanet.objects.get(name=self.eve_planet_name)
|
490
|
+
|
491
|
+
@factory.lazy_attribute
|
492
|
+
def eve_solar_system(self):
|
493
|
+
return self.eve_planet.eve_solar_system
|
494
|
+
|
495
|
+
@factory.lazy_attribute
|
496
|
+
def eve_type(self):
|
497
|
+
return EveType.objects.get(id=EveTypeId.ORBITAL_SKYHOOK)
|
498
|
+
|
499
|
+
|
479
500
|
class JumpGateFactory(StructureFactory):
|
480
501
|
@factory.lazy_attribute
|
481
502
|
def eve_type(self):
|
@@ -3,177 +3,162 @@
|
|
3
3
|
this scripts create a test owner and adds test notifications to it
|
4
4
|
"""
|
5
5
|
|
6
|
-
import
|
6
|
+
import datetime as dt
|
7
7
|
import json
|
8
|
-
import
|
9
|
-
|
10
|
-
from
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
from
|
22
|
-
|
23
|
-
from
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
from esi.clients import esi_client_factory
|
33
|
-
from eveuniverse.models import EveEntity
|
34
|
-
|
35
|
-
from allianceauth.eveonline.models import EveCorporationInfo
|
36
|
-
|
37
|
-
from structures.models import Notification, Owner, Structure, Webhook
|
38
|
-
|
39
|
-
# corporation / structure the notifications will be added to
|
40
|
-
CORPORATION_ID = 98587692 # RABIS
|
41
|
-
|
42
|
-
print(
|
43
|
-
"load_test_notifications - "
|
44
|
-
"script loads test notification into the local database "
|
45
|
-
)
|
46
|
-
|
47
|
-
print("Connecting to ESI ...")
|
48
|
-
client = esi_client_factory()
|
49
|
-
|
50
|
-
print("Creating base data ...")
|
51
|
-
try:
|
52
|
-
corporation = EveCorporationInfo.objects.get(corporation_id=CORPORATION_ID)
|
53
|
-
except EveCorporationInfo.DoesNotExist:
|
54
|
-
corporation = EveCorporationInfo.objects.create_corporation(CORPORATION_ID)
|
55
|
-
|
56
|
-
owner, created = Owner.objects.get_or_create(
|
57
|
-
corporation=corporation, defaults={"is_active": False}
|
58
|
-
)
|
59
|
-
if created and not owner.webhooks.exists():
|
60
|
-
webhook = Webhook.objects.filter(is_active=True, is_default=True).first()
|
61
|
-
if webhook:
|
62
|
-
owner.webhooks.add(webhook)
|
63
|
-
|
64
|
-
structure = {
|
65
|
-
"fuel_expires": None,
|
66
|
-
"name": "Test Structure Alpha",
|
67
|
-
"next_reinforce_apply": None,
|
68
|
-
"next_reinforce_hour": None,
|
69
|
-
"position": {"x": 55028384780.0, "y": 7310316270.0, "z": -163686684205.0},
|
70
|
-
"profile_id": 101853,
|
71
|
-
"reinforce_hour": 18,
|
72
|
-
"services": [
|
73
|
-
{
|
74
|
-
"name": "Clone Bay",
|
75
|
-
"name_de": "Clone Bay_de",
|
76
|
-
"name_ko": "Clone Bay_ko",
|
77
|
-
"state": "online",
|
78
|
-
},
|
79
|
-
{
|
80
|
-
"name": "Market Hub",
|
81
|
-
"name_de": "Market Hub_de",
|
82
|
-
"name_ko": "Market Hub_ko",
|
83
|
-
"state": "offline",
|
84
|
-
},
|
85
|
-
],
|
86
|
-
"state": "shield_vulnerable",
|
87
|
-
"state_timer_end": None,
|
88
|
-
"state_timer_start": None,
|
89
|
-
"structure_id": 1999999999999,
|
90
|
-
"system_id": 30002537,
|
91
|
-
"type_id": 35832,
|
92
|
-
"unanchors_at": None,
|
93
|
-
}
|
94
|
-
structure, _ = Structure.objects.update_or_create_from_dict(structure, owner)
|
95
|
-
|
96
|
-
with open(file=currentdir + "/entities.json", mode="r", encoding="utf-8") as fp:
|
97
|
-
data = json.load(fp)
|
98
|
-
|
99
|
-
notifications = data["Notification"]
|
100
|
-
for notification in notifications:
|
101
|
-
if notification["sender_id"] == 2901:
|
102
|
-
notification["sender_id"] = 1000137 # DED
|
103
|
-
if notification["sender_id"] == 2902:
|
104
|
-
notification["sender_id"] = 1000125 # Concord
|
105
|
-
elif notification["sender_id"] == 1011:
|
106
|
-
notification["sender_id"] = 3004029
|
107
|
-
elif notification["sender_id"] == 2022:
|
108
|
-
notification["sender_id"] = 1000127 # Guristas
|
109
|
-
elif notification["sender_id"] == 3001:
|
110
|
-
notification["sender_id"] = 99010298
|
111
|
-
notification["text"] = notification["text"].replace(
|
112
|
-
"1000000000001", str(structure.id)
|
113
|
-
)
|
114
|
-
notification["text"] = notification["text"].replace(
|
115
|
-
"35835", str(structure.eve_type_id)
|
116
|
-
)
|
117
|
-
notification["text"] = notification["text"].replace(
|
118
|
-
"35835", str(structure.eve_type_id)
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
from app_utils.scripts import start_django
|
11
|
+
|
12
|
+
start_django()
|
13
|
+
|
14
|
+
|
15
|
+
def main():
|
16
|
+
|
17
|
+
from django.utils.timezone import now
|
18
|
+
from esi.clients import esi_client_factory
|
19
|
+
from eveuniverse.models import EveEntity
|
20
|
+
|
21
|
+
from allianceauth.eveonline.models import EveCorporationInfo
|
22
|
+
|
23
|
+
from structures.core.notification_types import NotificationType
|
24
|
+
from structures.models import Notification, Owner, Structure, Webhook
|
25
|
+
|
26
|
+
# corporation / structure the notifications will be added to
|
27
|
+
CORPORATION_ID = 1000127 # Guristas
|
28
|
+
|
29
|
+
print(
|
30
|
+
"load_test_notifications - "
|
31
|
+
"script loads test notification into the local database "
|
119
32
|
)
|
120
|
-
|
121
|
-
|
33
|
+
|
34
|
+
print("Connecting to ESI ...")
|
35
|
+
client = esi_client_factory()
|
36
|
+
|
37
|
+
print("Creating base data ...")
|
38
|
+
try:
|
39
|
+
corporation = EveCorporationInfo.objects.get(corporation_id=CORPORATION_ID)
|
40
|
+
except EveCorporationInfo.DoesNotExist:
|
41
|
+
corporation = EveCorporationInfo.objects.create_corporation(CORPORATION_ID)
|
42
|
+
|
43
|
+
owner, created = Owner.objects.get_or_create(
|
44
|
+
corporation=corporation, defaults={"is_active": False}
|
122
45
|
)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
46
|
+
if created and not owner.webhooks.exists():
|
47
|
+
webhook = Webhook.objects.filter(is_active=True, is_default=True).first()
|
48
|
+
if webhook:
|
49
|
+
owner.webhooks.add(webhook)
|
50
|
+
|
51
|
+
structure = {
|
52
|
+
"fuel_expires": None,
|
53
|
+
"name": "Test Structure Alpha",
|
54
|
+
"next_reinforce_apply": None,
|
55
|
+
"next_reinforce_hour": None,
|
56
|
+
"position": {"x": 55028384780.0, "y": 7310316270.0, "z": -163686684205.0},
|
57
|
+
"profile_id": 101853,
|
58
|
+
"reinforce_hour": 18,
|
59
|
+
"services": [
|
60
|
+
{
|
61
|
+
"name": "Clone Bay",
|
62
|
+
"name_de": "Clone Bay_de",
|
63
|
+
"name_ko": "Clone Bay_ko",
|
64
|
+
"state": "online",
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"name": "Market Hub",
|
68
|
+
"name_de": "Market Hub_de",
|
69
|
+
"name_ko": "Market Hub_ko",
|
70
|
+
"state": "offline",
|
71
|
+
},
|
72
|
+
],
|
73
|
+
"state": "shield_vulnerable",
|
74
|
+
"state_timer_end": None,
|
75
|
+
"state_timer_start": None,
|
76
|
+
"structure_id": 1999999999999,
|
77
|
+
"system_id": 30002537,
|
78
|
+
"type_id": 35832,
|
79
|
+
"unanchors_at": None,
|
80
|
+
}
|
81
|
+
structure, _ = Structure.objects.update_or_create_from_dict(structure, owner)
|
82
|
+
|
83
|
+
p = Path(__file__).parent / "/entities.json"
|
84
|
+
with p.open(mode="r", encoding="utf-8") as fp:
|
85
|
+
data = json.load(fp)
|
86
|
+
|
87
|
+
notifications = data["Notification"]
|
88
|
+
for n in notifications:
|
89
|
+
if n["sender_id"] == 2901:
|
90
|
+
n["sender_id"] = 1000137 # DED
|
91
|
+
if n["sender_id"] == 2902:
|
92
|
+
n["sender_id"] = 1000125 # Concord
|
93
|
+
elif n["sender_id"] == 1011:
|
94
|
+
n["sender_id"] = 3004029
|
95
|
+
elif n["sender_id"] == 2022:
|
96
|
+
n["sender_id"] = 1000127 # Guristas
|
97
|
+
elif n["sender_id"] == 3001:
|
98
|
+
n["sender_id"] = 99010298
|
99
|
+
n["text"] = n["text"].replace("1000000000001", str(structure.id))
|
100
|
+
n["text"] = n["text"].replace("35835", str(structure.eve_type_id))
|
101
|
+
n["text"] = n["text"].replace("35835", str(structure.eve_type_id))
|
102
|
+
n["text"] = n["text"].replace("30002537", str(structure.eve_solar_system_id))
|
103
|
+
n["text"] = n["text"].replace("1001", "3004037")
|
104
|
+
n["text"] = n["text"].replace("1002", "3019491")
|
105
|
+
n["text"] = n["text"].replace("1011", "3004029")
|
106
|
+
n["text"] = n["text"].replace("2001", "98394960")
|
107
|
+
n["text"] = n["text"].replace("2002", "1000134") # Blood Raiders
|
108
|
+
n["text"] = n["text"].replace("3001", "99005502")
|
109
|
+
n["text"] = n["text"].replace("3002", "99009333")
|
110
|
+
n["text"] = n["text"].replace("3011", "1354830081")
|
111
|
+
|
112
|
+
timestamp_start = now() - dt.timedelta(hours=2)
|
113
|
+
|
114
|
+
for n in notifications:
|
115
|
+
notif_type = n["type"]
|
116
|
+
if notif_type not in NotificationType.values:
|
117
|
+
print(f"Skipping unsupported: {notif_id} {notif_type}")
|
118
|
+
|
119
|
+
notif_id = n["notification_id"]
|
120
|
+
sender, _ = EveEntity.objects.get_or_create_esi(id=n["sender_id"])
|
121
|
+
text = n["text"] if "text" in n else None
|
122
|
+
is_read = n["is_read"] if "is_read" in n else None
|
123
|
+
timestamp_start = timestamp_start + dt.timedelta(minutes=5)
|
124
|
+
obj, created = Notification.objects.update_or_create(
|
125
|
+
notification_id=notif_id,
|
146
126
|
owner=owner,
|
147
127
|
defaults={
|
148
128
|
"sender": sender,
|
149
129
|
"timestamp": timestamp_start,
|
150
|
-
"notif_type":
|
130
|
+
"notif_type": notif_type,
|
151
131
|
"text": text,
|
152
132
|
"is_read": is_read,
|
153
133
|
"last_updated": now(),
|
154
134
|
"is_sent": False,
|
155
135
|
},
|
156
136
|
)
|
137
|
+
if created:
|
138
|
+
print(f"Created: {notif_id} {notif_type}")
|
157
139
|
|
158
|
-
print("DONE")
|
140
|
+
print("DONE")
|
159
141
|
|
142
|
+
"""
|
143
|
+
for notification in notifications:
|
144
|
+
dt = datetime.datetime.utcfromtimestamp(notification['timestamp'])
|
145
|
+
dt = pytz.utc.localize(dt)
|
146
|
+
notification['timestamp'] = dt.isoformat()
|
147
|
+
|
148
|
+
with open(
|
149
|
+
file=currentdir + '/td_notifications_2.json',
|
150
|
+
mode='w',
|
151
|
+
encoding='utf-8'
|
152
|
+
) as f:
|
153
|
+
json.dump(
|
154
|
+
notifications,
|
155
|
+
f,
|
156
|
+
sort_keys=True,
|
157
|
+
indent=4
|
158
|
+
)
|
160
159
|
|
161
|
-
"""
|
162
|
-
for notification in notifications:
|
163
|
-
dt = datetime.datetime.utcfromtimestamp(notification['timestamp'])
|
164
|
-
dt = pytz.utc.localize(dt)
|
165
|
-
notification['timestamp'] = dt.isoformat()
|
166
|
-
|
167
|
-
with open(
|
168
|
-
file=currentdir + '/td_notifications_2.json',
|
169
|
-
mode='w',
|
170
|
-
encoding='utf-8'
|
171
|
-
) as f:
|
172
|
-
json.dump(
|
173
|
-
notifications,
|
174
|
-
f,
|
175
|
-
sort_keys=True,
|
176
|
-
indent=4
|
177
|
-
)
|
160
|
+
"""
|
178
161
|
|
179
|
-
|
162
|
+
|
163
|
+
if __name__ == "__main__":
|
164
|
+
main()
|
@@ -4,6 +4,7 @@ import datetime as dt
|
|
4
4
|
import json
|
5
5
|
import logging
|
6
6
|
import unicodedata
|
7
|
+
from collections import namedtuple
|
7
8
|
from pathlib import Path
|
8
9
|
from random import randrange
|
9
10
|
|
@@ -192,3 +193,8 @@ def datetime_to_ldap(my_dt: dt.datetime) -> int:
|
|
192
193
|
((my_dt - dt.datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds())
|
193
194
|
+ 11644473600
|
194
195
|
) * 10000000
|
196
|
+
|
197
|
+
|
198
|
+
NearestCelestial = namedtuple(
|
199
|
+
"NearestCelestial", ["eve_type", "eve_object", "distance"]
|
200
|
+
)
|
@@ -19,6 +19,7 @@ from structures.tests.testdata.factories import (
|
|
19
19
|
JumpGateFactory,
|
20
20
|
OwnerFactory,
|
21
21
|
PocoFactory,
|
22
|
+
SkyhookFactory,
|
22
23
|
StarbaseFactory,
|
23
24
|
StructureFactory,
|
24
25
|
StructureTagFactory,
|
@@ -148,6 +149,7 @@ class TestStructureListDataFilterVariant(TestCase):
|
|
148
149
|
owner = OwnerFactory(user=cls.user)
|
149
150
|
cls.structure = StructureFactory(owner=owner)
|
150
151
|
cls.poco = PocoFactory(owner=owner)
|
152
|
+
cls.skyhook = SkyhookFactory(owner=owner)
|
151
153
|
cls.starbase = StarbaseFactory(owner=owner)
|
152
154
|
cls.jump_gate = JumpGateFactory(owner=owner)
|
153
155
|
|
@@ -163,17 +165,17 @@ class TestStructureListDataFilterVariant(TestCase):
|
|
163
165
|
structure_ids = set(data.keys())
|
164
166
|
self.assertSetEqual(structure_ids, {self.structure.id, self.jump_gate.id})
|
165
167
|
|
166
|
-
def
|
168
|
+
def test_should_return_orbitals_only(self):
|
167
169
|
# given
|
168
170
|
request = self.factory.get("/")
|
169
171
|
request.user = self.user
|
170
172
|
# when
|
171
|
-
response = structures.structure_list_data(request, "
|
173
|
+
response = structures.structure_list_data(request, "orbitals")
|
172
174
|
# then
|
173
175
|
self.assertEqual(response.status_code, 200)
|
174
176
|
data = json_response_to_dict(response)
|
175
177
|
structure_ids = set(data.keys())
|
176
|
-
self.assertSetEqual(structure_ids, {self.poco.id})
|
178
|
+
self.assertSetEqual(structure_ids, {self.poco.id, self.skyhook.id})
|
177
179
|
|
178
180
|
def test_should_return_starbases_only(self):
|
179
181
|
# given
|
@@ -211,7 +213,13 @@ class TestStructureListDataFilterVariant(TestCase):
|
|
211
213
|
structure_ids = set(data.keys())
|
212
214
|
self.assertSetEqual(
|
213
215
|
structure_ids,
|
214
|
-
{
|
216
|
+
{
|
217
|
+
self.structure.id,
|
218
|
+
self.poco.id,
|
219
|
+
self.starbase.id,
|
220
|
+
self.jump_gate.id,
|
221
|
+
self.skyhook.id,
|
222
|
+
},
|
215
223
|
)
|
216
224
|
|
217
225
|
def test_should_raise_error_when_invalid_variant_requested(self):
|
structures/views/structures.py
CHANGED
@@ -58,7 +58,7 @@ class StructureSelection(str, Enum):
|
|
58
58
|
"""A pre-defined selection to filter structures data."""
|
59
59
|
|
60
60
|
STRUCTURES = "structures"
|
61
|
-
|
61
|
+
ORBITALS = "orbitals"
|
62
62
|
STARBASES = "starbases"
|
63
63
|
JUMP_GATES = "jump_gates"
|
64
64
|
ALL = "all"
|
@@ -118,8 +118,8 @@ def structure_list(request: HttpRequest):
|
|
118
118
|
structures_count = _structures_query(
|
119
119
|
request.user, StructureSelection.STRUCTURES, tags
|
120
120
|
).count()
|
121
|
-
|
122
|
-
request.user, StructureSelection.
|
121
|
+
orbitals_count = _structures_query(
|
122
|
+
request.user, StructureSelection.ORBITALS, tags
|
123
123
|
).count()
|
124
124
|
starbases_count = _structures_query(
|
125
125
|
request.user, StructureSelection.STARBASES, tags
|
@@ -136,7 +136,7 @@ def structure_list(request: HttpRequest):
|
|
136
136
|
"tags_exist": StructureTag.objects.exists(),
|
137
137
|
"show_jump_gates_tab": STRUCTURES_SHOW_JUMP_GATES,
|
138
138
|
"structures_count": structures_count,
|
139
|
-
"
|
139
|
+
"orbitals_count": orbitals_count,
|
140
140
|
"starbases_count": starbases_count,
|
141
141
|
"jump_gates_count": jump_gates_count,
|
142
142
|
"data_export": data_export,
|
@@ -146,7 +146,7 @@ def structure_list(request: HttpRequest):
|
|
146
146
|
|
147
147
|
def _construct_data_export(request, tags):
|
148
148
|
structures_ajax_url = _construct_ajax_url(StructureSelection.STRUCTURES, tags)
|
149
|
-
pocos_ajax_url = _construct_ajax_url(StructureSelection.
|
149
|
+
pocos_ajax_url = _construct_ajax_url(StructureSelection.ORBITALS, tags)
|
150
150
|
starbases_ajax_url = _construct_ajax_url(StructureSelection.STARBASES, tags)
|
151
151
|
jump_gates_ajax_url = _construct_ajax_url(StructureSelection.JUMP_GATES, tags)
|
152
152
|
|
@@ -213,7 +213,7 @@ def _structures_query(
|
|
213
213
|
eve_type__eve_group__eve_category_id=EveCategoryId.STRUCTURE
|
214
214
|
)
|
215
215
|
|
216
|
-
elif selection == StructureSelection.
|
216
|
+
elif selection == StructureSelection.ORBITALS:
|
217
217
|
structures_qs = structures_qs.filter(
|
218
218
|
eve_type__eve_group__eve_category_id=EveCategoryId.ORBITAL
|
219
219
|
).annotate_has_poco_details()
|
File without changes
|
File without changes
|