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.
Files changed (37) hide show
  1. {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/METADATA +1 -1
  2. {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/RECORD +37 -34
  3. structures/__init__.py +1 -1
  4. structures/admin.py +1 -1
  5. structures/app_settings.py +4 -0
  6. structures/constants.py +1 -0
  7. structures/core/notification_embeds/main.py +58 -31
  8. structures/core/notification_embeds/orbital_embeds.py +1 -1
  9. structures/core/notification_embeds/skyhook_embeds.py +89 -0
  10. structures/core/notification_embeds/structures_embeds.py +23 -12
  11. structures/core/notification_embeds/tower_embeds.py +1 -1
  12. structures/core/notification_timers.py +53 -6
  13. structures/core/notification_types.py +58 -36
  14. structures/managers.py +22 -8
  15. structures/migrations/0007_add_notificationtypes_skyhook_metenox.py +149 -0
  16. structures/migrations/0008_add_notificationtypes_skyhook_metenox.py +149 -0
  17. structures/models/owners.py +68 -8
  18. structures/models/structures_1.py +5 -0
  19. structures/templates/structures/public.html +2 -2
  20. structures/templates/structures/structures.html +3 -3
  21. structures/tests/core/test_notification_types.py +16 -0
  22. structures/tests/core/{test_notifications_timerboard.py → test_notifications_timers.py} +6 -1
  23. structures/tests/integration/test_tasks.py +102 -1
  24. structures/tests/integration/test_views.py +1 -1
  25. structures/tests/models/test_owners_5.py +135 -1
  26. structures/tests/models/test_structures.py +49 -42
  27. structures/tests/test_managers_1.py +11 -1
  28. structures/tests/testdata/create_eveuniverse.py +6 -1
  29. structures/tests/testdata/entities.json +71 -1
  30. structures/tests/testdata/eveuniverse.json +6306 -5145
  31. structures/tests/testdata/factories.py +21 -0
  32. structures/tests/testdata/generate_notifications.py +142 -157
  33. structures/tests/testdata/helpers.py +6 -0
  34. structures/tests/views/test_structures.py +12 -4
  35. structures/views/structures.py +6 -6
  36. {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/LICENSE +0 -0
  37. {aa_structures-2.12.0.dist-info → aa_structures-2.14.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aa-structures
3
- Version: 2.12.0
3
+ Version: 2.14.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,18 +1,18 @@
1
- structures/__init__.py,sha256=CxjO-itYCGXfwByFQ-cKfhmKWBvz2Lygf1fchGS8_nU,204
2
- structures/admin.py,sha256=TYWGPou4s-mgspoGaZSiZu2nxBeNzidL_DcJTv7JGJI,40068
3
- structures/app_settings.py,sha256=7I_6VC7YecCxnSgtyNQa9h1Zdwb11qJhrNaBLgyA5m0,6527
1
+ structures/__init__.py,sha256=OXqNqbUO5Qpf5_RjpBoWJz1oygLBj3q-5FymboOnAeQ,204
2
+ structures/admin.py,sha256=cA04JFghU-zIGC168fhZ5Hj_FYAQxlF6TFVDb8sgO4A,40066
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=R7sC5esaWJayJpTDbug7dTKxkkXDKXQ-U6M9Qb0GH5s,967
6
+ structures/constants.py,sha256=12iIVgFWSNaH1iYBByrsv3OQKCnNxluuckOdrfgzWzA,995
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=5hejDjWN3ZPZqvSGNf9HXtbtpWX9d75Ygc9FXrO0Np4,19638
9
+ structures/managers.py,sha256=6zGvmiP1_TZ1uZlPTxNFYgJ77JIjY3uw2PmYeyrJ10E,20063
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
13
13
  structures/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- structures/core/notification_timers.py,sha256=G-QwpqP9HFv_Y7KsID9bLF-GluEJ1-duSJQN-zqJtM0,14977
15
- structures/core/notification_types.py,sha256=0SExh-VuImRz05jatnCu9lAfIFORUZ-kon9rjF4SXfI,12279
14
+ structures/core/notification_timers.py,sha256=KLjkVrlCCKTWtHJNUfI3U6ppAIZN8vPnIx1zCafRkKQ,16748
15
+ structures/core/notification_types.py,sha256=Ebl4i-mvyGe4luxeNiPmxf7T9bmghe8NU5Giu9pqPCo,13262
16
16
  structures/core/serializers.py,sha256=4W6kA7mhVvc-1OSiTl_w0rSio_HUsjIBm9qbkEr9vCY,20965
17
17
  structures/core/sovereignty.py,sha256=XKgjAFO4BfLpEEUz_hBr2DVDnvWBq9sL9EEQiT4T0n0,730
18
18
  structures/core/starbases.py,sha256=nw7skHYATrnAV-zuPAuxmhM5E4Aqjc_DHSU2TYWgBng,1757
@@ -20,12 +20,13 @@ structures/core/notification_embeds/__init__.py,sha256=30cpjKLZ5_OFtXDACDcjvWQAY
20
20
  structures/core/notification_embeds/billing_embeds.py,sha256=d9XkTyYH7U3UDZaqXu0WoN0wvlrT2S68Rfn2jEpVtM4,5164
21
21
  structures/core/notification_embeds/corporate_embeds.py,sha256=mfm6dDrgzupyRZ9TZGXML-UGoY_PymNj9LuR8EthdDA,6098
22
22
  structures/core/notification_embeds/helpers.py,sha256=0SlrLLFyV0IrdOYfIOLQs0xZgzK8bO7Iroqh7dZnm98,2974
23
- structures/core/notification_embeds/main.py,sha256=P8Ajvd9j4SUBpZde2IOejFUV5bEXMUWU4lolNjkrxWQ,16048
23
+ structures/core/notification_embeds/main.py,sha256=B8OReupxjSbtxqw2MXC9qN41A4Bw8x6_n0LIZlfIJxE,17311
24
24
  structures/core/notification_embeds/moonmining_embeds.py,sha256=5OJtfwoLE18mB62iwyHTcMo9eOPBC2vQFSjQlDnTcTY,7130
25
- structures/core/notification_embeds/orbital_embeds.py,sha256=ovAnTqrc2X0s-HhQS-UleI8J5-gJEO361HYJzcoAdeQ,2864
25
+ structures/core/notification_embeds/orbital_embeds.py,sha256=abU9eN7-4FV2wm6IbZt5O0hQZ09hdrkSJ4JaKLBksTE,2864
26
+ structures/core/notification_embeds/skyhook_embeds.py,sha256=Wl7G3jYin8IfSPFWfoBHndtvxiOUTIboD9xfJ1VJd_4,3019
26
27
  structures/core/notification_embeds/sov_embeds.py,sha256=_r4U5zN3MfEag9FCeN0my2d4qfMBUwYUGWW-oGftjn8,8901
27
- structures/core/notification_embeds/structures_embeds.py,sha256=YOLCnfxIaui7C8HXbWh3grq3eC6TwmdwC4h5ACd05U4,13236
28
- structures/core/notification_embeds/tower_embeds.py,sha256=n76URsS5xUOCXSYQMNzXeNk_msV08-0eNokeku1TDNs,5848
28
+ structures/core/notification_embeds/structures_embeds.py,sha256=o4tWS2TACW70PTNtJt3FJNt2WGGUKy6n1890PMJfHzc,13683
29
+ structures/core/notification_embeds/tower_embeds.py,sha256=Gowxiy5G655CPSJ76Jovpw2jZQYDCUXMB-jxanyiFHE,5848
29
30
  structures/core/notification_embeds/war_embeds.py,sha256=Wj5SuTP1jGRug8_x7qy8oyRCv9CjlZON7-RpJ2k57I4,18333
30
31
  structures/locale/django.pot,sha256=t4voMGKIXRUW7sYx7Rmut2tVyBtg2rUcIB5BK_POWTM,68368
31
32
  structures/locale/de/LC_MESSAGES/django.mo,sha256=Ok2o1b-v0o7uGfARfS6dmXLGMUHRjEp9nEjf0IJEYvM,3997
@@ -58,12 +59,14 @@ structures/migrations/0003_add_localization_and_unique_key.py,sha256=ZxJMfUtgUH2
58
59
  structures/migrations/0004_improve_localization.py,sha256=R29j2Ki9I_yOvEQTxEu_zMnZrR7JkSGpmvMTpp9XjqM,14014
59
60
  structures/migrations/0005_add_notification_types.py,sha256=aIgNZN4Gsvh9GiJ0i4XmXopT0qqjZTQrdVjZaVIJKP8,7087
60
61
  structures/migrations/0006_add_ownercharacter_disabled.py,sha256=yfcuwWHdSoF7HTEzdtQ1bGhI-K78SxCeE3g3z6UjbqI,726
62
+ structures/migrations/0007_add_notificationtypes_skyhook_metenox.py,sha256=5qxb2AyZyyHFAU39ScFW4eCHHWBL9lMszt0MzXJu4RM,7835
63
+ structures/migrations/0008_add_notificationtypes_skyhook_metenox.py,sha256=5QtcYJR7krqKheJ-vBb7QT771mK39aET7F07hhMy9q4,7844
61
64
  structures/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
65
  structures/models/__init__.py,sha256=Da0-Z4BtsZ_mlnI6XtyvoE0UtTuOA0psGCuVhVPVKrM,916
63
66
  structures/models/eveuniverse.py,sha256=vTIfzZL9guEDuZHQvRdG6pI4zSEdMqfVE-2SkHdqbRo,2213
64
67
  structures/models/notifications.py,sha256=HwQc-ChdP0ULuJgxUym9_CBsCWCmcHT7whlk9tB2vzw,35364
65
- structures/models/owners.py,sha256=8VDRL1fPep0TN6Nv5MJg1NC6_2V6bMJd6f-eda4-PJg,55697
66
- structures/models/structures_1.py,sha256=e1sI-2zMSKcPi2PyYA--fcc8rn-yQwODzlUHKjeWgLI,29778
68
+ structures/models/owners.py,sha256=9LLjOv7QAICAodx6XUEGGuO6RxLY4h6hZs8EWWiobs0,57875
69
+ structures/models/structures_1.py,sha256=zk380uG2DuQ7exO7THbq5TE5Ro2jr6EyVCIxRJXHIJI,29958
67
70
  structures/models/structures_2.py,sha256=g5Pct5jNmZC-n7fnpLs5UyiP9JLrGdI1vjYucHTV_wQ,10371
68
71
  structures/static/structures/css/global.css,sha256=R4LEH9PwLoN77qkqBK7u2y_vzRC3fq8X_zKnAW7yhiA,1165
69
72
  structures/static/structures/css/main.css,sha256=kNgHhC3tVG376h8-6b71MtiERhYZ48cTIno5Kj6ZFGo,303
@@ -131,9 +134,9 @@ structures/static/structures/vendor/datatables/plugins/filterDropDown.min.js,sha
131
134
  structures/static/structures/vendor/datatables/plugins/rowGroup.bootstrap.min.css,sha256=mfb-mieZDwLASMlQTUNXrZQr8OXvQyEDfV3Xz3E7DSU,384
132
135
  structures/static/structures/vendor/datatables/plugins/rowGroup.dataTables.min.css,sha256=mfb-mieZDwLASMlQTUNXrZQr8OXvQyEDfV3Xz3E7DSU,384
133
136
  structures/templates/structures/base.html,sha256=ND0JjP2Pa537FXOrIj3cziHfDbTh0ZNzrLFJ_zpVhw8,337
134
- structures/templates/structures/public.html,sha256=x9IJXBmToPcBZygWfzhvipopP_yWPaS3VJGSKUASDYQ,3233
137
+ structures/templates/structures/public.html,sha256=R3kjhr1MLC5r9r8L3t-1-Nh7-ngKbRiiZNIwgpsGg70,3239
135
138
  structures/templates/structures/statistics.html,sha256=rVI_wPW4VXIO3IoWna8_GoqWCc5ra-6Jc9iekfusS78,1736
136
- structures/templates/structures/structures.html,sha256=87FkTebE2NvzVh9_nkffDo9wOX4tanLu66xpnG5--SI,8322
139
+ structures/templates/structures/structures.html,sha256=WdtBxY3XumtpO4b23Arw8lVqGJf_gHIeD2AAxaKf7cU,8327
137
140
  structures/templates/structures/modals/fitting_assets.html,sha256=0GSpDAk-wgvaZdxM9JzteUYhoPsek5y-L4TdG2q5Sbg,264
138
141
  structures/templates/structures/modals/fitting_gfx.html,sha256=hmdU1Zv09woGKigUugbBRxScKQun8l81yEPUMGrok2g,9530
139
142
  structures/templates/structures/modals/poco_details.html,sha256=uwaEM0jDvkdu_Lff2mUKwm7pn1KXePcgN9yBwFHsQO4,2705
@@ -159,13 +162,13 @@ structures/templatetags/structures.py,sha256=vSt5AnfYuo11q1SxiskT4oshSMsZ9ZgM0nY
159
162
  structures/tests/__init__.py,sha256=9MrJzKr8DdsQY3-79v188pTpwqT4TDQ46vKnBJAGqic,75
160
163
  structures/tests/test_admin.py,sha256=cb_AbOanp31k-oZhaUXCqnlkUu87EgNddq_VQKbB_Dk,26839
161
164
  structures/tests/test_helpers.py,sha256=BQC-4H-9-v5qW4nugqy0bkxuGlA3UO2clYY2lI2LjoY,4893
162
- structures/tests/test_managers_1.py,sha256=ruKq5VRYHdStDQe3uzVhcxF0seQQfmdudJEUYXzi8bY,34539
165
+ structures/tests/test_managers_1.py,sha256=4dnlK7Le04eJUPjJc9ex5BxZWIJGAyEvdKuuYXU2gqY,34846
163
166
  structures/tests/test_managers_2.py,sha256=FISr_NT1Qnu9j1JYYTceNsUk8k9rfCTKwjKi5WUVbPs,3025
164
167
  structures/tests/test_tasks.py,sha256=reL1rPv_kvTgsC4lq5SXulkbEHaJrw5B1-hFI4tiDWY,17269
165
168
  structures/tests/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
166
169
  structures/tests/core/test_notification_structuretimers.py,sha256=OvldjgIHmRVsqoC9C6VJRqwS9WeRFMgpyutRc69PjAU,10857
167
- structures/tests/core/test_notification_types.py,sha256=WNJGXoxO3LbgxPgCH416IJElREWFBtwx5pw8IulsmYo,9881
168
- structures/tests/core/test_notifications_timerboard.py,sha256=OMkAWH_jWXzCwotp6W2qWG6GpSGisyunZYOoy1UZomU,5583
170
+ structures/tests/core/test_notification_types.py,sha256=2J5A8Dr9UHhzLEj6QTMty5iZXlNkQxtFmLvU8Wpdno4,10447
171
+ structures/tests/core/test_notifications_timers.py,sha256=7Os0xmrfDV2zJeBOFYb7K1KGcwpVHq36IglOdjps6Ac,5915
169
172
  structures/tests/core/test_serializers.py,sha256=ACs6x1IhesoJBFG76RmlglDWqaMlOuqq5kPyzvjGeKI,7056
170
173
  structures/tests/core/test_sovereignty.py,sha256=SGgNw6NxmaU3jV-EDhKJRLfHnRnqDCwm4oCoO-8gt9w,821
171
174
  structures/tests/core/test_starbases.py,sha256=Q3EZVIKZGzxUUvvn0TvZYOL9YQ-baiTRTT83xWqTAhQ,3186
@@ -173,8 +176,8 @@ structures/tests/core/notification_embeds/__init__.py,sha256=47DEQpj8HBSa-_TImW-
173
176
  structures/tests/core/notification_embeds/test_helpers.py,sha256=HG20TC8Bz7NqpaQWo6uvrsxfNIwTL2Zi_NRkh3UyN2Y,1776
174
177
  structures/tests/core/notification_embeds/test_main.py,sha256=rSUm8dGsddjnX_OUwtCh-wd5UhJ6ttTsfxc1soAoDv8,14667
175
178
  structures/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
176
- structures/tests/integration/test_tasks.py,sha256=s6hL5UBotDmhLq7NUiOad72W-S_18u_yAHiLWVryVi8,23617
177
- structures/tests/integration/test_views.py,sha256=SkbIposTUjo0nujHL4WEaZO7nY1Bfuvm805H39XUv-g,4361
179
+ structures/tests/integration/test_tasks.py,sha256=uhl7TJNELrL1vSDaRee0xEKNMLJuVqRIM32cIVUa_h4,27217
180
+ structures/tests/integration/test_views.py,sha256=qlw1VzlyGW_xnWC-Ii16IHECO-F2x25sYbXeqz2T8IY,4364
178
181
  structures/tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
182
  structures/tests/models/test_eveuniverse.py,sha256=bQ1upOLfoivfaa9KCrzjWvSH_EvL2STuvfFfZ9saIMY,1623
180
183
  structures/tests/models/test_notifications_1.py,sha256=xVX4an54sZM8WLUdsAGUG2Nb4Rl7W5FBzhI0hBhJo5g,30300
@@ -185,19 +188,19 @@ structures/tests/models/test_owners_1.py,sha256=o8AJasQ0-Pdb0FRFZcmNcMGjaIk8fH3O
185
188
  structures/tests/models/test_owners_2.py,sha256=gkTXpSibPWs1XfZtPvyeEvVebyYZcKERD9GQSYSClYk,21911
186
189
  structures/tests/models/test_owners_3.py,sha256=cpDkfFkVvC1v4uuXha1vGUmWZ163huYTUDuZyed9Rdc,16947
187
190
  structures/tests/models/test_owners_4.py,sha256=_VP4QsPYGwBnn_bVN4aNX2ZVeJzMAzWObZrgCJkOPgY,19496
188
- structures/tests/models/test_owners_5.py,sha256=lTSfVY3rPOLyF-IhlKPT4mbRqvuN_NA-kyU0Vzzp9qY,31607
191
+ structures/tests/models/test_owners_5.py,sha256=TIF_SqJqyGja8FBV2lQNAC4yff1usmJ4e0QW7e68zTg,36929
189
192
  structures/tests/models/test_owners_6.py,sha256=R9UE2QGwiGTWLHzzOZwGQPWJrAPwIIl7UwrHH-ki4Ak,940
190
- structures/tests/models/test_structures.py,sha256=6HktwBOsmRtRq5MnRlZnvNixUsWUpRni_XnPjNpMN0Y,41469
193
+ structures/tests/models/test_structures.py,sha256=iCCa0yYyPHieNfj8TQbdoIv141oLc6hlICZ6AsTnHAw,41849
191
194
  structures/tests/testdata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
192
- structures/tests/testdata/create_eveuniverse.py,sha256=E-Fh-dmuHmLZcqgK2U6mwt9W6dI7H99bG7DaETfcVQY,2129
193
- structures/tests/testdata/entities.json,sha256=kmcmmbHG_igHwvkpAJGHQEztEXjlo8McDuojpEBmgqU,32147
195
+ structures/tests/testdata/create_eveuniverse.py,sha256=6CYgXtJaEwxWvQFyH-P0SKsRqeMuSyJ92ZJiXe_-nuY,2256
196
+ structures/tests/testdata/entities.json,sha256=vmb0uhwTpD0gycGAakgYidr3qSbnHiMubAd4u7T2l70,36053
194
197
  structures/tests/testdata/esi_data.json,sha256=DX47oSlRZIPxlPueMfiNElbZbAip2cp3LAUmv8GAPJ0,13864
195
- structures/tests/testdata/eveuniverse.json,sha256=Z8_EXOF8XNvls9RfBYIHhoNX0rj0NqcjInTU6tZuwhI,993284
196
- structures/tests/testdata/factories.py,sha256=KNXxOad44DKD0luQ7QS0DepnCr1S_Z6qwfiXnNDy10I,24774
197
- structures/tests/testdata/generate_notifications.py,sha256=nE077mVHVmOVudKIGMtHUfBIcV5Ch5Z0IngD1gp5yQk,5746
198
+ structures/tests/testdata/eveuniverse.json,sha256=3fhD72lUNLj96wO4ASbpNcdH_8VbqcXUvKUXR6j0768,1028885
199
+ structures/tests/testdata/factories.py,sha256=UF7Zao2-DjVFLZLEBWaJv4Pg1uw5D6p0TO8ZKuoAI_8,25293
200
+ structures/tests/testdata/generate_notifications.py,sha256=lhcnbsnE4O6g0OFUAYO2sCfu8vmwBcFtxn-TuTLtFnM,5417
198
201
  structures/tests/testdata/generate_notifications_2.py,sha256=mdoGXd9vgy_opmrwTr9MfGe-QieHV4BHtRA7VFzxFKM,1413
199
202
  structures/tests/testdata/generate_structures.py,sha256=4p2ypDj-goniBnraTP2KfWzEX3YLj0qhKPNTfCXy05g,9134
200
- structures/tests/testdata/helpers.py,sha256=nUecEhe9NqP70zMo8gbAZaWIm2NvzvnF4w9doMtFPY8,6183
203
+ structures/tests/testdata/helpers.py,sha256=FSlg7-6Dn3aMQnQPUnH9o9r8WsV1_BYxElm-E9x_5uo,6316
201
204
  structures/tests/testdata/load_eveuniverse.py,sha256=e3XQNYZXwmhfLQdvO4D1dfbSwhF1Zwr3ag9nG9E3XDM,395
202
205
  structures/tests/testdata/tasks_loadtest.py,sha256=Hn0UVeaMfdi5S4W12lsb6g_xwjQcNYDmeXvQdTsPfBM,963
203
206
  structures/tests/testdata/test_generate_structures.py,sha256=vpReGRROduZsGB99Dq7yPKNKSkSLFdLM_esdf5TTnnI,414
@@ -205,14 +208,14 @@ structures/tests/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
205
208
  structures/tests/views/test_public.py,sha256=FTaT3VUOnoT4t9rCCTCGyDrberpa8CRJHsXuqAw2PQE,1372
206
209
  structures/tests/views/test_service_status.py,sha256=mWkP13HnKRa3ltsZ2FKJuZRJjvYic9wjgQ1J3qA8n-k,4197
207
210
  structures/tests/views/test_statistics.py,sha256=MHt31AIX9_jt8-yP8XsbsiRRUKEtY8mQJbk11saFYZc,2626
208
- structures/tests/views/test_structures.py,sha256=4DrURs32GvbMnXXJm1dC1ZhsDVhJ50iKyiqTRyyRe70,28284
211
+ structures/tests/views/test_structures.py,sha256=KbD3RqUKhWxcRsHfZbgyNHWj7Z9bJt7wOj45s0y17EY,28489
209
212
  structures/tests/views/utils.py,sha256=0ALPjL8d0vcIWa_Pl4_gDl1qtBp71oDqyZLJyvDj-Uc,247
210
213
  structures/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
211
214
  structures/views/common.py,sha256=Z_hcpEpkGrhwFdMAAMON_DqsfQ_lMyRwOMl5ROo_aSk,818
212
215
  structures/views/public.py,sha256=-Tel-poYKZTy8eQllhsWUxVf7HYBuCfeL9JWlbKhs7s,3035
213
216
  structures/views/statistics.py,sha256=7jj8b9ATsYwE7Cg6gMp-bYx29nV43GdWYun9WBggGkM,4709
214
217
  structures/views/status.py,sha256=gcahbk6dPIZDqkaNHDAsEHyDWLzicTK18Fom0A6xx3c,718
215
- structures/views/structures.py,sha256=E1ssnqr2zp0rLQ3txIa6XkcX3NStNjMkuQM4iNjt6yw,22560
218
+ structures/views/structures.py,sha256=Wb57jFfRa0Zxo6TxKmOCQ-jtopzPtHe0go6gnJn40CA,22584
216
219
  structures/webhooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
220
  structures/webhooks/core.py,sha256=mP25MbQG8Yv2YayDFcR6x2V30eqXhR2q5u4SRefblf4,6573
218
221
  structures/webhooks/managers.py,sha256=L3G3AmsyDeif_lfpWshmAxQ61UGJ9w8i9lZaF2jbOtQ,1117
@@ -220,7 +223,7 @@ structures/webhooks/models.py,sha256=kUkt9rnRQIJIrU9Bjcs34rvkb-TMbUubHdn-kny08kI
220
223
  structures/webhooks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
221
224
  structures/webhooks/tests/test_core.py,sha256=4NcEAQgK2KhQkFOxYh2ad0S-qUWh1DNGDmLo5Mo5opI,6762
222
225
  structures/webhooks/tests/test_utils.py,sha256=ekADFv0JOEtXeqdiejbeqrABO__Q1flJHzVieQ7L9e0,459
223
- aa_structures-2.12.0.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
224
- aa_structures-2.12.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
225
- aa_structures-2.12.0.dist-info/METADATA,sha256=E2IAO0tGX_bRqM9r1ryldZsIGyv22TLHn8tMs8zQ2zs,5972
226
- aa_structures-2.12.0.dist-info/RECORD,,
226
+ aa_structures-2.14.0.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
227
+ aa_structures-2.14.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
228
+ aa_structures-2.14.0.dist-info/METADATA,sha256=X7YMjOqlJc_CkmHeFWJiYgKb8QLDPdnzPibT_bh6ReM,5972
229
+ aa_structures-2.14.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.12.0"
6
+ __version__ = "2.14.0"
7
7
  __title__ = "Structures"
structures/admin.py CHANGED
@@ -324,7 +324,7 @@ class NotificationBaseAdmin(admin.ModelAdmin):
324
324
  message = format_lazy("{first} {second}", first=first, second=second)
325
325
  else:
326
326
  message = first
327
- message = format_lazy({first})
327
+ message = format_lazy(first)
328
328
  self.message_user(request, message)
329
329
 
330
330
 
@@ -49,6 +49,10 @@ STRUCTURES_FEATURE_REFUELED_NOTIFICATIONS = clean_setting(
49
49
  )
50
50
  """Enable / disable refueled notifications feature."""
51
51
 
52
+ STRUCTURES_FEATURE_SKYHOOKS = clean_setting("STRUCTURES_FEATURE_SKYHOOKS", False)
53
+ """Show skyhooks in structures list."""
54
+
55
+
52
56
  STRUCTURES_FEATURE_STARBASES = clean_setting("STRUCTURES_FEATURE_STARBASES", True)
53
57
  """Enable / disable starbases feature."""
54
58
 
structures/constants.py CHANGED
@@ -42,6 +42,7 @@ class EveTypeId(IntEnum):
42
42
  IHUB = 32458
43
43
  JUMP_GATE = 35841
44
44
  LIQUID_OZONE = 16273
45
+ ORBITAL_SKYHOOK = 81080
45
46
  NITROGEN_FUEL_BLOCK = 4051
46
47
  STRONTIUM = 16275
47
48
  TCU = 32226
@@ -19,7 +19,7 @@ from structures.core.notification_types import NotificationType
19
19
  from structures.helpers import get_or_create_eve_entity, is_absolute_url
20
20
  from structures.models.notifications import Notification, NotificationBase, Webhook
21
21
 
22
- from .helpers import target_datetime_formatted
22
+ from .helpers import gen_alliance_link, gen_corporation_link, target_datetime_formatted
23
23
 
24
24
  logger = LoggerAddTag(get_extension_logger(__name__), __title__)
25
25
 
@@ -77,9 +77,9 @@ class NotificationBaseEmbed:
77
77
  damage_text = " | ".join(damage_parts)
78
78
  return damage_text
79
79
 
80
- def get_aggressor_link(self) -> str:
80
+ def gen_aggressor_link(self) -> str:
81
81
  """Returns the aggressor link from a parsed_text for POS and POCOs only."""
82
- if self._data.get("aggressorAllianceID"):
82
+ if key := self._data.get("aggressorAllianceID"):
83
83
  key = "aggressorAllianceID"
84
84
  elif self._data.get("aggressorCorpID"):
85
85
  key = "aggressorCorpID"
@@ -90,6 +90,16 @@ class NotificationBaseEmbed:
90
90
  entity = get_or_create_eve_entity(id=self._data[key])
91
91
  return Webhook.create_link(entity.name, entity.profile_url)
92
92
 
93
+ def gen_attacker_link(self) -> str:
94
+ """Returns the attacker link from a parsed_text for Upwell structures only."""
95
+ if name := self._data.get("allianceName"):
96
+ return gen_alliance_link(name)
97
+
98
+ if name := self._data.get("corpName"):
99
+ return gen_corporation_link(name)
100
+
101
+ return _("(unknown)")
102
+
93
103
  def fuel_expires_target_date(self) -> str:
94
104
  """Return calculated target date when fuel expires. Returns '?' when no data."""
95
105
  if self._structure and self._structure.fuel_expires_at:
@@ -200,6 +210,13 @@ class NotificationBaseEmbed:
200
210
  NotificationOrbitalAttacked,
201
211
  NotificationOrbitalReinforced,
202
212
  )
213
+ from .skyhook_embeds import (
214
+ NotificationSkyhookDeployed,
215
+ NotificationSkyhookDestroyed,
216
+ NotificationSkyhookLostShield,
217
+ NotificationSkyhookOnline,
218
+ NotificationSkyhookUnderAttack,
219
+ )
203
220
  from .sov_embeds import (
204
221
  NotificationSovAllAnchoringMsg,
205
222
  NotificationSovAllClaimAcquiredMsg,
@@ -216,6 +233,8 @@ class NotificationBaseEmbed:
216
233
  NotificationStructureJumpFuelAlert,
217
234
  NotificationStructureLostArmor,
218
235
  NotificationStructureLostShield,
236
+ NotificationStructureLowReagentsAlert,
237
+ NotificationStructureNoReagentsAlert,
219
238
  NotificationStructureOnline,
220
239
  NotificationStructureOwnershipTransferred,
221
240
  NotificationStructureRefueledExtra,
@@ -260,76 +279,84 @@ class NotificationBaseEmbed:
260
279
  NT = NotificationType
261
280
  notif_type_2_class = {
262
281
  # Billing
263
- NT.BILLING_CORP_ALL_BILL_MSG: NotificationCorpAllBillMsg,
264
282
  NT.BILLING_BILL_OUT_OF_MONEY_MSG: NotificationBillingBillOutOfMoneyMsg,
283
+ NT.BILLING_CORP_ALL_BILL_MSG: NotificationCorpAllBillMsg,
265
284
  NT.BILLING_I_HUB_BILL_ABOUT_TO_EXPIRE: NotificationBillingIHubBillAboutToExpire,
266
285
  NT.BILLING_I_HUB_DESTROYED_BY_BILL_FAILURE: NotificationBillingIHubDestroyedByBillFailure,
267
286
  # character
268
- NT.CORP_APP_NEW_MSG: NotificationCorpAppNewMsg,
287
+ NT.CHAR_APP_ACCEPT_MSG: NotificationCharAppAcceptMsg,
288
+ NT.CHAR_APP_WITHDRAW_MSG: NotificationCharAppWithdrawMsg,
289
+ NT.CHAR_LEFT_CORP_MSG: NotificationCharLeftCorpMsg,
269
290
  NT.CORP_APP_INVITED_MSG: NotificationCorpAppInvitedMsg,
291
+ NT.CORP_APP_NEW_MSG: NotificationCorpAppNewMsg,
270
292
  NT.CORP_APP_REJECT_CUSTOM_MSG: NotificationCorpAppRejectCustomMsg,
271
293
  NT.CORP_APP_REJECT_MSG: NotificationCharAppRejectMsg,
272
- NT.CHAR_APP_WITHDRAW_MSG: NotificationCharAppWithdrawMsg,
273
- NT.CHAR_APP_ACCEPT_MSG: NotificationCharAppAcceptMsg,
274
- NT.CHAR_LEFT_CORP_MSG: NotificationCharLeftCorpMsg,
275
294
  # moonmining
276
- NT.MOONMINING_EXTRACTION_STARTED: NotificationMoonminningExtractionStarted,
277
- NT.MOONMINING_EXTRACTION_FINISHED: NotificationMoonminningExtractionFinished,
278
295
  NT.MOONMINING_AUTOMATIC_FRACTURE: NotificationMoonminningAutomaticFracture,
279
296
  NT.MOONMINING_EXTRACTION_CANCELLED: NotificationMoonminningExtractionCanceled,
297
+ NT.MOONMINING_EXTRACTION_FINISHED: NotificationMoonminningExtractionFinished,
298
+ NT.MOONMINING_EXTRACTION_STARTED: NotificationMoonminningExtractionStarted,
280
299
  NT.MOONMINING_LASER_FIRED: NotificationMoonminningLaserFired,
281
300
  # Orbitals
282
301
  NT.ORBITAL_ATTACKED: NotificationOrbitalAttacked,
283
302
  NT.ORBITAL_REINFORCED: NotificationOrbitalReinforced,
284
303
  # Sov
285
- NT.SOV_ENTOSIS_CAPTURE_STARTED: NotificationSovEntosisCaptureStarted,
286
- NT.SOV_COMMAND_NODE_EVENT_STARTED: NotificationSovCommandNodeEventStarted,
304
+ NT.SOV_ALL_ANCHORING_MSG: NotificationSovAllAnchoringMsg,
287
305
  NT.SOV_ALL_CLAIM_ACQUIRED_MSG: NotificationSovAllClaimAcquiredMsg,
288
306
  NT.SOV_ALL_CLAIM_LOST_MSG: NotificationSovAllClaimLostMsg,
289
- NT.SOV_STRUCTURE_REINFORCED: NotificationSovStructureReinforced,
307
+ NT.SOV_COMMAND_NODE_EVENT_STARTED: NotificationSovCommandNodeEventStarted,
308
+ NT.SOV_ENTOSIS_CAPTURE_STARTED: NotificationSovEntosisCaptureStarted,
290
309
  NT.SOV_STRUCTURE_DESTROYED: NotificationSovStructureDestroyed,
291
- NT.SOV_ALL_ANCHORING_MSG: NotificationSovAllAnchoringMsg,
310
+ NT.SOV_STRUCTURE_REINFORCED: NotificationSovStructureReinforced,
292
311
  # Towers
293
312
  NT.TOWER_ALERT_MSG: NotificationTowerAlertMsg,
294
- NT.TOWER_RESOURCE_ALERT_MSG: NotificationTowerResourceAlertMsg,
295
313
  NT.TOWER_REFUELED_EXTRA: NotificationTowerRefueledExtra,
296
314
  NT.TOWER_REINFORCED_EXTRA: NotificationTowerReinforcedExtra,
315
+ NT.TOWER_RESOURCE_ALERT_MSG: NotificationTowerResourceAlertMsg,
316
+ # Skyhooks
317
+ NT.SKYHOOK_DEPLOYED: NotificationSkyhookDeployed,
318
+ NT.SKYHOOK_DESTROYED: NotificationSkyhookDestroyed,
319
+ NT.SKYHOOK_LOST_SHIELDS: NotificationSkyhookLostShield,
320
+ NT.SKYHOOK_ONLINE: NotificationSkyhookOnline,
321
+ NT.SKYHOOK_UNDER_ATTACK: NotificationSkyhookUnderAttack,
297
322
  # Upwell structures
298
- NT.STRUCTURE_ONLINE: NotificationStructureOnline,
323
+ NT.OWNERSHIP_TRANSFERRED: NotificationStructureOwnershipTransferred,
324
+ NT.STRUCTURE_ANCHORING: NotificationStructureAnchoring,
325
+ NT.STRUCTURE_DESTROYED: NotificationStructureDestroyed,
299
326
  NT.STRUCTURE_FUEL_ALERT: NotificationStructureFuelAlert,
300
327
  NT.STRUCTURE_JUMP_FUEL_ALERT: NotificationStructureJumpFuelAlert,
328
+ NT.STRUCTURE_LOST_ARMOR: NotificationStructureLostArmor,
329
+ NT.STRUCTURE_LOST_SHIELD: NotificationStructureLostShield,
330
+ NT.STRUCTURE_LOW_REAGENTS_ALERT: NotificationStructureLowReagentsAlert,
331
+ NT.STRUCTURE_NO_REAGENTS_ALERT: NotificationStructureNoReagentsAlert,
332
+ NT.STRUCTURE_ONLINE: NotificationStructureOnline,
301
333
  NT.STRUCTURE_REFUELED_EXTRA: NotificationStructureRefueledExtra,
334
+ NT.STRUCTURE_REINFORCEMENT_CHANGED: NotificationStructureReinforceChange,
302
335
  NT.STRUCTURE_SERVICES_OFFLINE: NotificationStructureServicesOffline,
303
- NT.STRUCTURE_WENT_LOW_POWER: NotificationStructureWentLowPower,
304
- NT.STRUCTURE_WENT_HIGH_POWER: NotificationStructureWentHighPower,
305
336
  NT.STRUCTURE_UNANCHORING: NotificationStructureUnanchoring,
306
337
  NT.STRUCTURE_UNDER_ATTACK: NotificationStructureUnderAttack,
307
- NT.STRUCTURE_LOST_SHIELD: NotificationStructureLostShield,
308
- NT.STRUCTURE_LOST_ARMOR: NotificationStructureLostArmor,
309
- NT.STRUCTURE_DESTROYED: NotificationStructureDestroyed,
310
- NT.OWNERSHIP_TRANSFERRED: NotificationStructureOwnershipTransferred,
311
- NT.STRUCTURE_ANCHORING: NotificationStructureAnchoring,
312
- NT.STRUCTURE_REINFORCEMENT_CHANGED: NotificationStructureReinforceChange,
338
+ NT.STRUCTURE_WENT_HIGH_POWER: NotificationStructureWentHighPower,
339
+ NT.STRUCTURE_WENT_LOW_POWER: NotificationStructureWentLowPower,
313
340
  # War
314
341
  NT.WAR_ACCEPTED_ALLY: NotificationAcceptedAlly,
342
+ NT.WAR_ALL_WAR_CORP_JOINED_ALLIANCE_MSG: NotificationAllWarCorpJoinedAllianceMsg,
343
+ NT.WAR_ALL_WAR_SURRENDER_MSG: NotificationAllWarSurrenderMsg,
315
344
  NT.WAR_ALLY_JOINED_WAR_AGGRESSOR_MSG: NotificationAllyJoinedWarMsg,
316
345
  NT.WAR_ALLY_JOINED_WAR_ALLY_MSG: NotificationAllyJoinedWarMsg,
317
346
  NT.WAR_ALLY_JOINED_WAR_DEFENDER_MSG: NotificationAllyJoinedWarMsg,
318
- NT.WAR_ALL_WAR_CORP_JOINED_ALLIANCE_MSG: NotificationAllWarCorpJoinedAllianceMsg,
319
- NT.WAR_ALL_WAR_SURRENDER_MSG: NotificationAllWarSurrenderMsg,
347
+ NT.WAR_CORP_WAR_SURRENDER_MSG: NotificationCorpWarSurrenderMsg,
320
348
  NT.WAR_CORPORATION_BECAME_ELIGIBLE: NotificationWarCorporationBecameEligible,
321
349
  NT.WAR_CORPORATION_NO_LONGER_ELIGIBLE: NotificationWarCorporationNoLongerEligible,
322
350
  NT.WAR_DECLARE_WAR: NotificationDeclareWar,
323
- NT.WAR_MERC_OFFERED_NEGOTIATION_MSG: NotificationMercOfferedNegotiationMsg,
324
- NT.WAR_MERC_OFFER_RETRACTED_MSG: NotificationMercOfferRetractedMsg,
325
- NT.WAR_CORP_WAR_SURRENDER_MSG: NotificationCorpWarSurrenderMsg,
326
351
  NT.WAR_HQ_REMOVED_FROM_SPACE: NotificationWarHQRemovedFromSpace,
327
- NT.WAR_OFFERED_TO_ALLY: NotificationOfferedToAlly,
352
+ NT.WAR_INVALID: NotificationWarInvalid,
353
+ NT.WAR_MERC_OFFER_RETRACTED_MSG: NotificationMercOfferRetractedMsg,
354
+ NT.WAR_MERC_OFFERED_NEGOTIATION_MSG: NotificationMercOfferedNegotiationMsg,
328
355
  NT.WAR_OFFERED_SURRENDER: NotificationOfferedSurrender,
356
+ NT.WAR_OFFERED_TO_ALLY: NotificationOfferedToAlly,
329
357
  NT.WAR_WAR_ADOPTED: NotificationWarAdopted,
330
358
  NT.WAR_WAR_DECLARED: NotificationWarDeclared,
331
359
  NT.WAR_WAR_INHERITED: NotificationWarInherited,
332
- NT.WAR_INVALID: NotificationWarInvalid,
333
360
  NT.WAR_WAR_RETRACTED_BY_CONCORD: NotificationWarRetractedByConcord,
334
361
  NT.WAR_WAR_SURRENDER_OFFER_MSG: NotificationWarSurrenderOfferMsg,
335
362
  }
@@ -31,7 +31,7 @@ class NotificationOrbitalEmbed(NotificationBaseEmbed):
31
31
  self._notification.eve_solar_system()
32
32
  )
33
33
  self._owner_link = gen_corporation_link(str(notification.owner))
34
- self._aggressor_link = self.get_aggressor_link()
34
+ self._aggressor_link = self.gen_aggressor_link()
35
35
  self._thumbnail = dhooks_lite.Thumbnail(
36
36
  self._structure_type.icon_url(size=self.ICON_DEFAULT_SIZE)
37
37
  )
@@ -0,0 +1,89 @@
1
+ """Skyhook embeds."""
2
+
3
+ # pylint: disable=missing-class-docstring
4
+
5
+ import dhooks_lite
6
+
7
+ from django.utils.translation import gettext as _
8
+
9
+ from app_utils.datetime import ldap_time_2_datetime
10
+
11
+ from structures.models import Notification, Webhook
12
+
13
+ from .helpers import (
14
+ gen_corporation_link,
15
+ gen_solar_system_text,
16
+ target_datetime_formatted,
17
+ )
18
+ from .main import NotificationBaseEmbed
19
+
20
+
21
+ class NotificationSkyhookEmbed(NotificationBaseEmbed):
22
+ """Base class for most structure related notification embeds."""
23
+
24
+ def __init__(self, n: Notification) -> None:
25
+ super().__init__(n)
26
+ type_ = n.eve_structure_type("typeID")
27
+ solar_system = n.eve_solar_system("solarsystemID")
28
+ self._description = _(
29
+ "The %(structure_type)s at **%(planet)s** "
30
+ "in %(solar_system)s belonging to %(owner_link)s "
31
+ ) % {
32
+ "structure_type": type_,
33
+ "planet": n.eve_planet(),
34
+ "solar_system": gen_solar_system_text(solar_system),
35
+ "owner_link": gen_corporation_link(str(n.owner)),
36
+ }
37
+ self._thumbnail = dhooks_lite.Thumbnail(
38
+ type_.icon_url(size=self.ICON_DEFAULT_SIZE)
39
+ )
40
+
41
+
42
+ class NotificationSkyhookDeployed(NotificationSkyhookEmbed):
43
+ def __init__(self, n: Notification) -> None:
44
+ super().__init__(n)
45
+ self._title = _("Skyhook has started onlining")
46
+ self._description += _("has started onlining.")
47
+ self._color = Webhook.Color.INFO
48
+
49
+
50
+ class NotificationSkyhookDestroyed(NotificationSkyhookEmbed):
51
+ def __init__(self, n: Notification) -> None:
52
+ super().__init__(n)
53
+ self._title = _("Skyhook destroyed")
54
+ self._description += _("has been destroyed.")
55
+ self._color = Webhook.Color.DANGER
56
+
57
+
58
+ class NotificationSkyhookLostShield(NotificationSkyhookEmbed):
59
+ def __init__(self, n: Notification) -> None:
60
+ super().__init__(n)
61
+ self._title = _("Skyhook lost shield")
62
+ timer_ends_at = ldap_time_2_datetime(self._data["timestamp"])
63
+ self._description += _(
64
+ "has lost its shields and is now in reinforcement state until : %s"
65
+ ) % target_datetime_formatted(timer_ends_at)
66
+ self._color = Webhook.Color.DANGER
67
+
68
+
69
+ class NotificationSkyhookOnline(NotificationSkyhookEmbed):
70
+ def __init__(self, n: Notification) -> None:
71
+ super().__init__(n)
72
+ self._title = _("Skyhook online")
73
+ self._description += _("is now online.")
74
+ self._color = Webhook.Color.SUCCESS
75
+
76
+
77
+ class NotificationSkyhookUnderAttack(NotificationSkyhookEmbed):
78
+ def __init__(self, n: Notification) -> None:
79
+ super().__init__(n)
80
+ self._title = _("Skyhook under attack")
81
+ self._description += _(
82
+ "is under attack by %(attacker)s.\n"
83
+ "%(damage_text)s"
84
+ % {
85
+ "attacker": self.gen_attacker_link(),
86
+ "damage_text": self.compile_damage_text("Percentage"),
87
+ }
88
+ )
89
+ self._color = Webhook.Color.DANGER
@@ -14,7 +14,6 @@ from structures.helpers import get_or_create_eve_entity, get_or_create_eve_type
14
14
  from structures.models import Notification, Structure, Webhook
15
15
 
16
16
  from .helpers import (
17
- gen_alliance_link,
18
17
  gen_corporation_link,
19
18
  gen_solar_system_text,
20
19
  target_datetime_formatted,
@@ -165,21 +164,11 @@ class NotificationStructureUnderAttack(NotificationStructureEmbed):
165
164
  super().__init__(notification)
166
165
  self._title = _("Structure under attack")
167
166
  self._description += _("is under attack by %(attacker)s.\n%(damage_text)s") % {
168
- "attacker": self._get_attacker_link(),
167
+ "attacker": self.gen_attacker_link(),
169
168
  "damage_text": self.compile_damage_text("Percentage"),
170
169
  }
171
170
  self._color = Webhook.Color.DANGER
172
171
 
173
- def _get_attacker_link(self) -> str:
174
- """Returns the attacker link from a parsed_text for Upwell structures only."""
175
- if self._data.get("allianceName"):
176
- return gen_alliance_link(self._data["allianceName"])
177
-
178
- if self._data.get("corpName"):
179
- return gen_corporation_link(self._data["corpName"])
180
-
181
- return _("(unknown)")
182
-
183
172
 
184
173
  class NotificationStructureLostShield(NotificationStructureEmbed):
185
174
  def __init__(self, notification: Notification) -> None:
@@ -324,3 +313,25 @@ class NotificationStructureReinforceChange(NotificationBaseEmbed):
324
313
  _("\n\nChange becomes effective at %s.")
325
314
  ) % target_datetime_formatted(change_effective)
326
315
  self._color = Webhook.Color.INFO
316
+
317
+
318
+ class NotificationStructureLowReagentsAlert(NotificationStructureEmbed):
319
+ def __init__(self, notification: Notification) -> None:
320
+ super().__init__(notification)
321
+ self._title = _("Structure low on reagents")
322
+ self._description += _(
323
+ "has insufficient reagents present to support "
324
+ "one full day of moon drill activity."
325
+ )
326
+ self._color = Webhook.Color.WARNING
327
+
328
+
329
+ class NotificationStructureNoReagentsAlert(NotificationStructureEmbed):
330
+ def __init__(self, notification: Notification) -> None:
331
+ super().__init__(notification)
332
+ self._title = _("Structure out of reagents")
333
+ self._description += _(
334
+ "has run out of reagents, "
335
+ "which is preventing further moon material production."
336
+ )
337
+ self._color = Webhook.Color.DANGER
@@ -56,7 +56,7 @@ class NotificationTowerEmbed(NotificationBaseEmbed):
56
56
  class NotificationTowerAlertMsg(NotificationTowerEmbed):
57
57
  def __init__(self, notification: Notification) -> None:
58
58
  super().__init__(notification)
59
- aggressor_link = self.get_aggressor_link()
59
+ aggressor_link = self.gen_aggressor_link()
60
60
  damage_text = self.compile_damage_text("Value", 100)
61
61
  self._title = _("Starbase under attack")
62
62
  self._description += _("is under attack by %(aggressor)s.\n%(damage_text)s") % {
@@ -53,7 +53,9 @@ def add_or_remove_timer(notif: Notification) -> bool:
53
53
  elif notif.notif_type == NotificationType.SOV_STRUCTURE_REINFORCED:
54
54
  timer_processed = _gen_timer_sov_reinforcements(notif)
55
55
  elif notif.notif_type == NotificationType.ORBITAL_REINFORCED:
56
- timer_processed = _gen_timer_orbital_reinforcements(notif)
56
+ timer_processed = _gen_timer_customs_office_reinforcements(notif)
57
+ elif notif.notif_type == NotificationType.SKYHOOK_LOST_SHIELDS:
58
+ timer_processed = _gen_timer_skyhook_reinforcements(notif)
57
59
  elif notif.notif_type in [
58
60
  NotificationType.MOONMINING_EXTRACTION_STARTED,
59
61
  NotificationType.MOONMINING_EXTRACTION_CANCELLED,
@@ -65,9 +67,7 @@ def add_or_remove_timer(notif: Notification) -> bool:
65
67
  elif notif.notif_type == NotificationType.TOWER_REINFORCED_EXTRA:
66
68
  timer_processed = _gen_timer_tower_reinforcements(notif)
67
69
  else:
68
- raise NotImplementedError(
69
- f"Unsupported notification type for timers: {notif.notif_type}"
70
- )
70
+ raise NotImplementedError(notif.notif_type)
71
71
  if timer_processed:
72
72
  logger.info("%s: Created timer for notification", notif.notification_id)
73
73
  notif.is_timer_added = True
@@ -181,8 +181,8 @@ def _gen_timer_sov_reinforcements(notif: Notification) -> bool:
181
181
  return timer_processed
182
182
 
183
183
 
184
- def _gen_timer_orbital_reinforcements(notif: Notification) -> bool:
185
- """Generate timer for orbital reinforcements."""
184
+ def _gen_timer_customs_office_reinforcements(notif: Notification) -> bool:
185
+ """Generate timer for customs office reinforcements."""
186
186
 
187
187
  solar_system = notif.eve_solar_system()
188
188
  planet = notif.eve_planet()
@@ -231,6 +231,53 @@ def _gen_timer_orbital_reinforcements(notif: Notification) -> bool:
231
231
  return timer_processed
232
232
 
233
233
 
234
+ def _gen_timer_skyhook_reinforcements(notif: Notification) -> bool:
235
+ """Generate timer for skyhook reinforcements."""
236
+
237
+ solar_system = notif.eve_solar_system("solarsystemID")
238
+ structure_type = notif.eve_structure_type("typeID")
239
+ planet = notif.eve_planet()
240
+ eve_time = ldap_time_2_datetime(notif.parsed_text()["timestamp"])
241
+ timer_processed = False
242
+
243
+ if AuthTimer:
244
+ AuthTimer.objects.create(
245
+ details=gettext("Final timer"),
246
+ system=solar_system.name,
247
+ planet_moon=planet.name,
248
+ structure="POCO", # Auth timer does not support the Skyhook type yet
249
+ objective="Friendly",
250
+ eve_time=eve_time,
251
+ eve_corp=notif.owner.corporation,
252
+ corp_timer=STRUCTURES_TIMERS_ARE_CORP_RESTRICTED,
253
+ )
254
+ timer_processed = True
255
+
256
+ if Timer:
257
+ visibility = (
258
+ Timer.Visibility.CORPORATION
259
+ if STRUCTURES_TIMERS_ARE_CORP_RESTRICTED
260
+ else Timer.Visibility.UNRESTRICTED
261
+ )
262
+ Timer.objects.create(
263
+ eve_solar_system=solar_system,
264
+ structure_type=structure_type,
265
+ timer_type=Timer.Type.FINAL,
266
+ objective=Timer.Objective.FRIENDLY,
267
+ date=eve_time,
268
+ location_details=planet.name,
269
+ eve_corporation=notif.owner.corporation,
270
+ eve_alliance=notif.owner.corporation.alliance,
271
+ visibility=visibility,
272
+ structure_name=structure_type.name,
273
+ owner_name=notif.owner.corporation.corporation_name,
274
+ details_notes=_timer_details_notes(notif),
275
+ )
276
+ timer_processed = True
277
+
278
+ return timer_processed
279
+
280
+
234
281
  def _gen_timer_moon_extraction(notif: Notification) -> bool:
235
282
  """Generate timer for moon mining extractions."""
236
283
  solar_system = notif.eve_solar_system()