Ticket #4165: 5313_admin_and_contrib.diff
File 5313_admin_and_contrib.diff, 19.2 KB (added by , 17 years ago) |
---|
-
django/contrib/admin/media/js/UploadProgress.js
1 2 var upload_progress_failures = 0; 3 var TOTAL_UPLOAD_PROGRESS_FAILURES = 10; 4 var upload_progress_num__IE = 0; 5 var show_progress = false; 6 7 function getxy(){ 8 var x,y; 9 if (self.innerHeight) // all except Explorer 10 { 11 x = self.innerWidth; 12 y = self.innerHeight; 13 } 14 else if (document.documentElement && document.documentElement.clientHeight) 15 // Explorer 6 Strict Mode 16 { 17 x = document.documentElement.clientWidth; 18 y = document.documentElement.clientHeight; 19 } 20 else if (document.body) // other Explorers 21 { 22 x = document.body.clientWidth; 23 y = document.body.clientHeight; 24 } 25 return {'x':x,'y':y} 26 } 27 28 29 function upload_ajax_problem() { 30 /* If there's a problem, will cancel after 31 TOTAL_UPLOAD_PROGRESS_FAILURES tries. */ 32 33 var progress_wrap2 = document.getElementById('progress_wrap'); 34 upload_progress_failures++; 35 if (upload_progress_failures >= TOTAL_UPLOAD_PROGRESS_FAILURES){ 36 window.clearTimeout(interval); 37 } 38 progress_wrap2.style.display = 'none'; 39 progress_wrap2.style.visibility = 'hidden'; 40 } 41 42 var humanvalue = ['B','KB','MB','GB'] 43 function humanize(bytes) { 44 curbytes = bytes; 45 iterations = 0; 46 if (!curbytes) { 47 return ''; 48 } 49 while (curbytes>1024) { 50 iterations++; 51 curbytes=curbytes/1024; 52 } 53 return curbytes.toFixed(1) + ' ' + humanvalue[iterations]; 54 } 55 56 interval = null; 57 function fetch(uuid) { 58 /* no ajax here */ 59 if (!xmlhttp) { 60 upload_ajax_problem(); 61 return; 62 } 63 64 req = xmlhttp; 65 req.open("GET", "/admin/upload_progress/?" + upload_progress_num__IE, true); 66 upload_progress_num__IE++; // IE Hack 67 req.onreadystatechange = function () { 68 var progress_wrap2 = document.getElementById('progress_wrap'); 69 var progress_bar2 = document.getElementById('progress_bar'); 70 var bar_txt = document.getElementById('progress_text'); 71 72 if (req.readyState == 4) { 73 try { 74 request_status = req.status; 75 } catch (e) { 76 /* Really bad. */ 77 request_status = -1; 78 } 79 if (request_status == 200) { 80 var upload = new Function(" return "+req.responseText)(); 81 if (upload) { 82 83 if (!upload.state) { 84 progress_wrap2.style.visibility = 'hidden'; 85 progress_wrap2.style.display = 'none'; 86 return; 87 } else if (upload.state == 'done') { 88 window.clearTimeout(interval); 89 progress_wrap2.style.visibility = 'hidden'; 90 progress_wrap2.style.display = 'none'; 91 return; 92 } else { 93 if (show_progress) { 94 progress_wrap2.style.visibility = 'visible'; 95 progress_wrap2.style.display = 'block'; 96 } 97 move_to_center(progress_wrap2); 98 bar_txt.innerHTML = ((upload.received / upload.size) * 100).toFixed(1) 99 + '% - ' + humanize(upload.received) + ' of ' 100 + humanize(upload.size); 101 var bar_width__px = 400 * upload.received / upload.size; 102 progress_bar2.style.width = bar_width__px + 'px'; 103 } 104 } else { 105 upload_ajax_problem(); 106 } 107 } else { 108 upload_ajax_problem(); 109 } 110 } 111 }; 112 try { 113 req.setRequestHeader("X-Progress-Id", uuid); 114 } catch (e) { 115 /* couldn't set the header, the request is broken. */ 116 req.abort(); 117 } 118 req.send(null); 119 120 } 121 122 function move_to_center(progress_wrap) { 123 pos = getxy(); 124 posx = parseInt((pos.x/2)-(420/2), 10); 125 posy = parseInt((pos.y/2)-(50/2), 10); 126 127 progress_wrap.style.top = posy + 'px'; 128 progress_wrap.style.left = posx + 'px'; 129 } 130 131 function close_progress() { 132 var progress_wrap2 = document.getElementById('progress_wrap'); 133 progress_wrap2.style.display = 'none'; 134 progress_wrap2.style.visibility = 'hidden'; 135 show_progress = false; 136 // don't want to follow a link. 137 return false; 138 } 139 140 141 function openprogress(e) { 142 143 show_progress = true; 144 upload_progress_failures = 0; 145 uuid = ""; 146 for (i = 0; i < 32; i++) { 147 uuid += Math.floor(Math.random() * 16).toString(16); 148 } 149 frm = e.target||e.srcElement; 150 151 var progress_wrap2 = document.getElementById('progress_wrap'); 152 move_to_center(progress_wrap2); 153 progress_wrap2.style.display = 'block'; 154 progress_wrap2.style.visibility = 'visible'; 155 156 if (frm.action.indexOf('?') == -1) { 157 frm.action=frm.action+"?progress_id=" + uuid 158 } else { 159 frm.action=frm.action+"&progress_id=" + uuid; 160 } 161 162 interval = window.setInterval( 163 function () { 164 fetch(uuid); 165 }, 166 1000 167 ); 168 } 169 170 addEvent(window, 'load', function() { 171 frms = document.getElementsByTagName('form'); 172 for (var i=0; i<frms.length; i++) { 173 if (frms[i].encoding.toLowerCase() == 'multipart/form-data') { 174 addEvent(frms[i], 'submit', openprogress); 175 return; 176 } 177 } 178 }); -
django/contrib/admin/urls.py
10 10 ('^$', 'django.contrib.admin.views.main.index'), 11 11 ('^r/(\d+)/(.*)/$', 'django.views.defaults.shortcut'), 12 12 ('^jsi18n/$', i18n_view, {'packages': 'django.conf'}), 13 ('^upload_progress/$', 'django.contrib.admin.views.main.upload_progress'), 13 14 ('^logout/$', 'django.contrib.auth.views.logout'), 14 15 ('^password_change/$', 'django.contrib.auth.views.password_change'), 15 16 ('^password_change/done/$', 'django.contrib.auth.views.password_change_done'), -
django/contrib/admin/views/main.py
81 81 def get_javascript_imports(opts, auto_populated_fields, field_sets): 82 82 # Put in any necessary JavaScript imports. 83 83 js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] 84 if opts.has_field_type(models.FileField): 85 js.append('js/UploadProgress.js') 84 86 if auto_populated_fields: 85 87 js.append('js/urlify.js') 86 88 if opts.has_field_type(models.DateTimeField) or opts.has_field_type(models.TimeField) or opts.has_field_type(models.DateField): … … 777 779 'admin/%s/change_list.html' % app_label, 778 780 'admin/change_list.html'], context_instance=c) 779 781 change_list = staff_member_required(never_cache(change_list)) 782 783 def upload_progress(request): 784 """ 785 Given this request, returns a JSON 786 object that has information on a file upload progress. 787 If there is no file upload in progress, returns an 788 empty dictionary, '{}'. 789 """ 790 from django.utils import simplejson 791 792 content = simplejson.dumps(request.file_progress) 793 794 return HttpResponse(content=content, mimetype='text/plain') -
django/contrib/admin/templates/admin/change_form.html
65 65 {% auto_populated_field_script auto_populated_fields change %} 66 66 </script> 67 67 {% endif %} 68 69 {% if has_file_field %} 70 <div id="progress_wrap" style="position: absolute; background: white; z-index: 9040; display: none; visibility: hidden; width: 420px; height: 50px padding: 10px; border: solid 1px #ddd;"> 71 <a href="#" onclick="close_progress();return false" title="Close Progress Bar" 72 style="color: #c00; font-size: 1.5em; font-weight: bold; float: right; padding: 0; position: relative; top: -2px; left: -2px;">X</a> 73 <h1>Upload progress</h1> 74 75 <div id="progress_bar" style="top: 0; left: 0; width: 0; z-index: 9049; height: 4px;" class="submit-row"></div> 76 <div id="progress_text" style="color: black;">0%</div> 68 77 </div> 78 {% endif %} 79 80 </div> 69 81 </form></div> 70 82 {% endblock %} -
django/contrib/uploadprogress/models.py
1 """ 2 Models file for a simple file upload progress application. 3 This cause the file progress to be stored in the database. 4 To activate: 5 1) Add 'django.contrib.uploadprogress.middleware.FileProgressDB' 6 to your MIDDLEWARE_CLASSES setting. 7 2) Add 'django.contrib.uploadprogress' to your INSTALLED_APPS. 8 9 """ 10 11 from django.db import models 12 import pickle 13 import datetime 14 15 class FileProgress(models.Model): 16 17 remote_addr = models.CharField(maxlength=64) 18 progress_id = models.CharField(maxlength=32) 19 progress_text = models.TextField(editable = False) 20 last_ts = models.DateTimeField() 21 22 class Meta: 23 verbose_name_plural = 'File Progresses' 24 unique_together = (('remote_addr', 25 'progress_id', 26 ), 27 ) 28 29 class Admin: 30 pass 31 32 def __str__(self): 33 return 'File Progress for "%s" and IP "%s".' % (self.progress_id, self.remote_addr) 34 35 def _get_dict(self): 36 """ 37 Returns a dictionary object. 38 """ 39 if hasattr(self, '_progress_dict'): 40 return self._progress_dict 41 42 if not self.progress_text: 43 self._progress_dict = {} 44 return {} 45 46 try: 47 self._progress_dict = pickle.loads(self.progress_text) 48 except: 49 self._progress_dict = {} 50 51 return self._progress_dict 52 53 def _set_dict(self, dict): 54 """ 55 Sets a dictionary object. 56 """ 57 self._progress_dict = dict 58 59 progress = property(_get_dict, _set_dict) 60 61 def save(self, *args, **kwargs): 62 """ 63 Pickles the dictionary representation 64 of the progress. 65 """ 66 try: 67 self.progress_text = pickle.dumps(self.progress) 68 except: 69 pass 70 71 self.last_ts = datetime.datetime.now() 72 73 return super(FileProgress, self).save(*args, **kwargs) 74 """ 75 Models file for a simple file upload progress application. 76 This cause the file progress to be stored in the database. 77 To activate: 78 1) Add 'django.contrib.uploadprogress.middleware.FileProgressDB' 79 to your MIDDLEWARE_CLASSES setting. 80 2) Add 'django.contrib.uploadprogress' to your INSTALLED_APPS. 81 82 """ 83 84 from django.db import models 85 import pickle 86 import datetime 87 88 class FileProgress(models.Model): 89 90 remote_addr = models.CharField(maxlength=64) 91 progress_id = models.CharField(maxlength=32) 92 progress_text = models.TextField(editable = False) 93 last_ts = models.DateTimeField() 94 95 class Meta: 96 verbose_name_plural = 'File Progresses' 97 unique_together = (('remote_addr', 98 'progress_id', 99 ), 100 ) 101 102 class Admin: 103 pass 104 105 def __str__(self): 106 return 'File Progress for "%s" and IP "%s".' % (self.progress_id, self.remote_addr) 107 108 def _get_dict(self): 109 """ 110 Returns a dictionary object. 111 """ 112 if hasattr(self, '_progress_dict'): 113 return self._progress_dict 114 115 if not self.progress_text: 116 self._progress_dict = {} 117 return {} 118 119 try: 120 self._progress_dict = pickle.loads(self.progress_text) 121 except: 122 self._progress_dict = {} 123 124 return self._progress_dict 125 126 def _set_dict(self, dict): 127 """ 128 Sets a dictionary object. 129 """ 130 self._progress_dict = dict 131 132 progress = property(_get_dict, _set_dict) 133 134 def save(self, *args, **kwargs): 135 """ 136 Pickles the dictionary representation 137 of the progress. 138 """ 139 try: 140 self.progress_text = pickle.dumps(self.progress) 141 except: 142 pass 143 144 self.last_ts = datetime.datetime.now() 145 146 return super(FileProgress, self).save(*args, **kwargs) -
django/contrib/uploadprogress/middleware/uploadcache.py
1 """ 2 Example middleware to process uploads using the cache framework. 3 """ 4 from django.core.cache import cache 5 from django.conf import settings 6 7 UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS_') 8 9 class FileProgressStore(object): 10 11 def _get_key(self, request): 12 """ 13 Returns the cache prefix for any cache key. 14 Uses the IP Address as well as the randomly generated uuid. 15 """ 16 17 if hasattr(self, '_cache_key'): 18 return self._cache_key 19 20 self._cache_key = '%s__%s__%s' % \ 21 (UPLOAD_CACHE_PREFIX, 22 request.META['REMOTE_ADDR'], 23 request.META['UPLOAD_PROGRESS_ID'],) 24 25 return self._cache_key 26 27 def __init__(self, UploadException): 28 self.uploadException = UploadException 29 30 def __get__(self, request, HttpRequest): 31 return cache.get(self._get_key(request), {}) 32 33 def __set__(self, request, new_val): 34 received_size = total_size = -1 35 try: 36 total_size = int(new_val['size']) 37 except: 38 pass 39 40 try: 41 received_size = int(new_val['received']) 42 except: 43 pass 44 45 cache.set(self._get_key(request), new_val) 46 47 def __delete__(self, request): 48 cache.delete(self._get_key(request)) 49 50 class FileProgressCached(object): 51 52 def process_upload(self, UploadException): 53 return FileProgressStore(UploadException) 54 """ 55 Example middleware to process uploads using the cache framework. 56 """ 57 from django.core.cache import cache 58 from django.conf import settings 59 60 UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS_') 61 62 class FileProgressStore(object): 63 64 def _get_key(self, request): 65 """ 66 Returns the cache prefix for any cache key. 67 Uses the IP Address as well as the randomly generated uuid. 68 """ 69 70 if hasattr(self, '_cache_key'): 71 return self._cache_key 72 73 self._cache_key = '%s__%s__%s' % \ 74 (UPLOAD_CACHE_PREFIX, 75 request.META['REMOTE_ADDR'], 76 request.META['UPLOAD_PROGRESS_ID'],) 77 78 return self._cache_key 79 80 def __init__(self, UploadException): 81 self.uploadException = UploadException 82 83 def __get__(self, request, HttpRequest): 84 return cache.get(self._get_key(request), {}) 85 86 def __set__(self, request, new_val): 87 received_size = total_size = -1 88 try: 89 total_size = int(new_val['size']) 90 except: 91 pass 92 93 try: 94 received_size = int(new_val['received']) 95 except: 96 pass 97 98 cache.set(self._get_key(request), new_val) 99 100 def __delete__(self, request): 101 cache.delete(self._get_key(request)) 102 103 class FileProgressCached(object): 104 105 def process_upload(self, UploadException): 106 return FileProgressStore(UploadException) -
django/contrib/uploadprogress/middleware/uploaddb.py
1 """ 2 Example middleware to process uploads using a database model. 3 """ 4 from django.contrib.uploadprogress.models import FileProgress 5 from django.conf import settings 6 import pickle 7 8 UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS') 9 10 class FileProgressDBStore(object): 11 12 def _get_db_row(self, request): 13 if not hasattr(self, '_db_row'): 14 self._db_row, created = FileProgress.objects.get_or_create( 15 remote_addr = request.META['REMOTE_ADDR'], 16 progress_id = request.META['UPLOAD_PROGRESS_ID']) 17 18 return self._db_row 19 20 def __init__(self, UploadException): 21 self.uploadException = UploadException 22 23 def __get__(self, request, HttpRequest): 24 return self._get_db_row(request).progress 25 26 def __set__(self, request, new_val): 27 row = self._get_db_row(request) 28 row.progress = new_val 29 row.save() 30 31 def __delete__(self, request): 32 self._get_db_row(request).delete() 33 34 class FileProgressDB(object): 35 36 def process_upload(self, UploadException): 37 return FileProgressDBStore(UploadException) 38 """ 39 Example middleware to process uploads using a database model. 40 """ 41 from django.contrib.uploadprogress.models import FileProgress 42 from django.conf import settings 43 import pickle 44 45 UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS') 46 47 class FileProgressDBStore(object): 48 49 def _get_db_row(self, request): 50 if not hasattr(self, '_db_row'): 51 self._db_row, created = FileProgress.objects.get_or_create( 52 remote_addr = request.META['REMOTE_ADDR'], 53 progress_id = request.META['UPLOAD_PROGRESS_ID']) 54 55 return self._db_row 56 57 def __init__(self, UploadException): 58 self.uploadException = UploadException 59 60 def __get__(self, request, HttpRequest): 61 return self._get_db_row(request).progress 62 63 def __set__(self, request, new_val): 64 row = self._get_db_row(request) 65 row.progress = new_val 66 row.save() 67 68 def __delete__(self, request): 69 self._get_db_row(request).delete() 70 71 class FileProgressDB(object): 72 73 def process_upload(self, UploadException): 74 return FileProgressDBStore(UploadException) -
django/contrib/uploadprogress/middleware/__init__.py
1 from django.contrib.uploadprogress.middleware.uploaddb import FileProgressDB 2 from django.contrib.uploadprogress.middleware.uploadcache import FileProgressCached 3 4 from django.contrib.uploadprogress.middleware.uploaddb import FileProgressDB 5 from django.contrib.uploadprogress.middleware.uploadcache import FileProgressCached 6