Added 3rd party sendfile app
This commit is contained in:
51
3rd_party_apps/sendfile/__init__.py
Normal file
51
3rd_party_apps/sendfile/__init__.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
VERSION = (0, 1, 1)
|
||||||
|
__version__ = '.'.join(map(str, VERSION))
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
from mimetypes import guess_type
|
||||||
|
|
||||||
|
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', 'sendfile.backends.simple')
|
||||||
|
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()
|
||||||
|
response = _sendfile(request, filename)
|
||||||
|
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)
|
||||||
|
|
||||||
|
content_type = guess_type(filename)[0]
|
||||||
|
if content_type is None:
|
||||||
|
content_type = "application/octet-stream"
|
||||||
|
response['Content-Type'] = content_type
|
||||||
|
|
||||||
|
return response
|
||||||
0
3rd_party_apps/sendfile/backends/__init__.py
Normal file
0
3rd_party_apps/sendfile/backends/__init__.py
Normal file
13
3rd_party_apps/sendfile/backends/chunked_file.py
Normal file
13
3rd_party_apps/sendfile/backends/chunked_file.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from django.http import HttpResponse
|
||||||
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
|
||||||
|
def sendfile(request, filename):
|
||||||
|
return = HttpResponse(IterFile(filename))
|
||||||
|
|
||||||
|
class IterFile(object):
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.file = SimpleUploadedFile(name=filename, content=open(filename).read())
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self.file.chunks()
|
||||||
|
|
||||||
15
3rd_party_apps/sendfile/backends/development.py
Normal file
15
3rd_party_apps/sendfile/backends/development.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from django.views.static import serve
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
def sendfile(request, filename):
|
||||||
|
'''
|
||||||
|
Send file using django dev static file server.
|
||||||
|
|
||||||
|
DO NOT USE IN PRODUCTION
|
||||||
|
this is only to be used when developing and is provided
|
||||||
|
for convenience only
|
||||||
|
'''
|
||||||
|
dirname = os.path.dirname(filename)
|
||||||
|
basename = os.path.basename(filename)
|
||||||
|
return serve(request, basename, dirname)
|
||||||
30
3rd_party_apps/sendfile/backends/mod_wsgi.py
Normal file
30
3rd_party_apps/sendfile/backends/mod_wsgi.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
def _convert_file_to_url(filename):
|
||||||
|
# CURRENTLY NOT WORKING
|
||||||
|
# mod_wsgi wants a relative URL not a filename
|
||||||
|
# so apache does an internal redirect
|
||||||
|
|
||||||
|
relpath = os.path.relpath(filename, settings.SENDFILE_ROOT)
|
||||||
|
|
||||||
|
url = [settings.SENDFILE_URL]
|
||||||
|
|
||||||
|
while relpath:
|
||||||
|
relpath, head = os.path.split(relpath)
|
||||||
|
url.insert(1, head)
|
||||||
|
|
||||||
|
return u''.join(url)
|
||||||
|
|
||||||
|
def sendfile(request, filename):
|
||||||
|
response = HttpResponse()
|
||||||
|
response['Location'] = _convert_file_to_url(filename)
|
||||||
|
# need to destroy get_host() to stop django
|
||||||
|
# rewriting our location to include http, so that
|
||||||
|
# mod_wsgi is able to do the internal redirect
|
||||||
|
request.get_host = lambda: ''
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
6
3rd_party_apps/sendfile/backends/simple.py
Normal file
6
3rd_party_apps/sendfile/backends/simple.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.core.servers.basehttp import FileWrapper
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
def sendfile(request, filename):
|
||||||
|
wrapper = FileWrapper(file(filename))
|
||||||
|
return HttpResponse(wrapper)
|
||||||
8
3rd_party_apps/sendfile/backends/xsendfile.py
Normal file
8
3rd_party_apps/sendfile/backends/xsendfile.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
def sendfile(request, filename):
|
||||||
|
response = HttpResponse()
|
||||||
|
response['X-Sendfile'] = filename
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
Reference in New Issue
Block a user