django-spire 0.23.10__py3-none-any.whl → 0.23.12__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.
- django_spire/auth/decorators.py +23 -0
- django_spire/consts.py +1 -1
- django_spire/contrib/progress/session.py +13 -8
- django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js +15 -3
- django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html +5 -2
- {django_spire-0.23.10.dist-info → django_spire-0.23.12.dist-info}/METADATA +1 -1
- {django_spire-0.23.10.dist-info → django_spire-0.23.12.dist-info}/RECORD +10 -9
- {django_spire-0.23.10.dist-info → django_spire-0.23.12.dist-info}/WHEEL +0 -0
- {django_spire-0.23.10.dist-info → django_spire-0.23.12.dist-info}/licenses/LICENSE.md +0 -0
- {django_spire-0.23.10.dist-info → django_spire-0.23.12.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
4
|
+
from django.http.response import HttpResponse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def bearer_token_auth_required(token: str) -> Callable[[Callable], Callable]:
|
|
8
|
+
def decorator_wrapper(view_func: Callable) -> Callable:
|
|
9
|
+
def view_wrapper(request: WSGIRequest, *args, **kwargs) -> HttpResponse:
|
|
10
|
+
if request.user.is_authenticated:
|
|
11
|
+
return view_func(request, *args, **kwargs)
|
|
12
|
+
|
|
13
|
+
auth_header_parts = request.META.get('HTTP_AUTHORIZATION', '').split(' ')
|
|
14
|
+
|
|
15
|
+
if auth_header_parts[0].lower() == 'bearer':
|
|
16
|
+
if auth_header_parts[1] == token:
|
|
17
|
+
return view_func(request, *args, **kwargs)
|
|
18
|
+
|
|
19
|
+
return HttpResponse(status=401)
|
|
20
|
+
|
|
21
|
+
return view_wrapper
|
|
22
|
+
|
|
23
|
+
return decorator_wrapper
|
django_spire/consts.py
CHANGED
|
@@ -31,7 +31,7 @@ class ProgressSession:
|
|
|
31
31
|
_COMPLETION_INCREMENT = 3.0
|
|
32
32
|
_COMPLETION_INTERVAL = 0.03
|
|
33
33
|
_MAX_SIMULATED_PERCENT = 85
|
|
34
|
-
_SIMULATION_INTERVAL = 0.
|
|
34
|
+
_SIMULATION_INTERVAL = 0.15
|
|
35
35
|
|
|
36
36
|
def __init__(self, session_id: str, tasks: dict[str, str]) -> None:
|
|
37
37
|
self._lock = threading.Lock()
|
|
@@ -40,7 +40,7 @@ class ProgressSession:
|
|
|
40
40
|
self._tasks: dict[str, dict[str, Any]] = {
|
|
41
41
|
task_id: {
|
|
42
42
|
'complete_message': '',
|
|
43
|
-
'message': '',
|
|
43
|
+
'message': 'Waiting...',
|
|
44
44
|
'name': name,
|
|
45
45
|
'percent': 0.0,
|
|
46
46
|
'status': ProgressStatus.PENDING,
|
|
@@ -53,10 +53,10 @@ class ProgressSession:
|
|
|
53
53
|
def _calculate_increment(self, current_percent: float) -> float:
|
|
54
54
|
remaining = self._MAX_SIMULATED_PERCENT - current_percent
|
|
55
55
|
ratio = remaining / self._MAX_SIMULATED_PERCENT
|
|
56
|
-
eased = ratio * ratio
|
|
57
|
-
increment = 0.
|
|
56
|
+
eased = ratio * ratio * ratio
|
|
57
|
+
increment = 0.5 * eased
|
|
58
58
|
|
|
59
|
-
return max(increment, 0.
|
|
59
|
+
return max(increment, 0.03)
|
|
60
60
|
|
|
61
61
|
def _calculate_message_index(self, percent: float) -> int:
|
|
62
62
|
message_index = int((percent / 100) * len(SIMULATION_MESSAGES))
|
|
@@ -224,8 +224,15 @@ class ProgressSession:
|
|
|
224
224
|
self._simulation_threads[task_id] = (stop_event, thread)
|
|
225
225
|
thread.start()
|
|
226
226
|
|
|
227
|
-
def stream(self, poll_interval: float = 0.
|
|
227
|
+
def stream(self, poll_interval: float = 0.1) -> Generator[str, None, None]:
|
|
228
|
+
with self._lock:
|
|
229
|
+
data = self.to_dict()
|
|
230
|
+
|
|
231
|
+
yield f'{json.dumps(data)}\n'
|
|
232
|
+
|
|
228
233
|
while True:
|
|
234
|
+
time.sleep(poll_interval)
|
|
235
|
+
|
|
229
236
|
with self._lock:
|
|
230
237
|
data = self.to_dict()
|
|
231
238
|
|
|
@@ -235,8 +242,6 @@ class ProgressSession:
|
|
|
235
242
|
self._delete()
|
|
236
243
|
break
|
|
237
244
|
|
|
238
|
-
time.sleep(poll_interval)
|
|
239
|
-
|
|
240
245
|
def to_dict(self) -> dict[str, Any]:
|
|
241
246
|
return {
|
|
242
247
|
'overall_percent': self.overall_percent,
|
|
@@ -22,7 +22,12 @@ class ProgressStream {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async start() {
|
|
25
|
-
let response = await fetch(this.url
|
|
25
|
+
let response = await fetch(this.url, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: {
|
|
28
|
+
'X-CSRFToken': get_cookie('csrftoken'),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
26
31
|
|
|
27
32
|
if (!response.ok) {
|
|
28
33
|
this.config.on_error({ message: `HTTP ${response.status}` });
|
|
@@ -31,6 +36,7 @@ class ProgressStream {
|
|
|
31
36
|
|
|
32
37
|
let reader = response.body.getReader();
|
|
33
38
|
let decoder = new TextDecoder();
|
|
39
|
+
let buffer = '';
|
|
34
40
|
|
|
35
41
|
while (true) {
|
|
36
42
|
let { done, value } = await reader.read();
|
|
@@ -39,10 +45,16 @@ class ProgressStream {
|
|
|
39
45
|
break;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
let lines =
|
|
48
|
+
buffer += decoder.decode(value, { stream: true });
|
|
49
|
+
let lines = buffer.split('\n');
|
|
50
|
+
|
|
51
|
+
buffer = lines.pop();
|
|
44
52
|
|
|
45
53
|
for (let line of lines) {
|
|
54
|
+
if (!line.trim()) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
let data = JSON.parse(line);
|
|
47
59
|
|
|
48
60
|
this.config.on_update(data);
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
</div>
|
|
59
59
|
<div class="progress" style="height: 4px;">
|
|
60
60
|
<div
|
|
61
|
-
class="progress-bar"
|
|
61
|
+
class="progress-bar progress-bar-smooth"
|
|
62
62
|
:class="task.status === 'error' ? 'bg-danger' : 'bg-success'"
|
|
63
63
|
role="progressbar"
|
|
64
64
|
:style="'width: ' + task.percent + '%'"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
</div>
|
|
76
76
|
<div class="progress" style="height: 8px;">
|
|
77
77
|
<div
|
|
78
|
-
class="progress-bar bg-primary"
|
|
78
|
+
class="progress-bar progress-bar-smooth bg-primary"
|
|
79
79
|
role="progressbar"
|
|
80
80
|
:style="'width: ' + overall_percent + '%'"
|
|
81
81
|
></div>
|
|
@@ -104,6 +104,9 @@
|
|
|
104
104
|
</div>
|
|
105
105
|
|
|
106
106
|
<style>
|
|
107
|
+
.progress-bar-smooth {
|
|
108
|
+
transition: width 0.15s ease-out;
|
|
109
|
+
}
|
|
107
110
|
.spin {
|
|
108
111
|
animation: spin 1s linear infinite;
|
|
109
112
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-spire
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.12
|
|
4
4
|
Summary: A project for Django Spire
|
|
5
5
|
Author-email: Brayden Carlson <braydenc@stratusadv.com>, Nathan Johnson <nathanj@stratusadv.com>
|
|
6
6
|
License: Copyright (c) 2025 Stratus Advanced Technologies and Contributors.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
django_spire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
django_spire/conf.py,sha256=3oUB1mtgHRjvbJsxfQWG5uL1KUP9uGig3zdP2dZphe8,942
|
|
3
|
-
django_spire/consts.py,sha256=
|
|
3
|
+
django_spire/consts.py,sha256=MhzlRhDnPAf20rnn0MeHHsKTpE0j66COSwpxmmMuUHg,172
|
|
4
4
|
django_spire/exceptions.py,sha256=M7buFvm-K4lK09pH5fVcZ-MxsDIzdpEJBF33Xss5bSw,289
|
|
5
5
|
django_spire/settings.py,sha256=0xImrKpF7VW4wc9jLGO07e2ev6D4-i_TREgpTepLp3I,1042
|
|
6
6
|
django_spire/urls.py,sha256=wQx6R-nXx69MeOF-WmDxcEUM5WmUHGplbY5uZ_HnDp8,703
|
|
@@ -139,6 +139,7 @@ django_spire/ai/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
139
139
|
django_spire/ai/tests/test_ai.py,sha256=Xjt1pWKyQCYVP47ixjEGs7fxkGoXTgRH9MFUoQc5IoQ,5404
|
|
140
140
|
django_spire/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
141
|
django_spire/auth/apps.py,sha256=oiRo6DHzANOojgEIyh0WTLn0_h-TUrbAegqvO8jOSRg,474
|
|
142
|
+
django_spire/auth/decorators.py,sha256=1YVr6R9NrUrz5FGz9oyCzgk4PM8FRy1vhSaM4IKoaHM,812
|
|
142
143
|
django_spire/auth/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
144
|
django_spire/auth/controller/controller.py,sha256=_2JRhpAlLkWQEhyfCfh5w8dFoIZ9j2AudhdVUTdrWlA,2974
|
|
144
145
|
django_spire/auth/controller/exceptions.py,sha256=yxoWnl8ZGasdGjmV_ovr_VSTt0Ys6t6uiy-Ii-6yD-c,148
|
|
@@ -399,12 +400,12 @@ django_spire/contrib/performance/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
|
399
400
|
django_spire/contrib/performance/tests/test_performance.py,sha256=wVNzrUEG0bTMcvJrqkSWkAE27LSyJMxrRZRd04ZKDQM,3029
|
|
400
401
|
django_spire/contrib/progress/__init__.py,sha256=5a7LTmUyw_cfO-3_QuN5M6zAhrCNs7MjEypL13qhoQA,345
|
|
401
402
|
django_spire/contrib/progress/enums.py,sha256=Rexk804FhmVQou7UOKSOCnjaZrSDZdniV_MWLh-kGxI,218
|
|
402
|
-
django_spire/contrib/progress/session.py,sha256=
|
|
403
|
+
django_spire/contrib/progress/session.py,sha256=yQDgqB-O6z9NRzAVbzBnoVS_ki5Z4fk74dpCH41AA10,8942
|
|
403
404
|
django_spire/contrib/progress/tasks.py,sha256=afC4vhWzvuRq6-P80LdB-BmDGD5kADtgYGM2SaKz8Ao,1625
|
|
404
405
|
django_spire/contrib/progress/static/django_spire/css/contrib/progress/progress.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
405
|
-
django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=
|
|
406
|
+
django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=aG-qCMx24Tg1xIUbhI59uziUa3gPissJzfRNPjb7ZGE,1981
|
|
406
407
|
django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html,sha256=UB5PpaZzaSihiE6BnThYrM21qVrf1iT1fF-TbtkoZrc,3389
|
|
407
|
-
django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=
|
|
408
|
+
django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=79u-wnWF8xFBObLCxTYXbPoXjnb8WP1JLWWCd4YPguo,4984
|
|
408
409
|
django_spire/contrib/queryset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
409
410
|
django_spire/contrib/queryset/enums.py,sha256=dkzI464Q53huqtNGfnM-biuKpHUQU78WwuWvt3Pm8mI,145
|
|
410
411
|
django_spire/contrib/queryset/filter_tools.py,sha256=V_s6pG2uyqvoTNtBXXXNKXE69ipwexxWAR-X30H1-XI,1129
|
|
@@ -1369,8 +1370,8 @@ django_spire/theme/urls/page_urls.py,sha256=Oak3x_xwQEb01NKdrsB1nk6yPaOEnheuSG1m
|
|
|
1369
1370
|
django_spire/theme/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1370
1371
|
django_spire/theme/views/json_views.py,sha256=PWwVTaty0BVGbj65L5cxex6JNhc-xVAI_rEYjbJWqEM,1893
|
|
1371
1372
|
django_spire/theme/views/page_views.py,sha256=WenjOa6Welpu3IMolY56ZwBjy4aK9hpbiMNuygjAl1A,3922
|
|
1372
|
-
django_spire-0.23.
|
|
1373
|
-
django_spire-0.23.
|
|
1374
|
-
django_spire-0.23.
|
|
1375
|
-
django_spire-0.23.
|
|
1376
|
-
django_spire-0.23.
|
|
1373
|
+
django_spire-0.23.12.dist-info/licenses/LICENSE.md,sha256=ZAeCT76WvaoEZE9xPhihyWjTwH0wQZXQmyRsnV2VPFs,1091
|
|
1374
|
+
django_spire-0.23.12.dist-info/METADATA,sha256=JVyjk_PCyNHx2okQ8_yiZ9GDAI4KsNPUmJScqZWGHis,5128
|
|
1375
|
+
django_spire-0.23.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1376
|
+
django_spire-0.23.12.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
|
|
1377
|
+
django_spire-0.23.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|