Ticket #4165: 5126_file_upload_contrib_app.diff

File 5126_file_upload_contrib_app.diff, 6.0 KB (added by Michael Axiak <axiak@…>, 8 years ago)

Wrote some example MiddleWare and such. Using caching makes a lot of sense for upload progress.

  • 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)
  • 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)
  • 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)
  • django/contrib/uploadprogress/middleware/__init__.py

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