django-spire 0.23.5__py3-none-any.whl → 0.23.6__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/consts.py CHANGED
@@ -1,4 +1,4 @@
1
- __VERSION__ = '0.23.5'
1
+ __VERSION__ = '0.23.6'
2
2
 
3
3
  MAINTENANCE_MODE_SETTINGS_NAME = 'MAINTENANCE_MODE'
4
4
 
@@ -1,7 +1,9 @@
1
1
  class ProgressStream {
2
2
  constructor(url, config = {}) {
3
3
  this.url = url;
4
- this.event_source = null;
4
+ this.controller = null;
5
+ this.is_running = false;
6
+
5
7
  this.config = {
6
8
  on_update: config.on_update || (() => {}),
7
9
  on_complete: config.on_complete || (() => {}),
@@ -11,52 +13,119 @@ class ProgressStream {
11
13
  };
12
14
  }
13
15
 
14
- start() {
15
- this.event_source = new EventSource(this.url);
16
+ async start() {
17
+ if (this.is_running) return;
18
+
19
+ this.is_running = true;
20
+ this.controller = new AbortController();
21
+
22
+ try {
23
+ let response = await this._fetch();
24
+
25
+ if (!response.ok) {
26
+ throw new Error(`HTTP ${response.status}`);
27
+ }
16
28
 
17
- this.event_source.onmessage = (event) => {
18
- const data = JSON.parse(event.data);
29
+ await this._read_stream(response);
30
+ } catch (error) {
31
+ this._handle_error(error);
32
+ }
33
+ }
19
34
 
20
- this.config.on_update(data);
35
+ stop() {
36
+ if (!this.is_running) return;
21
37
 
22
- if (data.step === 'error') {
23
- this.config.on_error(data);
24
- this.stop();
38
+ this.is_running = false;
25
39
 
26
- return;
40
+ if (this.controller) {
41
+ this.controller.abort();
42
+ this.controller = null;
43
+ }
44
+ }
45
+
46
+ async _fetch() {
47
+ return fetch(this.url, {
48
+ method: 'POST',
49
+ signal: this.controller.signal,
50
+ headers: {
51
+ 'X-CSRFToken': get_cookie('csrftoken'),
27
52
  }
53
+ });
54
+ }
55
+
56
+ async _read_stream(response) {
57
+ let reader = response.body.getReader();
58
+ let decoder = new TextDecoder();
59
+ let buffer = '';
28
60
 
29
- if (data.progress >= 100) {
30
- this.config.on_complete(data);
31
- this.stop();
61
+ while (this.is_running) {
62
+ let { done, value } = await reader.read();
32
63
 
33
- if (this.config.redirect_on_complete) {
34
- setTimeout(() => {
35
- window.location.href = this.config.redirect_on_complete;
36
- }, this.config.redirect_delay);
37
- }
64
+ if (done) break;
65
+
66
+ buffer += decoder.decode(value, { stream: true });
67
+ buffer = this._process_buffer(buffer);
68
+ }
69
+ }
70
+
71
+ _process_buffer(buffer) {
72
+ let lines = buffer.split('\n');
73
+ let remainder = lines.pop();
74
+
75
+ for (let line of lines) {
76
+ if (line.startsWith('data: ')) {
77
+ this._handle_message(line.slice(6));
38
78
  }
39
- };
79
+ }
80
+
81
+ return remainder;
82
+ }
40
83
 
41
- this.event_source.onerror = (error) => {
42
- console.error('ProgressStream error:', error);
84
+ _handle_message(json_string) {
85
+ let data;
86
+
87
+ try {
88
+ data = JSON.parse(json_string);
89
+ } catch {
90
+ return;
91
+ }
43
92
 
44
- this.config.on_error({
45
- step: 'error',
46
- message: 'Connection error',
47
- progress: 0
48
- });
93
+ this.config.on_update(data);
49
94
 
95
+ if (data.step === 'error') {
96
+ this.config.on_error(data);
50
97
  this.stop();
51
- };
52
- }
98
+ return;
99
+ }
53
100
 
54
- stop() {
55
- if (this.event_source) {
56
- this.event_source.close();
57
- this.event_source = null;
101
+ if (data.progress >= 100) {
102
+ this.config.on_complete(data);
103
+ this.stop();
104
+ this._redirect();
58
105
  }
59
106
  }
107
+
108
+ _handle_error(error) {
109
+ if (error.name === 'AbortError') return;
110
+
111
+ console.error('ProgressStream error:', error);
112
+
113
+ this.config.on_error({
114
+ step: 'error',
115
+ message: 'Connection error',
116
+ progress: 0
117
+ });
118
+
119
+ this.stop();
120
+ }
121
+
122
+ _redirect() {
123
+ if (!this.config.redirect_on_complete) return;
124
+
125
+ setTimeout(() => {
126
+ window.location.href = this.config.redirect_on_complete;
127
+ }, this.config.redirect_delay);
128
+ }
60
129
  }
61
130
 
62
131
  window.ProgressStream = ProgressStream;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-spire
3
- Version: 0.23.5
3
+ Version: 0.23.6
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) 2024 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=c5Hs-7lk9T15254tOasiQ2ZTFLQIVJof9_QJDfm1PAI,933
3
- django_spire/consts.py,sha256=YR9sX6FXBUPmKDLHD7b1mDlQp6jwxIOoAF39q4rJoiM,171
3
+ django_spire/consts.py,sha256=01VQ7ErZIkZ3Hafkfrhc-evimRsJsp0GWrFmDpULkDI,171
4
4
  django_spire/exceptions.py,sha256=L5ndRO5ftMmh0pHkO2z_NG3LSGZviJ-dDHNT73SzTNw,48
5
5
  django_spire/settings.py,sha256=B4GPqBGt_dmkt0Ay0j-IP-SZ6mY44m2Ap5kVSON5YLA,1005
6
6
  django_spire/urls.py,sha256=mKeZszb5U4iIGqddMb5Tt5fRC72U2wABEOi6mvOfEBU,656
@@ -357,7 +357,7 @@ django_spire/contrib/progress/task.py,sha256=4pMbzOsjRRNqPKNohh08D39DRFpC3QomTCH
357
357
  django_spire/contrib/progress/tracker.py,sha256=xjGlEyKe5aiKW_KC8NKZ8F0BjQdFpLUqHz5Gr_C7jws,6490
358
358
  django_spire/contrib/progress/views.py,sha256=CwJu-L09tTiCpsjVuqzvMEKVqp6-etLDi7L9ibmlq8U,1694
359
359
  django_spire/contrib/progress/static/django_spire/css/contrib/progress/progress.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
360
- django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=2Zuwiu1nWJpghzU-6fmf6s4qKLLyiZUcAJwB9-v5xWI,1701
360
+ django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=cfXUp-Kr-J9zxW1WZnCIY9G7e3IUBwR9ISzviSs2F4o,3109
361
361
  django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html,sha256=2Ajv0UBJEGwc4InVe69aLe2u4K56yh2JAuvO6uH24j8,3353
362
362
  django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=Qxer-q4GBC5h8onzno2NUlPrXluw_tO1kWlGComQ98E,5232
363
363
  django_spire/contrib/queryset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1201,8 +1201,8 @@ django_spire/theme/urls/page_urls.py,sha256=S8nkKkgbhG3XHI3uMUL-piOjXIrRkuY2UlM_
1201
1201
  django_spire/theme/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1202
1202
  django_spire/theme/views/json_views.py,sha256=PWwVTaty0BVGbj65L5cxex6JNhc-xVAI_rEYjbJWqEM,1893
1203
1203
  django_spire/theme/views/page_views.py,sha256=WenjOa6Welpu3IMolY56ZwBjy4aK9hpbiMNuygjAl1A,3922
1204
- django_spire-0.23.5.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1205
- django_spire-0.23.5.dist-info/METADATA,sha256=NsK-z_MdElXotF4ZnWMERuHNpLZODw6_kRI_lO7bt-Q,5127
1206
- django_spire-0.23.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1207
- django_spire-0.23.5.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1208
- django_spire-0.23.5.dist-info/RECORD,,
1204
+ django_spire-0.23.6.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1205
+ django_spire-0.23.6.dist-info/METADATA,sha256=bXPb2DXsbOugY9gvJ_l1mLKlYLxEuijjQSQk2VBETd8,5127
1206
+ django_spire-0.23.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1207
+ django_spire-0.23.6.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1208
+ django_spire-0.23.6.dist-info/RECORD,,