2010-10-20 09:33:24 +08:00
|
|
|
import urllib
|
|
|
|
from urlparse import urlparse
|
|
|
|
|
2010-11-12 05:43:49 +08:00
|
|
|
from django.conf import settings
|
|
|
|
from django.core.handlers.wsgi import WSGIHandler
|
2010-10-20 09:33:24 +08:00
|
|
|
|
2010-11-12 05:43:49 +08:00
|
|
|
from django.contrib.staticfiles import utils
|
2010-10-20 09:33:24 +08:00
|
|
|
from django.contrib.staticfiles.views import serve
|
|
|
|
|
|
|
|
class StaticFilesHandler(WSGIHandler):
|
|
|
|
"""
|
|
|
|
WSGI middleware that intercepts calls to the static files directory, as
|
2010-11-17 23:36:26 +08:00
|
|
|
defined by the STATIC_URL setting, and serves those files.
|
2010-10-20 09:33:24 +08:00
|
|
|
"""
|
2010-11-17 23:36:26 +08:00
|
|
|
def __init__(self, application, base_dir=None):
|
2010-10-20 09:33:24 +08:00
|
|
|
self.application = application
|
2010-11-17 23:36:26 +08:00
|
|
|
if base_dir:
|
|
|
|
self.base_dir = base_dir
|
2010-10-20 09:33:24 +08:00
|
|
|
else:
|
2010-11-17 23:36:26 +08:00
|
|
|
self.base_dir = self.get_base_dir()
|
|
|
|
self.base_url = urlparse(self.get_base_url())
|
2010-11-12 05:43:49 +08:00
|
|
|
super(StaticFilesHandler, self).__init__()
|
2010-10-20 09:33:24 +08:00
|
|
|
|
2010-11-17 23:36:26 +08:00
|
|
|
def get_base_dir(self):
|
|
|
|
return settings.STATIC_ROOT
|
2010-10-20 09:33:24 +08:00
|
|
|
|
2010-11-17 23:36:26 +08:00
|
|
|
def get_base_url(self):
|
|
|
|
if settings.DEBUG:
|
|
|
|
utils.check_settings()
|
|
|
|
return settings.STATIC_URL
|
2010-10-20 09:33:24 +08:00
|
|
|
|
2010-11-12 05:43:49 +08:00
|
|
|
def _should_handle(self, path):
|
|
|
|
"""
|
|
|
|
Checks if the path should be handled. Ignores the path if:
|
|
|
|
|
2010-11-17 23:36:26 +08:00
|
|
|
* the host is provided as part of the base_url
|
2010-11-12 05:43:49 +08:00
|
|
|
* the request's path isn't under the media path (or equal)
|
|
|
|
"""
|
2010-11-17 23:36:26 +08:00
|
|
|
return (self.base_url[2] != path and
|
|
|
|
path.startswith(self.base_url[2]) and not self.base_url[1])
|
2010-11-12 05:43:49 +08:00
|
|
|
|
2010-10-20 09:33:24 +08:00
|
|
|
def file_path(self, url):
|
|
|
|
"""
|
|
|
|
Returns the relative path to the media file on disk for the given URL.
|
|
|
|
|
2010-11-17 23:36:26 +08:00
|
|
|
The passed URL is assumed to begin with ``base_url``. If the
|
2010-10-20 09:33:24 +08:00
|
|
|
resultant file path is outside the media directory, then a ValueError
|
|
|
|
is raised.
|
|
|
|
"""
|
2010-11-17 23:36:26 +08:00
|
|
|
relative_url = url[len(self.base_url[2]):]
|
2010-10-20 09:33:24 +08:00
|
|
|
return urllib.url2pathname(relative_url)
|
|
|
|
|
2010-11-12 05:43:49 +08:00
|
|
|
def serve(self, request):
|
|
|
|
"""
|
|
|
|
Actually serves the request path.
|
|
|
|
"""
|
|
|
|
return serve(request, self.file_path(request.path), insecure=True)
|
|
|
|
|
|
|
|
def get_response(self, request):
|
|
|
|
from django.http import Http404
|
|
|
|
|
|
|
|
if self._should_handle(request.path):
|
|
|
|
try:
|
|
|
|
return self.serve(request)
|
|
|
|
except Http404, e:
|
|
|
|
if settings.DEBUG:
|
|
|
|
from django.views import debug
|
|
|
|
return debug.technical_404_response(request, e)
|
|
|
|
return super(StaticFilesHandler, self).get_response(request)
|
2010-10-20 09:33:24 +08:00
|
|
|
|
|
|
|
def __call__(self, environ, start_response):
|
2010-11-12 05:43:49 +08:00
|
|
|
if not self._should_handle(environ['PATH_INFO']):
|
2010-10-20 09:33:24 +08:00
|
|
|
return self.application(environ, start_response)
|
2010-11-12 05:43:49 +08:00
|
|
|
return super(StaticFilesHandler, self).__call__(environ, start_response)
|