Buckets:
| """ | |
| Views and functions for serving static files. These are only to be used | |
| during development, and SHOULD NOT be used in a production setting. | |
| """ | |
| import mimetypes | |
| import posixpath | |
| from pathlib import Path | |
| 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.translation import gettext as _ | |
| from django.utils.translation import gettext_lazy | |
| def builtin_template_path(name): | |
| """ | |
| Return a path to a builtin template. | |
| Avoid calling this function at the module level or in a class-definition | |
| because __file__ may not exist, e.g. in frozen environments. | |
| """ | |
| return Path(__file__).parent / "templates" / name | |
| 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 | |
| path('<path: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(path).lstrip("/") | |
| fullpath = Path(safe_join(document_root, path)) | |
| if fullpath.is_dir(): | |
| if show_indexes: | |
| return directory_index(path, fullpath) | |
| raise Http404(_("Directory indexes are not allowed here.")) | |
| if not fullpath.exists(): | |
| raise Http404(_("“%(path)s” does not exist") % {"path": fullpath}) | |
| # Respect the If-Modified-Since header. | |
| statobj = fullpath.stat() | |
| if not was_modified_since( | |
| request.META.get("HTTP_IF_MODIFIED_SINCE"), statobj.st_mtime | |
| ): | |
| return HttpResponseNotModified() | |
| content_type, encoding = mimetypes.guess_type(str(fullpath)) | |
| content_type = content_type or "application/octet-stream" | |
| response = FileResponse(fullpath.open("rb"), content_type=content_type) | |
| response.headers["Last-Modified"] = http_date(statobj.st_mtime) | |
| if encoding: | |
| response.headers["Content-Encoding"] = encoding | |
| return response | |
| # Translatable string for static directory index template title. | |
| template_translatable = gettext_lazy("Index of %(directory)s") | |
| def directory_index(path, fullpath): | |
| try: | |
| t = loader.select_template( | |
| [ | |
| "static/directory_index.html", | |
| "static/directory_index", | |
| ] | |
| ) | |
| except TemplateDoesNotExist: | |
| with builtin_template_path("directory_index.html").open(encoding="utf-8") as fh: | |
| t = Engine(libraries={"i18n": "django.templatetags.i18n"}).from_string( | |
| fh.read() | |
| ) | |
| c = Context() | |
| else: | |
| c = {} | |
| files = [] | |
| for f in fullpath.iterdir(): | |
| if not f.name.startswith("."): | |
| url = str(f.relative_to(fullpath)) | |
| if f.is_dir(): | |
| url += "/" | |
| files.append(url) | |
| c.update( | |
| { | |
| "directory": path + "/", | |
| "file_list": files, | |
| } | |
| ) | |
| return HttpResponse(t.render(c)) | |
| def was_modified_since(header=None, mtime=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. | |
| """ | |
| try: | |
| if header is None: | |
| raise ValueError | |
| header_mtime = parse_http_date(header) | |
| if int(mtime) > header_mtime: | |
| raise ValueError | |
| except (ValueError, OverflowError): | |
| return True | |
| return False | |
Xet Storage Details
- Size:
- 4.05 kB
- Xet hash:
- 4644fef5f80a88f18f091ba286d1ca4beb70b2f145134db800a92893c4a804e5
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.