Index: venv/Lib/site-packages/django/views/static.py |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/venv/Lib/site-packages/django/views/static.py |
@@ -0,0 +1,140 @@ |
+""" |
+Views and functions for serving static files. These are only to be used |
+during development, and SHOULD NOT be used in a production setting. |
+""" |
+from __future__ import unicode_literals |
+ |
+import mimetypes |
+import os |
+import posixpath |
+import re |
+import stat |
+ |
+from django.http import ( |
+ FileResponse, Http404, HttpResponse, HttpResponseNotModified, |
+) |
+from django.template import Context, Engine, TemplateDoesNotExist, loader |
+from django.utils._os import safe_join |
+from django.utils.http import http_date, parse_http_date |
+from django.utils.six.moves.urllib.parse import unquote |
+from django.utils.translation import ugettext as _, ugettext_lazy |
+ |
+ |
+def serve(request, path, document_root=None, show_indexes=False): |
+ """ |
+ Serve static files below a given point in the directory structure. |
+ |
+ To use, put a URL pattern such as:: |
+ |
+ from django.views.static import serve |
+ |
+ url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'}) |
+ |
+ in your URLconf. You must provide the ``document_root`` param. 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``. |
+ """ |
+ path = posixpath.normpath(unquote(path)).lstrip('/') |
+ fullpath = safe_join(document_root, path) |
+ if os.path.isdir(fullpath): |
+ if show_indexes: |
+ return directory_index(path, fullpath) |
+ raise Http404(_("Directory indexes are not allowed here.")) |
+ if not os.path.exists(fullpath): |
+ raise Http404(_('"%(path)s" does not exist') % {'path': fullpath}) |
+ # Respect the If-Modified-Since header. |
+ statobj = os.stat(fullpath) |
+ if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'), |
+ statobj.st_mtime, statobj.st_size): |
+ return HttpResponseNotModified() |
+ content_type, encoding = mimetypes.guess_type(fullpath) |
+ content_type = content_type or 'application/octet-stream' |
+ response = FileResponse(open(fullpath, 'rb'), content_type=content_type) |
+ response["Last-Modified"] = http_date(statobj.st_mtime) |
+ if stat.S_ISREG(statobj.st_mode): |
+ response["Content-Length"] = statobj.st_size |
+ if encoding: |
+ response["Content-Encoding"] = encoding |
+ return response |
+ |
+ |
+DEFAULT_DIRECTORY_INDEX_TEMPLATE = """ |
+{% load i18n %} |
+<!DOCTYPE html> |
+<html lang="en"> |
+ <head> |
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> |
+ <meta http-equiv="Content-Language" content="en-us" /> |
+ <meta name="robots" content="NONE,NOARCHIVE" /> |
+ <title>{% blocktrans %}Index of {{ directory }}{% endblocktrans %}</title> |
+ </head> |
+ <body> |
+ <h1>{% blocktrans %}Index of {{ directory }}{% endblocktrans %}</h1> |
+ <ul> |
+ {% if directory != "/" %} |
+ <li><a href="../">../</a></li> |
+ {% endif %} |
+ {% for f in file_list %} |
+ <li><a href="{{ f|urlencode }}">{{ f }}</a></li> |
+ {% endfor %} |
+ </ul> |
+ </body> |
+</html> |
+""" |
+template_translatable = ugettext_lazy("Index of %(directory)s") |
+ |
+ |
+def directory_index(path, fullpath): |
+ try: |
+ t = loader.select_template([ |
+ 'static/directory_index.html', |
+ 'static/directory_index', |
+ ]) |
+ except TemplateDoesNotExist: |
+ t = Engine(libraries={'i18n': 'django.templatetags.i18n'}).from_string(DEFAULT_DIRECTORY_INDEX_TEMPLATE) |
+ c = Context() |
+ else: |
+ c = {} |
+ files = [] |
+ for f in os.listdir(fullpath): |
+ if not f.startswith('.'): |
+ if os.path.isdir(os.path.join(fullpath, f)): |
+ f += '/' |
+ files.append(f) |
+ c.update({ |
+ 'directory': path + '/', |
+ 'file_list': files, |
+ }) |
+ return HttpResponse(t.render(c)) |
+ |
+ |
+def was_modified_since(header=None, mtime=0, size=0): |
+ """ |
+ Was something modified since the user last downloaded it? |
+ |
+ header |
+ This is the value of the If-Modified-Since header. If this is None, |
+ I'll just return True. |
+ |
+ mtime |
+ This is the modification time of the item we're talking about. |
+ |
+ size |
+ This is the size of the item we're talking about. |
+ """ |
+ try: |
+ if header is None: |
+ raise ValueError |
+ matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header, |
+ re.IGNORECASE) |
+ header_mtime = parse_http_date(matches.group(1)) |
+ header_len = matches.group(3) |
+ if header_len and int(header_len) != size: |
+ raise ValueError |
+ if int(mtime) > header_mtime: |
+ raise ValueError |
+ except (AttributeError, ValueError, OverflowError): |
+ return True |
+ return False |