60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
VERSION = (0, 1, 1)
|
|
__version__ = '.'.join(map(str, VERSION))
|
|
|
|
import os.path
|
|
from mimetypes import guess_type
|
|
|
|
from django.http import Http404
|
|
|
|
def _lazy_load(fn):
|
|
_cached = []
|
|
def _decorated():
|
|
if not _cached:
|
|
_cached.append(fn())
|
|
return _cached[0]
|
|
return _decorated
|
|
|
|
|
|
@_lazy_load
|
|
def _get_sendfile():
|
|
from django.utils.importlib import import_module
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
backend = getattr(settings, 'SENDFILE_BACKEND', None)
|
|
if not backend:
|
|
raise ImproperlyConfigured('You must specify a valued for SENDFILE_BACKEND')
|
|
module = import_module(backend)
|
|
return module.sendfile
|
|
|
|
|
|
|
|
def sendfile(request, filename, attachment=False, attachment_filename=None):
|
|
'''
|
|
create a response to send file using backend configured in SENDFILE_BACKEND
|
|
|
|
if attachment is True the content-disposition header will be set with either
|
|
the filename given or else the attachment_filename (of specified). This
|
|
will typically prompt the user to download the file, rather than view it.
|
|
'''
|
|
_sendfile = _get_sendfile()
|
|
|
|
if not os.path.exists(filename):
|
|
raise Http404('"%s" does not exist' % filename)
|
|
|
|
mimetype, encoding = guess_type(filename)
|
|
if mimetype is None:
|
|
mimetype = 'application/octet-stream'
|
|
|
|
response = _sendfile(request, filename, mimetype=mimetype)
|
|
if attachment:
|
|
attachment_filename = attachment_filename or os.path.basename(filename)
|
|
response['Content-Disposition'] = 'attachment; filename=%s' % attachment_filename
|
|
|
|
response['Content-length'] = os.path.getsize(filename)
|
|
response['Content-Type'] = mimetype
|
|
if encoding:
|
|
response['Content-Encoding'] = encoding
|
|
|
|
return response
|