aa-structures 2.9.1__py3-none-any.whl → 2.10.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.9.1
3
+ Version: 2.10.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,15 +1,15 @@
1
- structures/__init__.py,sha256=JDqVcTEi8eCaAdMSvOph_y7iv7PQbntaqVFeo0pFNS0,203
1
+ structures/__init__.py,sha256=uMpmaP4VBhwkpAgLo3BXo4Hx7Rw_4RLMyB7jScq_qO8,204
2
2
  structures/admin.py,sha256=cn6AtcSDI6bJROhBnvE2iQwOkm1t3NVabrpTVphxbTk,38662
3
3
  structures/app_settings.py,sha256=7BFWl1Q4tqTuj3CV6BmEctIFKJx9QIUfm2tjKzme2jM,6526
4
4
  structures/apps.py,sha256=MNZH9l3qWCwuS7OGiKGkBVrDzKoOFlqwDdEgyEFzxVA,195
5
- structures/auth_hooks.py,sha256=JI9dCNpYdRAPmD2fbiFqhc3ODxqvvyrgQQSmDyrZ3Fk,915
5
+ structures/auth_hooks.py,sha256=nRbrixFkAE5gphDokB1E8xhH8FY2VtXVwu0XMmSGBAw,1013
6
6
  structures/constants.py,sha256=R7sC5esaWJayJpTDbug7dTKxkkXDKXQ-U6M9Qb0GH5s,967
7
7
  structures/forms.py,sha256=kXs-SGIIj-D9xtFCILKe_PMRU4eHl3-HLNWRhaZKmnQ,391
8
8
  structures/helpers.py,sha256=_dw7j7yobpcV70VwWxoQiptk69b3ksvaDlRQKHg8Kmg,2344
9
9
  structures/managers.py,sha256=Th_nPY8GNcdBPqqfqjtTriYdsZWFAWknbNqI8QG17vo,19225
10
10
  structures/providers.py,sha256=9QYHd8X5HwBhrbgbX3LUrXXV1KGM3hFhcxK6qIJjJtg,317
11
11
  structures/tasks.py,sha256=INZ3soMYHYfxrQsyTO-ozoxbVX6lpMnF3AUo8ybWIoA,9083
12
- structures/urls.py,sha256=rBOv84nMX6WcZEnTZxASrSUhGaqubs4eRLyibDovrUs,1396
12
+ structures/urls.py,sha256=An5v27AD_NXMNL66cMVtQNci1C_Aqry32rrvDkMpgYo,1467
13
13
  structures/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  structures/core/notification_timers.py,sha256=G-QwpqP9HFv_Y7KsID9bLF-GluEJ1-duSJQN-zqJtM0,14977
15
15
  structures/core/notification_types.py,sha256=0SExh-VuImRz05jatnCu9lAfIFORUZ-kon9rjF4SXfI,12279
@@ -172,8 +172,8 @@ structures/tests/core/notification_embeds/__init__.py,sha256=47DEQpj8HBSa-_TImW-
172
172
  structures/tests/core/notification_embeds/test_helpers.py,sha256=HG20TC8Bz7NqpaQWo6uvrsxfNIwTL2Zi_NRkh3UyN2Y,1776
173
173
  structures/tests/core/notification_embeds/test_main.py,sha256=vTDByjxxVCA6KMcr5XH4f4QsMgcDI_YDd-fjZfHztng,13808
174
174
  structures/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
- structures/tests/integration/test_tasks.py,sha256=nb2HjS31ArQfoD2FIjQN-QHGGR4Xcqs9J1ICshmJVDA,23588
176
- structures/tests/integration/test_views.py,sha256=iA3chzZXhrnZzyBGmpRm-rQsKa6ru7y34fdB7CBtKDw,4331
175
+ structures/tests/integration/test_tasks.py,sha256=s6hL5UBotDmhLq7NUiOad72W-S_18u_yAHiLWVryVi8,23617
176
+ structures/tests/integration/test_views.py,sha256=SkbIposTUjo0nujHL4WEaZO7nY1Bfuvm805H39XUv-g,4361
177
177
  structures/tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
178
  structures/tests/models/test_eveuniverse.py,sha256=bQ1upOLfoivfaa9KCrzjWvSH_EvL2STuvfFfZ9saIMY,1623
179
179
  structures/tests/models/test_notifications_1.py,sha256=xVX4an54sZM8WLUdsAGUG2Nb4Rl7W5FBzhI0hBhJo5g,30300
@@ -201,14 +201,16 @@ structures/tests/testdata/tasks_loadtest.py,sha256=Hn0UVeaMfdi5S4W12lsb6g_xwjQcN
201
201
  structures/tests/testdata/test_generate_structures.py,sha256=vpReGRROduZsGB99Dq7yPKNKSkSLFdLM_esdf5TTnnI,414
202
202
  structures/tests/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
203
  structures/tests/views/test_public.py,sha256=FTaT3VUOnoT4t9rCCTCGyDrberpa8CRJHsXuqAw2PQE,1372
204
+ structures/tests/views/test_service_status.py,sha256=mWkP13HnKRa3ltsZ2FKJuZRJjvYic9wjgQ1J3qA8n-k,4197
204
205
  structures/tests/views/test_statistics.py,sha256=MHt31AIX9_jt8-yP8XsbsiRRUKEtY8mQJbk11saFYZc,2626
205
- structures/tests/views/test_structures.py,sha256=foTvuaI8x36wwTLiwsfAE1ofVPTJVrnXuBT39sWLBOs,29004
206
+ structures/tests/views/test_structures.py,sha256=dspLWOORWZyhgZRD8OtqZtG2kL4kN7JEFTI1v4l7I9U,25971
206
207
  structures/tests/views/utils.py,sha256=0ALPjL8d0vcIWa_Pl4_gDl1qtBp71oDqyZLJyvDj-Uc,247
207
208
  structures/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
208
209
  structures/views/common.py,sha256=Z_hcpEpkGrhwFdMAAMON_DqsfQ_lMyRwOMl5ROo_aSk,818
209
210
  structures/views/public.py,sha256=-Tel-poYKZTy8eQllhsWUxVf7HYBuCfeL9JWlbKhs7s,3035
210
211
  structures/views/statistics.py,sha256=7jj8b9ATsYwE7Cg6gMp-bYx29nV43GdWYun9WBggGkM,4709
211
- structures/views/structures.py,sha256=XtQxYySOPqO9klPgF1o57pCejuo22EdU00h5LAdEVME,23167
212
+ structures/views/status.py,sha256=gcahbk6dPIZDqkaNHDAsEHyDWLzicTK18Fom0A6xx3c,718
213
+ structures/views/structures.py,sha256=hw4Rjr6O_fK7dvdgtZGP9r3DExkfEwCPixeoEBK5KNU,22548
212
214
  structures/webhooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
213
215
  structures/webhooks/core.py,sha256=mP25MbQG8Yv2YayDFcR6x2V30eqXhR2q5u4SRefblf4,6573
214
216
  structures/webhooks/managers.py,sha256=L3G3AmsyDeif_lfpWshmAxQ61UGJ9w8i9lZaF2jbOtQ,1117
@@ -216,7 +218,7 @@ structures/webhooks/models.py,sha256=kUkt9rnRQIJIrU9Bjcs34rvkb-TMbUubHdn-kny08kI
216
218
  structures/webhooks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
219
  structures/webhooks/tests/test_core.py,sha256=4NcEAQgK2KhQkFOxYh2ad0S-qUWh1DNGDmLo5Mo5opI,6762
218
220
  structures/webhooks/tests/test_utils.py,sha256=ekADFv0JOEtXeqdiejbeqrABO__Q1flJHzVieQ7L9e0,459
219
- aa_structures-2.9.1.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
220
- aa_structures-2.9.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
221
- aa_structures-2.9.1.dist-info/METADATA,sha256=yvzawtDxsWgorHAKcQRjx1WJFOc8GbVlvPQcYcL8q50,5971
222
- aa_structures-2.9.1.dist-info/RECORD,,
221
+ aa_structures-2.10.0.dist-info/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
222
+ aa_structures-2.10.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
223
+ aa_structures-2.10.0.dist-info/METADATA,sha256=fc6JHf4tNiaFaCZmiZZRD71A0Q2BMEjAjuIQNHmwicI,5972
224
+ aa_structures-2.10.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.9.1"
6
+ __version__ = "2.10.0"
7
7
  __title__ = "Structures"
structures/auth_hooks.py CHANGED
@@ -32,4 +32,9 @@ def register_menu():
32
32
 
33
33
  @hooks.register("url_hook")
34
34
  def register_urls():
35
- return UrlHook(urls, "structures", r"^structures/")
35
+ return UrlHook(
36
+ urls,
37
+ "structures",
38
+ r"^structures/",
39
+ excluded_views=["structures.views.status.service_status"],
40
+ )
@@ -16,8 +16,7 @@ from app_utils.esi_testing import EsiClientStub, EsiEndpoint
16
16
  from structures import tasks
17
17
  from structures.core.notification_types import NotificationType
18
18
  from structures.models import Structure
19
-
20
- from ..testdata.factories import (
19
+ from structures.tests.testdata.factories import (
21
20
  EveEntityAllianceFactory,
22
21
  EveEntityCorporationFactory,
23
22
  NotificationFactory,
@@ -28,7 +27,7 @@ from ..testdata.factories import (
28
27
  WebhookFactory,
29
28
  datetime_to_esi,
30
29
  )
31
- from ..testdata.load_eveuniverse import load_eveuniverse
30
+ from structures.tests.testdata.load_eveuniverse import load_eveuniverse
32
31
 
33
32
  if "structuretimers" in app_labels():
34
33
  from structuretimers.models import Timer as StructureTimer
@@ -5,7 +5,7 @@ from django.urls import reverse
5
5
 
6
6
  from app_utils.testing import add_character_to_user
7
7
 
8
- from ..testdata.factories import (
8
+ from structures.tests.testdata.factories import (
9
9
  EveCharacterFactory,
10
10
  JumpGateFactory,
11
11
  OwnerFactory,
@@ -15,7 +15,7 @@ from ..testdata.factories import (
15
15
  UserMainBasicFactory,
16
16
  UserMainDefaultFactory,
17
17
  )
18
- from ..testdata.load_eveuniverse import load_eveuniverse
18
+ from structures.tests.testdata.load_eveuniverse import load_eveuniverse
19
19
 
20
20
  STRUCTURES_PATH = "structures.views.structures"
21
21
  PUBLIC_PATH = "structures.views.public"
@@ -0,0 +1,113 @@
1
+ import datetime as dt
2
+ from unittest.mock import patch
3
+
4
+ from django.test import TestCase
5
+ from django.urls import reverse
6
+ from django.utils.timezone import now
7
+
8
+ from app_utils.testing import response_text
9
+
10
+ from structures.tests.testdata.factories import OwnerFactory
11
+ from structures.views import status
12
+
13
+ OWNERS_PATH = "structures.models.owners"
14
+
15
+
16
+ @patch(OWNERS_PATH + ".STRUCTURES_STRUCTURE_SYNC_GRACE_MINUTES", 30)
17
+ @patch(OWNERS_PATH + ".STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES", 30)
18
+ class TestServiceStatus(TestCase):
19
+ def test_should_report_ok(self):
20
+ # given
21
+ OwnerFactory(
22
+ structures_last_update_at=now(),
23
+ notifications_last_update_at=now(),
24
+ forwarding_last_update_at=now(),
25
+ assets_last_update_at=now(),
26
+ )
27
+ request = self.client.get(reverse("structures:service_status"))
28
+ # when
29
+ response = status.service_status(request)
30
+ # then
31
+ self.assertEqual(response.status_code, 200)
32
+ self.assertEqual(response_text(response), "service is up")
33
+
34
+ def test_should_report_ok_when_downed_owner_is_inactive(self):
35
+ # given
36
+ OwnerFactory(
37
+ structures_last_update_at=now(),
38
+ notifications_last_update_at=now(),
39
+ forwarding_last_update_at=now(),
40
+ assets_last_update_at=now(),
41
+ )
42
+ OwnerFactory(
43
+ structures_last_update_at=now() - dt.timedelta(minutes=31),
44
+ notifications_last_update_at=now(),
45
+ forwarding_last_update_at=now(),
46
+ assets_last_update_at=now(),
47
+ is_active=False,
48
+ )
49
+ request = self.client.get(reverse("structures:service_status"))
50
+ # when
51
+ response = status.service_status(request)
52
+ # then
53
+ self.assertEqual(response.status_code, 200)
54
+
55
+ def test_should_report_fail_when_issue_with_structures(self):
56
+ # given
57
+ OwnerFactory(
58
+ structures_last_update_at=now() - dt.timedelta(minutes=31),
59
+ notifications_last_update_at=now(),
60
+ forwarding_last_update_at=now(),
61
+ assets_last_update_at=now(),
62
+ )
63
+ request = self.client.get(reverse("structures:service_status"))
64
+ # when
65
+ response = status.service_status(request)
66
+ # then
67
+ self.assertEqual(response.status_code, 500)
68
+ self.assertEqual(response_text(response), "service is down")
69
+
70
+ def test_should_report_fail_when_issue_with_notifications(self):
71
+ # given
72
+ OwnerFactory(
73
+ structures_last_update_at=now(),
74
+ notifications_last_update_at=now() - dt.timedelta(minutes=31),
75
+ forwarding_last_update_at=now(),
76
+ assets_last_update_at=now(),
77
+ )
78
+ request = self.client.get(reverse("structures:service_status"))
79
+ # when
80
+ response = status.service_status(request)
81
+ # then
82
+ self.assertEqual(response.status_code, 500)
83
+ self.assertEqual(response_text(response), "service is down")
84
+
85
+ def test_should_report_fail_when_issue_with_forwarding(self):
86
+ # given
87
+ OwnerFactory(
88
+ structures_last_update_at=now(),
89
+ notifications_last_update_at=now(),
90
+ forwarding_last_update_at=now() - dt.timedelta(minutes=31),
91
+ assets_last_update_at=now(),
92
+ )
93
+ request = self.client.get(reverse("structures:service_status"))
94
+ # when
95
+ response = status.service_status(request)
96
+ # then
97
+ self.assertEqual(response.status_code, 500)
98
+ self.assertEqual(response_text(response), "service is down")
99
+
100
+ def test_should_report_fail_when_issue_with_assets(self):
101
+ # given
102
+ OwnerFactory(
103
+ structures_last_update_at=now(),
104
+ notifications_last_update_at=now(),
105
+ forwarding_last_update_at=now(),
106
+ assets_last_update_at=now() - dt.timedelta(minutes=31),
107
+ )
108
+ request = self.client.get(reverse("structures:service_status"))
109
+ # when
110
+ response = status.service_status(request)
111
+ # then
112
+ self.assertEqual(response.status_code, 500)
113
+ self.assertEqual(response_text(response), "service is down")
@@ -11,6 +11,7 @@ from django.utils.timezone import now
11
11
  from app_utils.testdata_factories import UserMainFactory
12
12
  from app_utils.testing import json_response_to_python
13
13
 
14
+ import structures.views.status
14
15
  from structures.models import Owner, Structure
15
16
  from structures.views import structures
16
17
 
@@ -656,88 +657,6 @@ class TestAddStructureOwner(TestCase):
656
657
  self.assertTrue(owner.is_active)
657
658
 
658
659
 
659
- class TestStatus(TestCase):
660
- @classmethod
661
- def setUpClass(cls):
662
- super().setUpClass()
663
- cls.factory = RequestFactory()
664
- # Owner.objects.filter(is_included_in_service_status=True)
665
-
666
- def test_view_service_status_ok(self):
667
- # given
668
- OwnerFactory(
669
- structures_last_update_at=now(),
670
- notifications_last_update_at=now(),
671
- forwarding_last_update_at=now(),
672
- assets_last_update_at=now(),
673
- )
674
- request = self.factory.get(reverse("structures:service_status"))
675
- # when
676
- response = structures.service_status(request)
677
- # then
678
- self.assertEqual(response.status_code, 200)
679
-
680
- @patch(OWNERS_PATH + ".STRUCTURES_STRUCTURE_SYNC_GRACE_MINUTES", 30)
681
- def test_view_service_status_fail_structures(self):
682
- # given
683
- OwnerFactory(
684
- structures_last_update_at=now() - dt.timedelta(minutes=31),
685
- notifications_last_update_at=now(),
686
- forwarding_last_update_at=now(),
687
- assets_last_update_at=now(),
688
- )
689
- request = self.factory.get(reverse("structures:service_status"))
690
- # when
691
- response = structures.service_status(request)
692
- # then
693
- self.assertEqual(response.status_code, 500)
694
-
695
- @patch(OWNERS_PATH + ".STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES", 30)
696
- def test_view_service_status_fail_notifications(self):
697
- # given
698
- OwnerFactory(
699
- structures_last_update_at=now(),
700
- notifications_last_update_at=now() - dt.timedelta(minutes=31),
701
- forwarding_last_update_at=now(),
702
- assets_last_update_at=now(),
703
- )
704
- request = self.factory.get(reverse("structures:service_status"))
705
- # when
706
- response = structures.service_status(request)
707
- # then
708
- self.assertEqual(response.status_code, 500)
709
-
710
- @patch(OWNERS_PATH + ".STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES", 30)
711
- def test_view_service_status_fail_forwarding(self):
712
- # given
713
- OwnerFactory(
714
- structures_last_update_at=now(),
715
- notifications_last_update_at=now(),
716
- forwarding_last_update_at=now() - dt.timedelta(minutes=31),
717
- assets_last_update_at=now(),
718
- )
719
- request = self.factory.get(reverse("structures:service_status"))
720
- # when
721
- response = structures.service_status(request)
722
- # then
723
- self.assertEqual(response.status_code, 500)
724
-
725
- @patch(OWNERS_PATH + ".STRUCTURES_STRUCTURE_SYNC_GRACE_MINUTES", 30)
726
- def test_view_service_status_fail_assets(self):
727
- # given
728
- OwnerFactory(
729
- structures_last_update_at=now(),
730
- notifications_last_update_at=now(),
731
- forwarding_last_update_at=now(),
732
- assets_last_update_at=now() - dt.timedelta(minutes=31),
733
- )
734
- request = self.factory.get(reverse("structures:service_status"))
735
- # when
736
- response = structures.service_status(request)
737
- # then
738
- self.assertEqual(response.status_code, 500)
739
-
740
-
741
660
  class TestStructureFittingModal(TestCase):
742
661
  @classmethod
743
662
  def setUpClass(cls):
structures/urls.py CHANGED
@@ -1,8 +1,9 @@
1
1
  """Tasks for Structures."""
2
2
 
3
3
  from django.urls import path
4
+ from django.views.decorators.cache import never_cache
4
5
 
5
- from .views import public, statistics, structures
6
+ from .views import public, statistics, status, structures
6
7
 
7
8
  app_name = "structures"
8
9
 
@@ -19,7 +20,7 @@ urlpatterns = [
19
20
  structures.add_structure_owner,
20
21
  name="add_structure_owner",
21
22
  ),
22
- path("service_status", structures.service_status, name="service_status"),
23
+ path("service_status", never_cache(status.service_status), name="service_status"),
23
24
  path(
24
25
  "<int:structure_id>/structure_details",
25
26
  structures.structure_details,
@@ -0,0 +1,22 @@
1
+ """Status views."""
2
+
3
+ from django.http import HttpRequest, HttpResponse, HttpResponseServerError
4
+
5
+ from structures.models import Owner
6
+
7
+
8
+ def service_status(request: HttpRequest):
9
+ """Public view to 3rd party monitoring.
10
+
11
+ This is view allows running a 3rd party monitoring on the status
12
+ of this services. Service will be reported as down if any of the
13
+ configured structure or notifications syncs fails or is delayed
14
+ """
15
+ active_owners = Owner.objects.filter(
16
+ is_included_in_service_status=True, is_active=True
17
+ )
18
+ for owner in active_owners:
19
+ if not owner.are_all_syncs_ok:
20
+ return HttpResponseServerError("service is down")
21
+
22
+ return HttpResponse("service is up")
@@ -10,7 +10,7 @@ from django.contrib import messages
10
10
  from django.contrib.auth.decorators import login_required, permission_required
11
11
  from django.contrib.auth.models import User
12
12
  from django.db.models import Prefetch
13
- from django.http import HttpRequest, HttpResponse, HttpResponseServerError, JsonResponse
13
+ from django.http import HttpRequest, JsonResponse
14
14
  from django.shortcuts import get_object_or_404, redirect, render
15
15
  from django.templatetags.static import static
16
16
  from django.urls import reverse
@@ -651,19 +651,3 @@ def add_structure_owner(request: HttpRequest, token: Token):
651
651
  title=_("%s: Character added to: %s") % (__title__, owner),
652
652
  )
653
653
  return redirect("structures:index")
654
-
655
-
656
- def service_status(request: HttpRequest):
657
- """Public view to 3rd party monitoring.
658
-
659
- This is view allows running a 3rd party monitoring on the status
660
- of this services. Service will be reported as down if any of the
661
- configured structure or notifications syncs fails or is delayed
662
- """
663
- status_ok = True
664
- for owner in Owner.objects.filter(is_included_in_service_status=True):
665
- status_ok = status_ok and owner.are_all_syncs_ok
666
-
667
- if status_ok:
668
- return HttpResponse(_("service is up"))
669
- return HttpResponseServerError(_("service is down"))