Ticket #4165: 5313_admin_and_contrib.diff

File 5313_admin_and_contrib.diff, 19.2 KB (added by Michael Axiak <axiak@…>, 8 years ago)

Works in IE etc

  • django/contrib/admin/media/js/UploadProgress.js

     
     1
     2var upload_progress_failures = 0;
     3var TOTAL_UPLOAD_PROGRESS_FAILURES = 10;
     4var upload_progress_num__IE = 0;
     5var show_progress = false;
     6
     7function 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
     29function 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
     42var humanvalue = ['B','KB','MB','GB']
     43function 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
     56interval = null;
     57function 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
     122function 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
     131function 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
     141function 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
     170addEvent(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

     
    1010    ('^$', 'django.contrib.admin.views.main.index'),
    1111    ('^r/(\d+)/(.*)/$', 'django.views.defaults.shortcut'),
    1212    ('^jsi18n/$', i18n_view, {'packages': 'django.conf'}),
     13    ('^upload_progress/$', 'django.contrib.admin.views.main.upload_progress'),
    1314    ('^logout/$', 'django.contrib.auth.views.logout'),
    1415    ('^password_change/$', 'django.contrib.auth.views.password_change'),
    1516    ('^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
  • django/contrib/admin/views/main.py

     
    8181def get_javascript_imports(opts, auto_populated_fields, field_sets):
    8282# Put in any necessary JavaScript imports.
    8383    js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
     84    if opts.has_field_type(models.FileField):
     85        js.append('js/UploadProgress.js')
    8486    if auto_populated_fields:
    8587        js.append('js/urlify.js')
    8688    if opts.has_field_type(models.DateTimeField) or opts.has_field_type(models.TimeField) or opts.has_field_type(models.DateField):
     
    777779                               'admin/%s/change_list.html' % app_label,
    778780                               'admin/change_list.html'], context_instance=c)
    779781change_list = staff_member_required(never_cache(change_list))
     782
     783def 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

     
    6565   {% auto_populated_field_script auto_populated_fields change %}
    6666   </script>
    6767{% 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>
    6877</div>
     78{% endif %}
     79
     80</div>
    6981</form></div>
    7082{% endblock %}
  • django/contrib/uploadprogress/models.py

     
     1"""
     2Models file for a simple file upload progress application.
     3This cause the file progress to be stored in the database.
     4To activate:
     51) Add 'django.contrib.uploadprogress.middleware.FileProgressDB'
     6   to your MIDDLEWARE_CLASSES setting.
     72) Add 'django.contrib.uploadprogress' to your INSTALLED_APPS.
     8
     9"""
     10
     11from django.db import models
     12import pickle
     13import datetime
     14
     15class 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"""
     75Models file for a simple file upload progress application.
     76This cause the file progress to be stored in the database.
     77To activate:
     781) Add 'django.contrib.uploadprogress.middleware.FileProgressDB'
     79   to your MIDDLEWARE_CLASSES setting.
     802) Add 'django.contrib.uploadprogress' to your INSTALLED_APPS.
     81
     82"""
     83
     84from django.db import models
     85import pickle
     86import datetime
     87
     88class 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"""
     2Example middleware to process uploads using the cache framework.
     3"""
     4from django.core.cache import cache
     5from django.conf import settings
     6
     7UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS_')
     8
     9class 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
     50class FileProgressCached(object):
     51
     52    def process_upload(self, UploadException):
     53        return FileProgressStore(UploadException)
     54"""
     55Example middleware to process uploads using the cache framework.
     56"""
     57from django.core.cache import cache
     58from django.conf import settings
     59
     60UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS_')
     61
     62class 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
     103class FileProgressCached(object):
     104
     105    def process_upload(self, UploadException):
     106        return FileProgressStore(UploadException)
  • django/contrib/uploadprogress/middleware/uploaddb.py

     
     1"""
     2Example middleware to process uploads using a database model.
     3"""
     4from django.contrib.uploadprogress.models import FileProgress
     5from django.conf import settings
     6import pickle
     7
     8UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS')
     9
     10class 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
     34class FileProgressDB(object):
     35
     36    def process_upload(self, UploadException):
     37        return FileProgressDBStore(UploadException)
     38"""
     39Example middleware to process uploads using a database model.
     40"""
     41from django.contrib.uploadprogress.models import FileProgress
     42from django.conf import settings
     43import pickle
     44
     45UPLOAD_CACHE_PREFIX = getattr(settings, 'UPLOAD_CACHE_PREFIX', 'UPLOAD_PROGRESS')
     46
     47class 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
     71class FileProgressDB(object):
     72
     73    def process_upload(self, UploadException):
     74        return FileProgressDBStore(UploadException)
  • django/contrib/uploadprogress/middleware/__init__.py

     
     1from django.contrib.uploadprogress.middleware.uploaddb import FileProgressDB
     2from django.contrib.uploadprogress.middleware.uploadcache import FileProgressCached
     3
     4from django.contrib.uploadprogress.middleware.uploaddb import FileProgressDB
     5from django.contrib.uploadprogress.middleware.uploadcache import FileProgressCached
     6
Back to Top