Code

Ticket #4165: 5116_progress_bar_newforms_admin.diff

File 5116_progress_bar_newforms_admin.diff, 18.5 KB (added by Michael Axiak <axiak@…>, 7 years ago)

Newforms-Admin branch patch

Line 
1Index: django/contrib/admin/media/js/UploadProgress.js
2===================================================================
3--- django/contrib/admin/media/js/UploadProgress.js     (revision 0)
4+++ django/contrib/admin/media/js/UploadProgress.js     (revision 0)
5@@ -0,0 +1,528 @@
6+function getxy(){
7+    var x,y;
8+    if (self.innerHeight) // all except Explorer
9+        {
10+        x = self.innerWidth;
11+        y = self.innerHeight;
12+        }
13+    else if (document.documentElement && document.documentElement.clientHeight)
14+        // Explorer 6 Strict Mode
15+        {
16+        x = document.documentElement.clientWidth;
17+        y = document.documentElement.clientHeight;
18+        }
19+    else if (document.body) // other Explorers
20+        {
21+        x = document.body.clientWidth;
22+        y = document.body.clientHeight;
23+        }
24+    return {'x':x,'y':y}
25+    }
26+
27+var humanvalue = ['B','KB','MB','GB']
28+function humanize(bytes) {
29+    curbytes = bytes
30+    iterations = 0
31+    while (curbytes>1024) {
32+        iterations++
33+        curbytes=curbytes/1024
34+        }
35+    return curbytes.toFixed(1) + ' ' + humanvalue[iterations]
36+    }
37+
38+interval = null;
39+function fetch(uuid) {
40+    req = xmlhttp
41+    req.open("GET", "/admin/upload_progress/", 1);
42+    req.setRequestHeader("X-Progress-Id", uuid);
43+    req.onreadystatechange = function () {
44+    if (req.readyState == 4) {
45+        if (req.status == 200) {
46+
47+            var upload = eval( '(' + req.responseText + ')' );
48+
49+            if (upload.state == 'done' || upload.state == 'uploading')
50+                bar = document.getElementById('progress_bar');
51+                progress_wrap = document.getElementById('progress_wrap');
52+                if (upload.state == 'done') {
53+                    window.clearTimeout(interval);
54+                   progress_wrap.style.visibility = 'hidden';
55+                    return;   
56+                }
57+                bar_txt = document.getElementById('progress_text')
58+                bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) + '% - ' +
59+                    humanize(upload.received) + ' of ' + humanize(upload.size)
60+                w = 400 * upload.received / upload.size;
61+                bar.style.width = w + 'px';
62+
63+                }
64+            }
65+        }
66+    req.send(null);
67+
68+    }
69+
70+function closeprogress() {
71+
72+
73+
74+}
75+
76+function openprogress(e) {
77+
78+    uuid = "";
79+    for (i = 0; i < 32; i++) {
80+        uuid += Math.floor(Math.random() * 16).toString(16);
81+        }
82+    frm = e.target||e.srcElement;
83+
84+    if (frm.action.indexOf('?') == -1) {
85+       frm.action=frm.action+"?progress_id=" + uuid;
86+    } else {
87+       frm.action=frm.action+"&progress_id=" + uuid;
88+    }
89+
90+    if (document.getElementById('progress_wrap')) {
91+        document.getElementById('progress_wrap').style.visibility = 'visible';
92+        document.getElementById('progress_bar').style.width = '0';
93+        document.getElementById('progress_text').innerHTML = '0%';
94+
95+        interval = window.setInterval(
96+        function () {
97+            fetch(uuid);
98+            },
99+        1000
100+        );
101+        return;
102+    }
103+
104+    pos = getxy()
105+    posx = parseInt((pos.x/2)-(420/2), 10)
106+    posy = parseInt((pos.y/2)-(50/2), 10)
107+
108+    progress_wrap = quickElement('div', document.body, '', 'style',
109+        'position: absolute; top: '+posy+'px; left: '+posx+'px; height: 50px; ' +
110+        'padding: 10px; width: 420px; background: #ffffff; ' +
111+        'border: solid 1px #dddddd;', 'id', 'progress_wrap')
112+
113+    progress_label = quickElement('h1', progress_wrap, 'Upload progress')
114+
115+    progress = quickElement('div', progress_wrap, '', 'style',
116+        'top: 0; left: 0; width: 0px; ', 'id', 'progress_bar', 'class', 'submit-row')
117+
118+    progress_text = quickElement('div', progress_wrap, '0%', 'style',
119+        'color: #000000; ', 'id', 'progress_text')
120+
121+    interval = window.setInterval(
122+        function () {
123+            fetch(uuid);
124+            },
125+        1000
126+        );
127+    }
128+
129+addEvent(window, 'load', function() {
130+        frms = document.getElementsByTagName('form');
131+        for (var i=0; i<frms.length; i++) {
132+           if (frms[i].encoding.toLowerCase() == 'multipart/form-data') {
133+              addEvent(frms[i], 'submit',  openprogress);
134+              return;
135+           }
136+        }
137+    });
138+function getxy(){
139+    var x,y;
140+    if (self.innerHeight) // all except Explorer
141+        {
142+        x = self.innerWidth;
143+        y = self.innerHeight;
144+        }
145+    else if (document.documentElement && document.documentElement.clientHeight)
146+        // Explorer 6 Strict Mode
147+        {
148+        x = document.documentElement.clientWidth;
149+        y = document.documentElement.clientHeight;
150+        }
151+    else if (document.body) // other Explorers
152+        {
153+        x = document.body.clientWidth;
154+        y = document.body.clientHeight;
155+        }
156+    return {'x':x,'y':y}
157+    }
158+
159+var humanvalue = ['B','KB','MB','GB']
160+function humanize(bytes) {
161+    curbytes = bytes
162+    iterations = 0
163+    while (curbytes>1024) {
164+        iterations++
165+        curbytes=curbytes/1024
166+        }
167+    return curbytes.toFixed(1) + ' ' + humanvalue[iterations]
168+    }
169+
170+interval = null;
171+function fetch(uuid) {
172+    req = xmlhttp
173+    req.open("GET", "/admin/upload_progress/", 1);
174+    req.setRequestHeader("X-Progress-Id", uuid);
175+    req.onreadystatechange = function () {
176+    if (req.readyState == 4) {
177+        if (req.status == 200) {
178+
179+            var upload = eval( '(' + req.responseText + ')' );
180+
181+            if (upload.state == 'done' || upload.state == 'uploading')
182+                bar = document.getElementById('progress_bar');
183+                progress_wrap = document.getElementById('progress_wrap');
184+                if (upload.state == 'done') {
185+                    window.clearTimeout(interval);
186+                   progress_wrap.style.visibility = 'hidden';
187+                    return;   
188+                }
189+                bar_txt = document.getElementById('progress_text')
190+                bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) + '% - ' +
191+                    humanize(upload.received) + ' of ' + humanize(upload.size)
192+                w = 400 * upload.received / upload.size;
193+                bar.style.width = w + 'px';
194+
195+                }
196+            }
197+        }
198+    req.send(null);
199+
200+    }
201+
202+function closeprogress() {
203+
204+
205+
206+}
207+
208+function openprogress(e) {
209+
210+    uuid = "";
211+    for (i = 0; i < 32; i++) {
212+        uuid += Math.floor(Math.random() * 16).toString(16);
213+        }
214+    frm = e.target||e.srcElement;
215+
216+    if (frm.action.indexOf('?') == -1) {
217+       frm.action=frm.action+"?progress_id=" + uuid;
218+    } else {
219+       frm.action=frm.action+"&progress_id=" + uuid;
220+    }
221+
222+    if (document.getElementById('progress_wrap')) {
223+        document.getElementById('progress_wrap').style.visibility = 'visible';
224+        document.getElementById('progress_bar').style.width = '0';
225+        document.getElementById('progress_text').innerHTML = '0%';
226+
227+        interval = window.setInterval(
228+        function () {
229+            fetch(uuid);
230+            },
231+        1000
232+        );
233+        return;
234+    }
235+
236+    pos = getxy()
237+    posx = parseInt((pos.x/2)-(420/2), 10)
238+    posy = parseInt((pos.y/2)-(50/2), 10)
239+
240+    progress_wrap = quickElement('div', document.body, '', 'style',
241+        'position: absolute; top: '+posy+'px; left: '+posx+'px; height: 50px; ' +
242+        'padding: 10px; width: 420px; background: #ffffff; ' +
243+        'border: solid 1px #dddddd;', 'id', 'progress_wrap')
244+
245+    progress_label = quickElement('h1', progress_wrap, 'Upload progress')
246+
247+    progress = quickElement('div', progress_wrap, '', 'style',
248+        'top: 0; left: 0; width: 0px; ', 'id', 'progress_bar', 'class', 'submit-row')
249+
250+    progress_text = quickElement('div', progress_wrap, '0%', 'style',
251+        'color: #000000; ', 'id', 'progress_text')
252+
253+    interval = window.setInterval(
254+        function () {
255+            fetch(uuid);
256+            },
257+        1000
258+        );
259+    }
260+
261+addEvent(window, 'load', function() {
262+        frms = document.getElementsByTagName('form');
263+        for (var i=0; i<frms.length; i++) {
264+           if (frms[i].encoding.toLowerCase() == 'multipart/form-data') {
265+              addEvent(frms[i], 'submit',  openprogress);
266+              return;
267+           }
268+        }
269+    });
270+function getxy(){
271+    var x,y;
272+    if (self.innerHeight) // all except Explorer
273+        {
274+        x = self.innerWidth;
275+        y = self.innerHeight;
276+        }
277+    else if (document.documentElement && document.documentElement.clientHeight)
278+        // Explorer 6 Strict Mode
279+        {
280+        x = document.documentElement.clientWidth;
281+        y = document.documentElement.clientHeight;
282+        }
283+    else if (document.body) // other Explorers
284+        {
285+        x = document.body.clientWidth;
286+        y = document.body.clientHeight;
287+        }
288+    return {'x':x,'y':y}
289+    }
290+
291+var humanvalue = ['B','KB','MB','GB']
292+function humanize(bytes) {
293+    curbytes = bytes
294+    iterations = 0
295+    while (curbytes>1024) {
296+        iterations++
297+        curbytes=curbytes/1024
298+        }
299+    return curbytes.toFixed(1) + ' ' + humanvalue[iterations]
300+    }
301+
302+interval = null;
303+function fetch(uuid) {
304+    req = xmlhttp
305+    req.open("GET", "/admin/upload_progress/", 1);
306+    req.setRequestHeader("X-Progress-Id", uuid);
307+    req.onreadystatechange = function () {
308+    if (req.readyState == 4) {
309+        if (req.status == 200) {
310+
311+            var upload = eval( '(' + req.responseText + ')' );
312+
313+            if (upload.state == 'done' || upload.state == 'uploading')
314+                bar = document.getElementById('progress_bar');
315+                progress_wrap = document.getElementById('progress_wrap');
316+                if (upload.state == 'done') {
317+                    window.clearTimeout(interval);
318+                   progress_wrap.style.visibility = 'hidden';
319+                    return;   
320+                }
321+                bar_txt = document.getElementById('progress_text')
322+                bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) + '% - ' +
323+                    humanize(upload.received) + ' of ' + humanize(upload.size)
324+                w = 400 * upload.received / upload.size;
325+                bar.style.width = w + 'px';
326+
327+                }
328+            }
329+        }
330+    req.send(null);
331+
332+    }
333+
334+function closeprogress() {
335+
336+
337+
338+}
339+
340+function openprogress(e) {
341+
342+    uuid = "";
343+    for (i = 0; i < 32; i++) {
344+        uuid += Math.floor(Math.random() * 16).toString(16);
345+        }
346+    frm = e.target||e.srcElement;
347+
348+    if (frm.action.indexOf('?') == -1) {
349+       frm.action=frm.action+"?progress_id=" + uuid;
350+    } else {
351+       frm.action=frm.action+"&progress_id=" + uuid;
352+    }
353+
354+    if (document.getElementById('progress_wrap')) {
355+        document.getElementById('progress_wrap').style.visibility = 'visible';
356+        document.getElementById('progress_bar').style.width = '0';
357+        document.getElementById('progress_text').innerHTML = '0%';
358+
359+        interval = window.setInterval(
360+        function () {
361+            fetch(uuid);
362+            },
363+        1000
364+        );
365+        return;
366+    }
367+
368+    pos = getxy()
369+    posx = parseInt((pos.x/2)-(420/2), 10)
370+    posy = parseInt((pos.y/2)-(50/2), 10)
371+
372+    progress_wrap = quickElement('div', document.body, '', 'style',
373+        'position: absolute; top: '+posy+'px; left: '+posx+'px; height: 50px; ' +
374+        'padding: 10px; width: 420px; background: #ffffff; ' +
375+        'border: solid 1px #dddddd;', 'id', 'progress_wrap')
376+
377+    progress_label = quickElement('h1', progress_wrap, 'Upload progress')
378+
379+    progress = quickElement('div', progress_wrap, '', 'style',
380+        'top: 0; left: 0; width: 0px; ', 'id', 'progress_bar', 'class', 'submit-row')
381+
382+    progress_text = quickElement('div', progress_wrap, '0%', 'style',
383+        'color: #000000; ', 'id', 'progress_text')
384+
385+    interval = window.setInterval(
386+        function () {
387+            fetch(uuid);
388+            },
389+        1000
390+        );
391+    }
392+
393+addEvent(window, 'load', function() {
394+        frms = document.getElementsByTagName('form');
395+        for (var i=0; i<frms.length; i++) {
396+           if (frms[i].encoding.toLowerCase() == 'multipart/form-data') {
397+              addEvent(frms[i], 'submit',  openprogress);
398+              return;
399+           }
400+        }
401+    });
402+function getxy(){
403+    var x,y;
404+    if (self.innerHeight) // all except Explorer
405+        {
406+        x = self.innerWidth;
407+        y = self.innerHeight;
408+        }
409+    else if (document.documentElement && document.documentElement.clientHeight)
410+        // Explorer 6 Strict Mode
411+        {
412+        x = document.documentElement.clientWidth;
413+        y = document.documentElement.clientHeight;
414+        }
415+    else if (document.body) // other Explorers
416+        {
417+        x = document.body.clientWidth;
418+        y = document.body.clientHeight;
419+        }
420+    return {'x':x,'y':y}
421+    }
422+
423+var humanvalue = ['B','KB','MB','GB']
424+function humanize(bytes) {
425+    curbytes = bytes
426+    iterations = 0
427+    while (curbytes>1024) {
428+        iterations++
429+        curbytes=curbytes/1024
430+        }
431+    return curbytes.toFixed(1) + ' ' + humanvalue[iterations]
432+    }
433+
434+interval = null;
435+function fetch(uuid) {
436+    req = xmlhttp
437+    req.open("GET", "/admin/upload_progress/", 1);
438+    req.setRequestHeader("X-Progress-Id", uuid);
439+    req.onreadystatechange = function () {
440+    if (req.readyState == 4) {
441+        if (req.status == 200) {
442+
443+            var upload = eval( '(' + req.responseText + ')' );
444+
445+            if (upload.state == 'done' || upload.state == 'uploading')
446+                bar = document.getElementById('progress_bar');
447+                progress_wrap = document.getElementById('progress_wrap');
448+                if (upload.state == 'done') {
449+                    window.clearTimeout(interval);
450+                   progress_wrap.style.visibility = 'hidden';
451+                    return;   
452+                }
453+                bar_txt = document.getElementById('progress_text')
454+                bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) + '% - ' +
455+                    humanize(upload.received) + ' of ' + humanize(upload.size)
456+                w = 400 * upload.received / upload.size;
457+                bar.style.width = w + 'px';
458+
459+                }
460+            }
461+        }
462+    req.send(null);
463+
464+    }
465+
466+function closeprogress() {
467+
468+
469+
470+}
471+
472+function openprogress(e) {
473+
474+    uuid = "";
475+    for (i = 0; i < 32; i++) {
476+        uuid += Math.floor(Math.random() * 16).toString(16);
477+        }
478+    frm = e.target||e.srcElement;
479+
480+    if (frm.action.indexOf('?') == -1) {
481+       frm.action=frm.action+"?progress_id=" + uuid;
482+    } else {
483+       frm.action=frm.action+"&progress_id=" + uuid;
484+    }
485+
486+    if (document.getElementById('progress_wrap')) {
487+        document.getElementById('progress_wrap').style.visibility = 'visible';
488+        document.getElementById('progress_bar').style.width = '0';
489+        document.getElementById('progress_text').innerHTML = '0%';
490+
491+        interval = window.setInterval(
492+        function () {
493+            fetch(uuid);
494+            },
495+        1000
496+        );
497+        return;
498+    }
499+
500+    pos = getxy()
501+    posx = parseInt((pos.x/2)-(420/2), 10)
502+    posy = parseInt((pos.y/2)-(50/2), 10)
503+
504+    progress_wrap = quickElement('div', document.body, '', 'style',
505+        'position: absolute; top: '+posy+'px; left: '+posx+'px; height: 50px; ' +
506+        'padding: 10px; width: 420px; background: #ffffff; ' +
507+        'border: solid 1px #dddddd;', 'id', 'progress_wrap')
508+
509+    progress_label = quickElement('h1', progress_wrap, 'Upload progress')
510+
511+    progress = quickElement('div', progress_wrap, '', 'style',
512+        'top: 0; left: 0; width: 0px; ', 'id', 'progress_bar', 'class', 'submit-row')
513+
514+    progress_text = quickElement('div', progress_wrap, '0%', 'style',
515+        'color: #000000; ', 'id', 'progress_text')
516+
517+    interval = window.setInterval(
518+        function () {
519+            fetch(uuid);
520+            },
521+        1000
522+        );
523+    }
524+
525+addEvent(window, 'load', function() {
526+        frms = document.getElementsByTagName('form');
527+        for (var i=0; i<frms.length; i++) {
528+           if (frms[i].encoding.toLowerCase() == 'multipart/form-data') {
529+              addEvent(frms[i], 'submit',  openprogress);
530+              return;
531+           }
532+        }
533+    });
534\ No newline at end of file
535Index: django/contrib/admin/options.py
536===================================================================
537--- django/contrib/admin/options.py     (revision 5116)
538+++ django/contrib/admin/options.py     (working copy)
539@@ -154,6 +154,8 @@
540         js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
541         if self.prepopulated_fields:
542             js.append('js/urlify.js')
543+        if self.opts.has_field_type(models.FileField):
544+            js.append('js/UploadProgress.js')
545         if self.opts.has_field_type(models.DateTimeField) or self.opts.has_field_type(models.TimeField) or self.opts.has_field_type(models.DateField):
546             js.extend(['js/calendar.js', 'js/admin/DateTimeShortcuts.js'])
547         if self.opts.get_ordered_objects():
548Index: django/contrib/admin/urls.py
549===================================================================
550--- django/contrib/admin/urls.py        (revision 5116)
551+++ django/contrib/admin/urls.py        (working copy)
552@@ -9,6 +9,8 @@
553     #('^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
554     ('^template_validator/$', 'django.contrib.admin.views.template.template_validator'),
555 
556+    # Upload progress bar support
557+    #('^upload_progress/$', 'django.contrib.admin.views.main.upload_progress'),
558     # "Add user" -- a special-case view
559     ('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
560     # "Change user password" -- another special-case view
561Index: django/contrib/admin/views/main.py
562===================================================================
563--- django/contrib/admin/views/main.py  (revision 5116)
564+++ django/contrib/admin/views/main.py  (working copy)
565@@ -48,6 +48,20 @@
566             res[i] = '_%02X' % ord(c)
567     return ''.join(res)
568 
569+def upload_progress(request):
570+    """
571+    Given this request, returns a JSON
572+    object that has information on a file upload progress.
573+    If there is no file upload in progress, returns an
574+    empty dictionary, '{}'.
575+    """
576+
577+    from django.utils import simplejson
578+
579+    content = simplejson.dumps(request.file_progress)
580+
581+    return HttpResponse(content=content, mimetype='text/plain')
582+
583 def model_admin_view(request, app_label, model_name, rest_of_url):
584     model = models.get_model(app_label, model_name)
585     if model is None: