Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: SmileyChris/django-old
...
head fork: SmileyChris/django-old
  • 2 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
54 django/contrib/staticfiles/finders.py
View
@@ -36,6 +36,13 @@ def list(self, ignore_patterns=[]):
"""
raise NotImplementedError()
+ def listdir(self, path):
+ """
+ List a path's contents returning a 2-tuple of lists; the first list
+ being directories, the second list being files.
+ """
+ raise NotImplementedError()
+
class FileSystemFinder(BaseFinder):
"""
@@ -96,6 +103,17 @@ def list(self, ignore_patterns):
for path in utils.get_files(storage, ignore_patterns):
yield path, prefix, storage
+ def listdir(self, path):
+ """
+ List all files and dirs for one path.
+ """
+ dirs, files = [], []
+ for prefix, root in self.locations:
+ partial_listdir = utils.storage_listdir(self.storages[root],
+ path, prefix)
+ utils.combine_listdir(dirs, files, partial_listdir)
+ return dirs, files
+
class AppDirectoriesFinder(BaseFinder):
"""
@@ -124,6 +142,17 @@ def list(self, ignore_patterns):
for path in utils.get_files(storage, ignore_patterns):
yield path, prefix, storage
+ def listdir(self, path):
+ """
+ List all files and dirs in all app storages (for one path).
+ """
+ dirs, files = [], []
+ for storage in self.storages.itervalues():
+ partial_listdir = utils.storage_listdir(storage, path,
+ storage.get_prefix())
+ utils.combine_listdir(dirs, files, partial_listdir)
+ return dirs, files
+
def find(self, path, all=False):
"""
Looks for files in the app directories.
@@ -197,6 +226,17 @@ def list(self, ignore_patterns):
for path in utils.get_files(self.storage, ignore_patterns):
yield path, '', self.storage
+ def listdir(self, path):
+ """
+ List all files and dirs in all app storages (for one path).
+ """
+ dirs, files = [], []
+ for storage in self.storages.itervalues():
+ if storage.exists(''): # check if storage location exists
+ utils.combine_listdir(dirs, files, storage.listdir(path))
+ return dirs, files
+
+
class DefaultStorageFinder(BaseStorageFinder):
"""
A static files finder that uses the default storage backend.
@@ -230,10 +270,24 @@ def find(path, all=False):
# No match.
return all and [] or None
+
+def listdir(path):
+ """
+ Find all files and directories in a given path across all finders.
+
+ Returns a 2-tuple containing a list of directories and
+ """
+ dirs, files = [], []
+ for finder in get_finders():
+ utils.combine_listdir(dirs, files, finder.listdir(path))
+ return dirs, files
+
+
def get_finders():
for finder_path in settings.STATICFILES_FINDERS:
yield get_finder(finder_path)
+
def _get_finder(import_path):
"""
Imports the message storage class described by import_path, where
12 django/contrib/staticfiles/handlers.py
View
@@ -13,6 +13,8 @@ class StaticFilesHandler(WSGIHandler):
WSGI middleware that intercepts calls to the static files directory, as
defined by the STATIC_URL setting, and serves those files.
"""
+ show_indexes = False
+
def __init__(self, application, base_dir=None):
self.application = application
if base_dir:
@@ -41,8 +43,7 @@ def _should_handle(self, path):
* the host is provided as part of the base_url
* the request's path isn't under the media path (or equal)
"""
- return (self.base_url[2] != path and
- path.startswith(self.base_url[2]) and not self.base_url[1])
+ return (path.startswith(self.base_url[2]) and not self.base_url[1])
def file_path(self, url):
"""
@@ -55,7 +56,12 @@ def serve(self, request):
"""
Actually serves the request path.
"""
- return serve(request, self.file_path(request.path), insecure=True)
+ if self.show_indexes:
+ kwargs = dict(show_indexes=True, index_prefix=self.base_url[2])
+ else:
+ kwargs = {}
+ return serve(request, self.file_path(request.path), insecure=True,
+ **kwargs)
def get_response(self, request):
from django.http import Http404
3  django/contrib/staticfiles/management/commands/runserver.py
View
@@ -11,6 +11,8 @@ class Command(BaseRunserverCommand):
help='Tells Django to NOT automatically serve static files at STATIC_URL.'),
make_option('--insecure', action="store_true", dest='insecure_serving', default=False,
help='Allows serving static files even if DEBUG is False.'),
+ make_option('--show-indexes', action="store_true",
+ help='Show static directory indexes.'),
)
help = "Starts a lightweight Web server for development, including static files serving."
@@ -24,4 +26,5 @@ def get_handler(self, *args, **options):
if (settings.DEBUG and use_static_handler or
(use_static_handler and insecure_serving)):
handler = StaticFilesHandler(handler)
+ handler.show_indexes = options.get('show_indexes')
return handler
4 django/contrib/staticfiles/urls.py
View
@@ -25,4 +25,6 @@ def staticfiles_urlpatterns(prefix=None):
if prefix.startswith("/"):
prefix = prefix[1:]
return patterns('',
- url(r'^%s' % re.escape(prefix), include(urlpatterns)),)
+ url(r'^(?P<index_prefix>%s)' % re.escape(prefix),
+ include(urlpatterns), {'show_indexes': True}),
+ )
29 django/contrib/staticfiles/utils.py
View
@@ -2,6 +2,7 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
+
def get_files(storage, ignore_patterns=[], location=''):
"""
Recursively walk the storage directories gathering a complete list of files
@@ -31,6 +32,7 @@ def is_ignored(path):
static_files.extend(get_files(storage, ignore_patterns, dir))
return static_files
+
def check_settings():
"""
Checks if the MEDIA_(ROOT|URL) and STATIC_(ROOT|URL)
@@ -43,3 +45,30 @@ def check_settings():
(settings.MEDIA_ROOT == settings.STATIC_ROOT)):
raise ImproperlyConfigured("The MEDIA_ROOT and STATIC_ROOT "
"settings must have different values")
+
+
+def combine_listdir(all_dirs, all_files, partial_listdir):
+ """
+ Combines a 2-tuple containing a list of directories and a list files into
+ master lists of directories and files.
+ """
+ dirs, files = partial_listdir
+ for dir in dirs:
+ if dir not in all_dirs:
+ all_dirs.append(dir)
+ for file in files:
+ if file not in all_files:
+ all_files.append(file)
+
+
+def storage_listdir(storage, path, prefix=None):
+ if prefix:
+ prefix += '/'
+ if not path.startswith(prefix):
+ return [], []
+ else:
+ prefix = ''
+ path = path[len(prefix):]
+ if not storage.exists(path):
+ return [], []
+ return storage.listdir(path)
67 django/contrib/staticfiles/views.py
View
@@ -17,10 +17,11 @@
from django.template import loader, Template, Context, TemplateDoesNotExist
from django.utils.http import http_date
-from django.contrib.staticfiles import finders, utils
+from django.contrib.staticfiles import finders
-def serve(request, path, document_root=None, show_indexes=False, insecure=False):
+def serve(request, path, document_root=None, show_indexes=False,
+ insecure=False, index_prefix=None):
"""
Serve static files below a given point in the directory structure or
from locations inferred from the static files finders.
@@ -34,23 +35,25 @@ def serve(request, path, document_root=None, show_indexes=False, insecure=False)
If you provide the ``document_root`` parameter, the file won't be looked
up with the staticfiles finders, but in the given filesystem path, e.g.::
- (r'^(?P<path>.*)$', 'django.contrib.staticfiles.views.serve', {'document_root' : '/path/to/my/files/'})
+ (r'^(?P<path>.*)$', 'django.contrib.staticfiles.views.serve',
+ {'document_root' : '/path/to/my/files/'})
You may also set ``show_indexes`` to ``True`` if you'd like to serve a
- basic index of the directory. This index view will use the
- template hardcoded below, but if you'd like to override it, you can create
- a template called ``static/directory_index.html``.
+ basic index of the directory. This index view will use the template
+ hardcoded below, but if you'd like to override it, you can create a
+ template called ``static/directory_index.html``. Use the ``index_prefix``
+ argument to display the correct full path in indexes, for example::
+
+ (r'^(?P<index_prefix>static/)(?P<path>.*)$',
+ 'django.contrib.staticfiles.views.serve', {'show_indexes': True})
"""
+ print 't', path
if not settings.DEBUG and not insecure:
raise ImproperlyConfigured("The view to serve static files can only "
"be used if the DEBUG setting is True or "
"the --insecure option of 'runserver' is "
"used")
- if not document_root:
- absolute_path = finders.find(path)
- if not absolute_path:
- raise Http404('"%s" could not be found' % path)
- document_root, path = os.path.split(absolute_path)
+ use_finders = not document_root
# Clean up given path to only allow serving files below document_root.
path = posixpath.normpath(urllib.unquote(path))
path = path.lstrip('/')
@@ -67,10 +70,17 @@ def serve(request, path, document_root=None, show_indexes=False, insecure=False)
newpath = os.path.join(newpath, part).replace('\\', '/')
if newpath and path != newpath:
return HttpResponseRedirect(newpath)
- fullpath = os.path.join(document_root, newpath)
+ if use_finders:
+ fullpath = finders.find(path)
+ else:
+ fullpath = os.path.join(document_root, newpath)
+ if not fullpath:
+ raise Http404('"%s" could not be found' % newpath)
if os.path.isdir(fullpath):
if show_indexes:
- return directory_index(newpath, fullpath)
+ if use_finders:
+ fullpath = None
+ return directory_index(newpath, fullpath, index_prefix)
raise Http404("Directory indexes are not allowed here.")
if not os.path.exists(fullpath):
raise Http404('"%s" does not exist' % fullpath)
@@ -113,21 +123,34 @@ def serve(request, path, document_root=None, show_indexes=False, insecure=False)
</html>
"""
-def directory_index(path, fullpath):
+def directory_index(path, fullpath=None, prefix=None):
try:
t = loader.select_template(['static/directory_index.html',
'static/directory_index'])
except TemplateDoesNotExist:
- t = Template(DEFAULT_DIRECTORY_INDEX_TEMPLATE, name='Default directory index template')
- files = []
- for f in os.listdir(fullpath):
- if not f.startswith('.'):
+ t = Template(DEFAULT_DIRECTORY_INDEX_TEMPLATE,
+ name='Default directory index template')
+ if fullpath is None:
+ dirs, files = finders.listdir(path)
+ else:
+ files = []
+ dirs = []
+ for f in os.listdir(fullpath):
if os.path.isdir(os.path.join(fullpath, f)):
- f += '/'
- files.append(f)
+ dirs.append('%s/' % f)
+ else:
+ files.append(f)
+ dirs = ['%s/' % f for f in dirs if not f.startswith('.')]
+ files = [f for f in files if not f.startswith('.')]
+ dirs.sort()
+ files.sort()
+
+ directory = '%s%s' % (prefix or '', path)
+ if not directory.endswith('/'):
+ directory = '%s/' % directory
c = Context({
- 'directory' : path + '/',
- 'file_list' : files,
+ 'directory' : directory,
+ 'file_list' : dirs + files,
})
return HttpResponse(t.render(c))

No commit comments for this range

Something went wrong with that request. Please try again.