irie 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of irie might be problematic. Click here for more details.

Files changed (145) hide show
  1. irie/__main__.py +24 -0
  2. irie/apps/__init__.py +5 -0
  3. irie/apps/authentication/__init__.py +1 -0
  4. irie/apps/authentication/admin.py +1 -0
  5. irie/apps/authentication/config.py +6 -0
  6. irie/apps/authentication/forms.py +41 -0
  7. irie/apps/authentication/migrations/__init__.py +1 -0
  8. irie/apps/authentication/models.py +1 -0
  9. irie/apps/authentication/tests.py +1 -0
  10. irie/apps/authentication/urls.py +9 -0
  11. irie/apps/authentication/views.py +53 -0
  12. irie/apps/config.py +8 -0
  13. irie/apps/context_processors.py +5 -0
  14. irie/apps/documents/__init__.py +0 -0
  15. irie/apps/documents/apps.py +7 -0
  16. irie/apps/documents/documents.py +61 -0
  17. irie/apps/documents/migrations/__init__.py +0 -0
  18. irie/apps/documents/tests.py +3 -0
  19. irie/apps/documents/urls.py +12 -0
  20. irie/apps/documents/views.py +27 -0
  21. irie/apps/evaluation/__init__.py +0 -0
  22. irie/apps/evaluation/admin.py +43 -0
  23. irie/apps/evaluation/apps.py +18 -0
  24. irie/apps/evaluation/daemon.py +107 -0
  25. irie/apps/evaluation/identification.py +196 -0
  26. irie/apps/evaluation/migrations/0001_initial.py +25 -0
  27. irie/apps/evaluation/migrations/0002_remove_evaluation_cesmd.py +17 -0
  28. irie/apps/evaluation/migrations/0003_evaluation_asset.py +20 -0
  29. irie/apps/evaluation/migrations/__init__.py +0 -0
  30. irie/apps/evaluation/models.py +72 -0
  31. irie/apps/evaluation/urls.py +16 -0
  32. irie/apps/evaluation/views.py +68 -0
  33. irie/apps/events/__init__.py +0 -0
  34. irie/apps/events/admin.py +9 -0
  35. irie/apps/events/apps.py +12 -0
  36. irie/apps/events/migrations/0001_initial.py +27 -0
  37. irie/apps/events/migrations/0002_alter_event_id.py +18 -0
  38. irie/apps/events/migrations/0003_event_cesmd.py +19 -0
  39. irie/apps/events/migrations/0004_event_record_identifier.py +19 -0
  40. irie/apps/events/migrations/0005_event_asset.py +21 -0
  41. irie/apps/events/migrations/0006_alter_event_event_file.py +18 -0
  42. irie/apps/events/migrations/__init__.py +0 -0
  43. irie/apps/events/models.py +70 -0
  44. irie/apps/events/tests.py +1 -0
  45. irie/apps/events/tests_events.py +240 -0
  46. irie/apps/events/urls.py +29 -0
  47. irie/apps/events/views.py +55 -0
  48. irie/apps/events/views_events.py +215 -0
  49. irie/apps/inventory/CESMD.py +81 -0
  50. irie/apps/inventory/__init__.py +5 -0
  51. irie/apps/inventory/admin.py +10 -0
  52. irie/apps/inventory/apps.py +12 -0
  53. irie/apps/inventory/archive/arcGIS.py +1175 -0
  54. irie/apps/inventory/calid.py +65 -0
  55. irie/apps/inventory/fields.py +5 -0
  56. irie/apps/inventory/forms.py +12 -0
  57. irie/apps/inventory/migrations/0001_initial.py +31 -0
  58. irie/apps/inventory/migrations/0002_assetevaluationmodel_cesmd.py +19 -0
  59. irie/apps/inventory/migrations/0003_auto_20230520_2030.py +23 -0
  60. irie/apps/inventory/migrations/0004_asset.py +27 -0
  61. irie/apps/inventory/migrations/0005_auto_20230731_1802.py +23 -0
  62. irie/apps/inventory/migrations/0006_auto_20230731_1816.py +28 -0
  63. irie/apps/inventory/migrations/0007_auto_20230731_1827.py +24 -0
  64. irie/apps/inventory/migrations/0008_asset_is_complete.py +19 -0
  65. irie/apps/inventory/migrations/0009_auto_20230731_1842.py +29 -0
  66. irie/apps/inventory/migrations/0010_auto_20230801_0025.py +23 -0
  67. irie/apps/inventory/migrations/0011_alter_asset_cgs_data.py +18 -0
  68. irie/apps/inventory/migrations/0012_corridor.py +22 -0
  69. irie/apps/inventory/migrations/0013_alter_asset_cesmd.py +18 -0
  70. irie/apps/inventory/migrations/0014_alter_asset_cesmd.py +18 -0
  71. irie/apps/inventory/migrations/__init__.py +0 -0
  72. irie/apps/inventory/models.py +70 -0
  73. irie/apps/inventory/tables.py +584 -0
  74. irie/apps/inventory/traffic.py +175052 -0
  75. irie/apps/inventory/urls.py +25 -0
  76. irie/apps/inventory/views.py +515 -0
  77. irie/apps/management/__init__.py +0 -0
  78. irie/apps/management/commands/__init__.py +0 -0
  79. irie/apps/networks/__init__.py +0 -0
  80. irie/apps/networks/apps.py +5 -0
  81. irie/apps/networks/forms.py +64 -0
  82. irie/apps/networks/migrations/0001_initial.py +26 -0
  83. irie/apps/networks/migrations/__init__.py +0 -0
  84. irie/apps/networks/models.py +14 -0
  85. irie/apps/networks/networks.py +782 -0
  86. irie/apps/networks/tests.py +1 -0
  87. irie/apps/networks/urls.py +18 -0
  88. irie/apps/networks/views.py +89 -0
  89. irie/apps/prediction/__init__.py +0 -0
  90. irie/apps/prediction/admin.py +9 -0
  91. irie/apps/prediction/apps.py +12 -0
  92. irie/apps/prediction/forms.py +20 -0
  93. irie/apps/prediction/metrics.py +61 -0
  94. irie/apps/prediction/migrations/0001_initial.py +32 -0
  95. irie/apps/prediction/migrations/0002_auto_20230731_1801.py +27 -0
  96. irie/apps/prediction/migrations/0003_rename_assetevaluationmodel_evaluation.py +18 -0
  97. irie/apps/prediction/migrations/0004_delete_evaluation.py +16 -0
  98. irie/apps/prediction/migrations/0005_predictormodel_protocol.py +18 -0
  99. irie/apps/prediction/migrations/0006_alter_predictormodel_protocol.py +18 -0
  100. irie/apps/prediction/migrations/0007_predictormodel_active.py +19 -0
  101. irie/apps/prediction/migrations/0008_predictormodel_description.py +18 -0
  102. irie/apps/prediction/migrations/0009_predictormodel_entry_point.py +19 -0
  103. irie/apps/prediction/migrations/0010_alter_predictormodel_entry_point.py +18 -0
  104. irie/apps/prediction/migrations/0011_remove_predictormodel_entry_point.py +17 -0
  105. irie/apps/prediction/migrations/0012_predictormodel_entry_point.py +18 -0
  106. irie/apps/prediction/migrations/0013_predictormodel_metrics.py +18 -0
  107. irie/apps/prediction/migrations/0014_auto_20240930_0004.py +28 -0
  108. irie/apps/prediction/migrations/0015_alter_predictormodel_render_file.py +18 -0
  109. irie/apps/prediction/migrations/__init__.py +0 -0
  110. irie/apps/prediction/models.py +37 -0
  111. irie/apps/prediction/predictor.py +286 -0
  112. irie/apps/prediction/runners/__init__.py +450 -0
  113. irie/apps/prediction/runners/metrics.py +168 -0
  114. irie/apps/prediction/runners/opensees/__init__.py +0 -0
  115. irie/apps/prediction/runners/opensees/schemas/__init__.py +39 -0
  116. irie/apps/prediction/runners/utilities.py +277 -0
  117. irie/apps/prediction/runners/xmlutils.py +232 -0
  118. irie/apps/prediction/runners/zipped.py +27 -0
  119. irie/apps/prediction/templatetags/__init__.py +0 -0
  120. irie/apps/prediction/templatetags/predictor.py +20 -0
  121. irie/apps/prediction/urls.py +19 -0
  122. irie/apps/prediction/views.py +184 -0
  123. irie/apps/prediction/views_api.py +216 -0
  124. irie/apps/site/__init__.py +0 -0
  125. irie/apps/site/admin.py +1 -0
  126. irie/apps/site/config.py +6 -0
  127. irie/apps/site/migrations/__init__.py +1 -0
  128. irie/apps/site/models.py +2 -0
  129. irie/apps/site/templatetags/__init__.py +0 -0
  130. irie/apps/site/templatetags/indexing.py +7 -0
  131. irie/apps/site/tests.py +1 -0
  132. irie/apps/site/urls.py +8 -0
  133. irie/apps/site/view_sdof.py +40 -0
  134. irie/apps/site/view_utils.py +13 -0
  135. irie/apps/site/views.py +88 -0
  136. irie/core/__init__.py +5 -0
  137. irie/core/asgi.py +12 -0
  138. irie/core/settings.py +223 -0
  139. irie/core/urls.py +39 -0
  140. irie/core/wsgi.py +12 -0
  141. irie-0.0.0.dist-info/METADATA +48 -0
  142. irie-0.0.0.dist-info/RECORD +145 -0
  143. irie-0.0.0.dist-info/WHEEL +5 -0
  144. irie-0.0.0.dist-info/entry_points.txt +2 -0
  145. irie-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,240 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
6
+ #
7
+ # Author: Claudio Perez
8
+ #
9
+ #----------------------------------------------------------------------------#
10
+ from django.test import TestCase
11
+ from django.contrib.auth.models import User
12
+ import json
13
+
14
+ test_user = {"username": "testuser", "password": "testpassword"}
15
+ event_file = "../tests/58658_007_20210426_10.09.54.P.zip"
16
+
17
+ class QuakeEventTest(TestCase):
18
+ def setUp(self):
19
+ new_user = User.objects.create(username=test_user["username"])
20
+ new_user.set_password(test_user["password"])
21
+ new_user.save()
22
+
23
+ def get_token(self):
24
+ res = self.client.post(
25
+ "/api/token/",
26
+ data=json.dumps(
27
+ {
28
+ "username": test_user["username"],
29
+ "password": test_user["password"],
30
+ }
31
+ ),
32
+ content_type="application/json",
33
+ )
34
+ result = json.loads(res.content)
35
+ self.assertTrue("access" in result)
36
+ return result["access"]
37
+
38
+ def test_add_events_forbidden(self):
39
+ with open(event_file, "rb") as fp:
40
+ res = self.client.post(
41
+ "/api/events/",
42
+ {
43
+ "upload_data": {"name": "name"},
44
+ "event_file": fp,
45
+ },
46
+ #content_type="multipart/form-data",
47
+ )
48
+ self.assertEquals(res.status_code, 401)
49
+ res = self.client.post(
50
+ "/api/events/",
51
+ {
52
+ "upload_data": {"name": "2"},
53
+ "event_file": open(event_file,"rb")
54
+ },
55
+ #content_type="multipart/form-data",
56
+ HTTP_AUTHORIZATION=f"Bearer WRONG TOKEN",
57
+ )
58
+ self.assertEquals(res.status_code, 401)
59
+
60
+ def test_add_events_ok(self):
61
+ token = self.get_token()
62
+ with open(event_file,"rb") as fp:
63
+ res = self.client.post(
64
+ "/api/events/",
65
+ {
66
+ "upload_data": '{"name": "2"}',
67
+ "event_file": fp
68
+ },
69
+ #content_type="multipart/form-data",
70
+ HTTP_AUTHORIZATION=f"Bearer {token}",
71
+ )
72
+ self.assertEquals(res.status_code, 201)
73
+ print("res.content: ",res.content)
74
+ result = json.loads(res.content)["data"]
75
+ self.assertEquals(result["upload_data"]["name"], "2")
76
+
77
+ def test_add_events_wrong_data(self):
78
+ token = self.get_token()
79
+ res = self.client.post(
80
+ "/api/events/",
81
+ data=json.dumps(
82
+ {
83
+ "upload_data": '{"name": "2020-01-01"}',
84
+ "item": "Hard Drive",
85
+ "price": -1,
86
+ "quantity": 10,
87
+ }
88
+ ),
89
+ content_type="multipart/form-data",
90
+ HTTP_AUTHORIZATION=f"Bearer {token}",
91
+ )
92
+ self.assertEquals(res.status_code, 400)
93
+
94
+ res = self.client.post(
95
+ "/api/events/",
96
+ data=json.dumps(
97
+ {
98
+ "upload_data": '{"name": "2020-01-01"}',
99
+ "item": "Hard Drive",
100
+ "price": 1,
101
+ "quantity": -10,
102
+ }
103
+ ),
104
+ content_type="application/json",
105
+ HTTP_AUTHORIZATION=f"Bearer {token}",
106
+ )
107
+ self.assertEquals(res.status_code, 400)
108
+
109
+ res = self.client.post(
110
+ "/api/events/",
111
+ data=json.dumps(
112
+ {
113
+ "upload_data": '{"date": "2020-01-01"}',
114
+ "item": "",
115
+ "price": 1,
116
+ "quantity": 10,
117
+ }
118
+ ),
119
+ content_type="application/json",
120
+ HTTP_AUTHORIZATION=f"Bearer {token}",
121
+ )
122
+ self.assertEquals(res.status_code, 400)
123
+
124
+ def test_add_events_calculate(self):
125
+ token = self.get_token()
126
+ res = self.client.post(
127
+ "/api/events/",
128
+ {
129
+ "upload_data": '{"name": "2020-01-01"}',
130
+ },
131
+ content_type="application/json",
132
+ HTTP_AUTHORIZATION=f"Bearer {token}",
133
+ )
134
+ self.assertEquals(res.status_code, 201)
135
+ result = json.loads(res.content)["data"]
136
+ self.assertEquals(result["amount"], 35) # should be calculated
137
+
138
+ # -------------------------- GET RECORDS -------------------------------------------
139
+
140
+ def test_get_records(self):
141
+ token = self.get_token()
142
+ with open(event_file, "rb") as fp:
143
+ res = self.client.post(
144
+ "/api/events/",
145
+ {"upload_data": '{"name":"1"}', "event_file": fp},
146
+ #content_type="multipart/form-data",
147
+ HTTP_AUTHORIZATION=f"Bearer {token}",
148
+ )
149
+ self.assertEquals(res.status_code, 201)
150
+ id1 = json.loads(res.content)["data"]["id"]
151
+
152
+ with open(event_file, "rb") as fp:
153
+ res = self.client.post(
154
+ "/api/events/",
155
+ {"upload_data": '{"name":"2"}', "event_file": fp},
156
+ #content_type="multipart/form-data",
157
+ HTTP_AUTHORIZATION=f"Bearer {token}",
158
+ )
159
+ self.assertEquals(res.status_code, 201)
160
+ id2 = json.loads(res.content)["data"]["id"]
161
+
162
+
163
+ # Perform GET requests
164
+ res = self.client.get(
165
+ "/api/events/",
166
+ content_type="application/json",
167
+ HTTP_AUTHORIZATION=f"Bearer {token}",
168
+ )
169
+
170
+ self.assertEquals(res.status_code, 200)
171
+ result = json.loads(res.content)["data"]
172
+ self.assertEquals(len(result), 2) # 2 records
173
+ self.assertTrue(result[0]["id"] == id1 or result[1]["id"] == id1)
174
+ self.assertTrue(result[0]["id"] == id2 or result[1]["id"] == id2)
175
+
176
+ res = self.client.get(
177
+ f"/api/events/{id1}/",
178
+ content_type="application/json",
179
+ HTTP_AUTHORIZATION=f"Bearer {token}",
180
+ )
181
+ self.assertEquals(res.status_code, 200)
182
+ result = json.loads(res.content)["data"]
183
+ self.assertEquals(result["upload_data"]["name"], "1")
184
+
185
+
186
+ # -------------------------- PUT AND DELETE RECORDS --------------------------------------
187
+
188
+ def test_put_delete_records(self):
189
+ token = self.get_token()
190
+ with open(event_file, "rb") as fp:
191
+ res = self.client.post(
192
+ "/api/events/",
193
+ {
194
+ "upload_data": '{"name":"test_put_delete_records"}',
195
+ "event_file": fp
196
+ },
197
+ #content_type="multipart/form-data",
198
+ HTTP_AUTHORIZATION=f"Bearer {token}",
199
+ )
200
+ self.assertEquals(res.status_code, 201)
201
+ id = json.loads(res.content)["data"]["id"]
202
+
203
+ with open(event_file, "rb") as fp:
204
+ res = self.client.put(
205
+ f"/api/events/{id}/",
206
+ {"name": "new_name", "event_file": fp},
207
+ #content_type="multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
208
+ content_type="multipart/form-data",
209
+ HTTP_AUTHORIZATION=f"Bearer {token}",
210
+ )
211
+
212
+ print(res.content)
213
+ self.assertEquals(res.status_code, 200)
214
+ result = json.loads(res.content)["data"]
215
+ self.assertEquals(result["upload_data"]["name"], "new_name")
216
+
217
+ res = self.client.get(
218
+ f"/api/events/{id}/",
219
+ content_type="application/json",
220
+ HTTP_AUTHORIZATION=f"Bearer {token}",
221
+ )
222
+ self.assertEquals(res.status_code, 200)
223
+ result = json.loads(res.content)["data"]
224
+ self.assertEquals(result["upload_data"]["name"], "new_name")
225
+
226
+
227
+ res = self.client.delete(
228
+ f"/api/events/{id}/",
229
+ content_type="application/json",
230
+ HTTP_AUTHORIZATION=f"Bearer {token}",
231
+ )
232
+ self.assertEquals(res.status_code, 410) # Gone
233
+
234
+ res = self.client.get(
235
+ f"/api/events/{id}/",
236
+ content_type="application/json",
237
+ HTTP_AUTHORIZATION=f"Bearer {token}",
238
+ )
239
+ self.assertEquals(res.status_code, 404) # Not found
240
+
@@ -0,0 +1,29 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
6
+ #
7
+ # Author: Claudio Perez
8
+ #
9
+ #----------------------------------------------------------------------------#
10
+ import rest_framework_simplejwt.views as jwt_views
11
+
12
+ from django.urls import path
13
+ from django.conf.urls.static import static
14
+
15
+ from . import views_events, views
16
+
17
+
18
+ urlpatterns = [
19
+ path("event-table/", views.event_table, name="event_table"),
20
+ path("event-table.html", views.event_table),
21
+
22
+ path("events/", views_events.index),
23
+ path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
24
+ path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
25
+ path('api/events/', views_events.events),
26
+ path('api/events/<int:event_id>/', views_events.event),
27
+ ]
28
+ #+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
29
+
@@ -0,0 +1,55 @@
1
+
2
+ import os
3
+ from django.template import loader
4
+ from django.core.paginator import Paginator
5
+ from django.http import HttpResponse
6
+ from django.contrib.auth.decorators import login_required
7
+
8
+ from apps.events.models import Event
9
+ from apps.site.view_utils import raise404
10
+
11
+
12
+ @login_required(login_url="/login/")
13
+ def event_table(request):
14
+ """
15
+ This view generates the event table page. It uses the event-table.html
16
+ """
17
+ context = {}
18
+ page_template = "event-table.html"
19
+ context["segment"] = "event-table.html"
20
+
21
+ page = request.GET.get("page", 1)
22
+ try:
23
+ page = int(page)
24
+ except:
25
+ page = 1
26
+
27
+ asset = request.GET.get("asset", None)
28
+
29
+ if asset is not None:
30
+ events = [i for i in reversed(sorted(Event.objects.filter(asset=asset),
31
+ key=lambda x: x.motion_data["event_date"]))]
32
+ else:
33
+ events = [i for i in reversed(sorted(Event.objects.all(),
34
+ key=lambda x: x.motion_data["event_date"]))]
35
+
36
+ # Paginator for 10 items per page
37
+ paginator = Paginator(events, 15)
38
+
39
+
40
+ # reversed(sorted(Event.objects.all(),
41
+ # key=lambda x: x.motion_data["event_date"]))
42
+ context["events"] = paginator.get_page(page)
43
+
44
+
45
+ html_template = loader.get_template("events/" + page_template)
46
+
47
+ try:
48
+ return HttpResponse(html_template.render(context, request))
49
+
50
+ except Exception as e:
51
+ if "DEBUG" in os.environ and os.environ["DEBUG"]:
52
+ raise e
53
+ html_template = loader.get_template("site/page-500.html")
54
+ return HttpResponse(html_template.render(context, request))
55
+
@@ -0,0 +1,215 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
6
+ import json
7
+ import datetime
8
+ from threading import Thread
9
+ from django.shortcuts import render
10
+ from django.core.exceptions import ObjectDoesNotExist
11
+ from django.shortcuts import HttpResponse
12
+ from django.forms.models import model_to_dict
13
+
14
+ from rest_framework.parsers import JSONParser, MultiPartParser
15
+ from rest_framework.decorators import api_view, permission_classes, parser_classes
16
+ from rest_framework import status
17
+ from rest_framework.permissions import IsAuthenticated
18
+
19
+ from .models import Event
20
+ from apps.inventory.models import Asset
21
+ # from apps.evaluation.evaluation import (run_evaluation,
22
+ # add_evaluation)
23
+ from apps.evaluation.models import Evaluation
24
+ import quakeio
25
+
26
+
27
+ def serialize_event(event):
28
+ serialized = model_to_dict(event)
29
+ serialized["upload_date"] = str(event.upload_date)
30
+
31
+ if event.event_file:
32
+ serialized["event_file"] = event.event_file.path
33
+ else:
34
+ serialized["event_file"] = None
35
+
36
+ #serialized["data_str"] = json.loads(event.data_str) if event.data_str else {}
37
+ return serialized
38
+
39
+
40
+ def save_event(request, event, success_status):
41
+ errors = []
42
+
43
+ # DATE
44
+ upload_date = datetime.datetime.now()
45
+
46
+ # UPLOAD DATA
47
+ upload_data = request.data.get("upload_data", "{}")
48
+ if upload_data == "":
49
+ errors.append({"upload_data": "This field is required"})
50
+
51
+ # EVENT FILE
52
+ try:
53
+ event_file = request.FILES["event_file"]
54
+ except KeyError:
55
+ event_file = None
56
+ # errors.append({"event_file": "This field is required"})
57
+ except Exception as e:
58
+ errors.append({"event_file": str(e)})
59
+
60
+
61
+ if len(errors) > 0:
62
+ return HttpResponse(json.dumps(
63
+ {
64
+ "errors": errors
65
+ }), status=status.HTTP_400_BAD_REQUEST)
66
+
67
+ # MOTION DATA
68
+ if event_file is not None:
69
+ try:
70
+ motion_data = (
71
+ quakeio.read(
72
+ event_file.temporary_file_path(), input_format="csmip.zip"
73
+ ).serialize(serialize_data=False, summarize=True)
74
+ )
75
+ except:
76
+ return HttpResponse(json.dumps(
77
+ {
78
+ "errors": ["Failed to parse ground motion file."]
79
+ }), status=status.HTTP_400_BAD_REQUEST)
80
+ elif "motion_data" in request.data:
81
+ motion_data = json.loads(request.data.get("motion_data"))
82
+
83
+ else:
84
+ return HttpResponse(json.dumps(
85
+ {
86
+ "errors": ["No motion_data provided."]
87
+ }), status=status.HTTP_400_BAD_REQUEST)
88
+
89
+ # RECORD ID
90
+ rec_id = motion_data.get("record_identifier", "")
91
+
92
+
93
+ # CREATE EVENT
94
+ if event is None:
95
+ # Doing a PUT
96
+ event = Event.objects.filter(record_identifier=rec_id).first()
97
+ if event is None:
98
+ print("PUT: creating", rec_id, "\n\n")
99
+ event = Event()
100
+ else:
101
+ print("PUT: updating", rec_id, "\n\n")
102
+ upload_date = event.upload_date
103
+
104
+
105
+ event.upload_date = upload_date
106
+ event.upload_data = json.loads(upload_data)
107
+ event.record_identifier = rec_id
108
+ event.motion_data = motion_data
109
+ event.cesmd = "CE" + event.motion_data["station_number"]
110
+ try:
111
+ event.asset = Asset.objects.get(cesmd="CE" + event.motion_data["station_number"])
112
+ except:
113
+ return HttpResponse('{"errors": ["No asset with station CE'
114
+ +str(event.motion_data["station_number"])
115
+ + 'from file '
116
+ + str(event_file.temporary_file_path())
117
+ + '"]}',
118
+ status=status.HTTP_400_BAD_REQUEST)
119
+ event.event_file = event_file
120
+ # if event_file is not None:
121
+
122
+ event.save()
123
+
124
+
125
+ # CREATE EVALUATION
126
+ if "evaluation" in request.data:
127
+ # TODO: check for parse error
128
+ eval_data = json.loads(request.data["evaluation"])
129
+ else:
130
+ eval_data = None
131
+
132
+
133
+ Evaluation.create(event, event.asset, eval_data)
134
+
135
+
136
+ # EMAIL
137
+ # Get users
138
+ from django.contrib.auth import get_user_model
139
+ User = get_user_model()
140
+ users = User.objects.all()
141
+
142
+ station_name = event.motion_data["station_name"]
143
+
144
+ event.email_notify(
145
+ subject = f"BRACE2: New event at '{station_name}'",
146
+
147
+ message = ("A new event has been sent to the BRACE2 platform. "
148
+ 'visit https://brace2-peer.ist.berkeley.edu/static/dmp/index.html for details.'),
149
+ html_message = ("A new event has been sent to the BRACE2 platform. "
150
+ 'visit <a href="https://brace2-peer.ist.berkeley.edu/static/dmp/index.html">here</a> for details.'),
151
+ fail_silently=True,
152
+ recipients=[user.email for user in users] + ["brace2-peer@mailinator.com"]
153
+ )
154
+
155
+ return HttpResponse(json.dumps({"data": serialize_event(event)}), status=success_status)
156
+
157
+
158
+
159
+ def index(request):
160
+ context = {}
161
+ return render(request, "events/events.html", context=context)
162
+
163
+
164
+ @api_view(["GET", "POST", "PUT"])
165
+ @permission_classes([IsAuthenticated])
166
+ def events(request):
167
+ # if request.user.is_anonymous:
168
+ # return HttpResponse(json.dumps({"detail": "Not authorized"}), status=status.HTTP_401_UNAUTHORIZED)
169
+
170
+ if request.method == "GET":
171
+ events_data = Event.objects.all()
172
+
173
+ events_count = events_data.count()
174
+
175
+ page_size = int(request.GET.get("page_size", events_count))
176
+ page_no = int(request.GET.get("page_no", 0))
177
+ events_data = list(events_data[page_no * page_size:page_no * page_size + page_size])
178
+
179
+ events_data = [serialize_event(event) for event in events_data]
180
+ return HttpResponse(json.dumps({"count": events_count, "data": events_data}), status=status.HTTP_200_OK)
181
+
182
+ elif request.method == "POST":
183
+ event = Event()
184
+ return save_event(request, event, status.HTTP_201_CREATED)
185
+
186
+ elif request.method == "PUT":
187
+ return save_event(request, None, status.HTTP_201_CREATED)
188
+
189
+ return HttpResponse(json.dumps({"detail": "Wrong method"}), status=status.HTTP_501_NOT_IMPLEMENTED)
190
+
191
+
192
+ @api_view(['GET', 'PUT', 'DELETE'])
193
+ @parser_classes([JSONParser,MultiPartParser])
194
+ @permission_classes([IsAuthenticated])
195
+ def event(request, event_id):
196
+ #if request.user.is_anonymous:
197
+ # return HttpResponse(json.dumps({"detail": "Not authorized"}), status=status.HTTP_401_UNAUTHORIZED)
198
+
199
+ try:
200
+ event = Event.objects.get(pk=event_id)
201
+ except ObjectDoesNotExist:
202
+ return HttpResponse(json.dumps({"detail": "Not found"}), status=status.HTTP_404_NOT_FOUND)
203
+
204
+ if request.method == "GET":
205
+ return HttpResponse(json.dumps({"data": serialize_event(event)}), status=status.HTTP_200_OK)
206
+
207
+ if request.method == "PUT":
208
+ return save_event(request, event, status.HTTP_200_OK)
209
+
210
+ if request.method == "DELETE":
211
+ event.delete()
212
+ return HttpResponse(json.dumps({"detail": "deleted"}), status=status.HTTP_410_GONE)
213
+
214
+ return HttpResponse(json.dumps({"detail": "Wrong method"}), status=status.HTTP_501_NOT_IMPLEMENTED)
215
+
@@ -0,0 +1,81 @@
1
+ CESMD = {
2
+ '89973': [40.5093, -124.1196],
3
+ '89324': [40.5031, -124.1009],
4
+ '89686': [40.8216, -124.1697],
5
+ '89736': [40.809, -124.1547],
6
+ '89735': [40.8136, -124.1594],
7
+ '47315': [36.8619, -121.5796],
8
+ '23631': [34.065, -117.2962],
9
+ '58700': [37.8198, -122.4788],
10
+ '25749': [34.4497, -119.735],
11
+ '14406': [33.7494, -118.2715],
12
+ '58632': [37.7982, -122.3774],
13
+ '58657': [37.8286, -122.2666],
14
+ '24775': [34.8663, -118.8836],
15
+ '58601': [37.8198, -122.3429],
16
+ '24706': [34.5463, -118.1301],
17
+ '33742': [35.6696, -117.8187],
18
+ '24704': [34.0368, -118.3762],
19
+ '24689': [34.1486, -118.1561],
20
+ '54730': [37.5733, -118.739],
21
+ '13705': [33.882, -117.5497],
22
+ '13795': [33.4659, -117.6674],
23
+ '68065': [38.1205, -122.2801],
24
+ '57595': [37.4639, -121.9302],
25
+ '68185': [38.061, -122.2265],
26
+ '68717': [38.3484, -122.713],
27
+ '58754': [37.3574, -122.397],
28
+ '58658': [37.6907, -122.0993],
29
+ '76741': [39.368, -120.1151],
30
+ '89708': [40.9563, -124.1161],
31
+ '24714': [34.2878, -118.4084],
32
+ '79421': [39.9213, -123.7634],
33
+ '68778': [38.1157, -122.5054],
34
+ '58602': [37.8126, -122.3627],
35
+ '68184': [38.061, -122.2252],
36
+ '12666': [33.9153, -116.6085],
37
+ '68682': [38.0414, -122.1238],
38
+ '12649': [33.9332, -116.9907],
39
+ '67771': [38.0278, -121.7514],
40
+ '57748': [37.4176, -121.9738],
41
+ '58600': [37.8152, -122.3589],
42
+ '69760': [38.955, -123.1051],
43
+ '47707': [36.9067, -121.7818],
44
+ '3679': [32.6891, -117.1538],
45
+ '24738': [34.2878, -118.865],
46
+ '36668': [35.7331, -120.2901],
47
+ '37728': [35.5955, -121.1256],
48
+ '3731': [32.838, -117.234],
49
+ '99190': [41.8797, -124.1373],
50
+ '25324': [34.2428, -119.1905],
51
+ '58258': [37.9344, -122.4346],
52
+ '79757': [39.8485, -123.7019],
53
+ '68322': [38.0441, -122.1229],
54
+ '58596': [37.505, -122.12],
55
+ '24694': [34.3349, -118.5084],
56
+ '79683': [39.2157, -123.7678],
57
+ '24670': [34.0314, -118.4354],
58
+ '69671': [38.4347, -123.1017],
59
+ '79761': [39.8471, -123.6967],
60
+ '58656': [37.7837, -122.1769],
61
+ '67972': [38.5728, -121.587],
62
+ '99710': [41.5174, -124.0307],
63
+ '23650': [34.2251, -117.4096],
64
+ '58677': [37.5836, -122.2515],
65
+ '25758': [34.9331, -119.5941],
66
+ '79296': [39.4274, -123.8068],
67
+ '58536': [37.6746, -122.3895],
68
+ '58501': [37.6708, -122.0885],
69
+ '58414': [37.584, -122.509],
70
+ '1571': [37.34105, -121.8514],
71
+ '5235': [33.96843, -117.44815],
72
+ '25725': [34.2622, -119.231],
73
+ '58799': [37.6083, -122.1842],
74
+ '47646': [36.2391, -121.7747],
75
+ '88638': [40.881, -122.3809],
76
+ '22503': [34.2419, -116.9775],
77
+ '88194': [40.7597, -122.3188],
78
+ '26917': [34.5215, -120.3369],
79
+ '34715': [35.0387, -118.1696],
80
+ '14690': [33.7865, -118.0939],
81
+ '58678': [37.5048, -122.3346]}
@@ -0,0 +1,5 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
@@ -0,0 +1,10 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
6
+ from django.contrib import admin
7
+ from .models import Asset, Corridor
8
+
9
+ admin.site.register(Corridor)
10
+ admin.site.register(Asset)
@@ -0,0 +1,12 @@
1
+ #===----------------------------------------------------------------------===#
2
+ #
3
+ # STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ #
5
+ #===----------------------------------------------------------------------===#
6
+ from django.apps import AppConfig
7
+
8
+
9
+ class InventoryConfig(AppConfig):
10
+ default_auto_field = 'django.db.models.BigAutoField'
11
+ name = 'apps.inventory'
12
+ label = 'apps_inventory'