docker setup

This commit is contained in:
AdrienLSH
2023-11-23 16:43:30 +01:00
parent fd19180e1d
commit f29003c66a
5410 changed files with 869440 additions and 0 deletions

View File

@ -0,0 +1,80 @@
from django.core.exceptions import ImproperlyConfigured, SuspiciousFileOperation
from django.template.utils import get_app_template_dirs
from django.utils._os import safe_join
from django.utils.functional import cached_property
class BaseEngine:
# Core methods: engines have to provide their own implementation
# (except for from_string which is optional).
def __init__(self, params):
"""
Initialize the template engine.
`params` is a dict of configuration settings.
"""
params = params.copy()
self.name = params.pop("NAME")
self.dirs = list(params.pop("DIRS"))
self.app_dirs = params.pop("APP_DIRS")
if params:
raise ImproperlyConfigured(
"Unknown parameters: {}".format(", ".join(params))
)
@property
def app_dirname(self):
raise ImproperlyConfigured(
"{} doesn't support loading templates from installed "
"applications.".format(self.__class__.__name__)
)
def from_string(self, template_code):
"""
Create and return a template for the given source code.
This method is optional.
"""
raise NotImplementedError(
"subclasses of BaseEngine should provide a from_string() method"
)
def get_template(self, template_name):
"""
Load and return a template for the given name.
Raise TemplateDoesNotExist if no such template exists.
"""
raise NotImplementedError(
"subclasses of BaseEngine must provide a get_template() method"
)
# Utility methods: they are provided to minimize code duplication and
# security issues in third-party backends.
@cached_property
def template_dirs(self):
"""
Return a list of directories to search for templates.
"""
# Immutable return value because it's cached and shared by callers.
template_dirs = tuple(self.dirs)
if self.app_dirs:
template_dirs += get_app_template_dirs(self.app_dirname)
return template_dirs
def iter_template_filenames(self, template_name):
"""
Iterate over candidate files for template_name.
Ignore files that don't lie inside configured template dirs to avoid
directory traversal attacks.
"""
for template_dir in self.template_dirs:
try:
yield safe_join(template_dir, template_name)
except SuspiciousFileOperation:
# The joined path was located outside of this template_dir
# (it might be inside another one, so this isn't fatal).
pass

View File

@ -0,0 +1,136 @@
from importlib import import_module
from pkgutil import walk_packages
from django.apps import apps
from django.conf import settings
from django.template import TemplateDoesNotExist
from django.template.context import make_context
from django.template.engine import Engine
from django.template.library import InvalidTemplateLibrary
from .base import BaseEngine
class DjangoTemplates(BaseEngine):
app_dirname = "templates"
def __init__(self, params):
params = params.copy()
options = params.pop("OPTIONS").copy()
options.setdefault("autoescape", True)
options.setdefault("debug", settings.DEBUG)
options.setdefault("file_charset", "utf-8")
libraries = options.get("libraries", {})
options["libraries"] = self.get_templatetag_libraries(libraries)
super().__init__(params)
self.engine = Engine(self.dirs, self.app_dirs, **options)
def from_string(self, template_code):
return Template(self.engine.from_string(template_code), self)
def get_template(self, template_name):
try:
return Template(self.engine.get_template(template_name), self)
except TemplateDoesNotExist as exc:
reraise(exc, self)
def get_templatetag_libraries(self, custom_libraries):
"""
Return a collation of template tag libraries from installed
applications and the supplied custom_libraries argument.
"""
libraries = get_installed_libraries()
libraries.update(custom_libraries)
return libraries
class Template:
def __init__(self, template, backend):
self.template = template
self.backend = backend
@property
def origin(self):
return self.template.origin
def render(self, context=None, request=None):
context = make_context(
context, request, autoescape=self.backend.engine.autoescape
)
try:
return self.template.render(context)
except TemplateDoesNotExist as exc:
reraise(exc, self.backend)
def copy_exception(exc, backend=None):
"""
Create a new TemplateDoesNotExist. Preserve its declared attributes and
template debug data but discard __traceback__, __context__, and __cause__
to make this object suitable for keeping around (in a cache, for example).
"""
backend = backend or exc.backend
new = exc.__class__(*exc.args, tried=exc.tried, backend=backend, chain=exc.chain)
if hasattr(exc, "template_debug"):
new.template_debug = exc.template_debug
return new
def reraise(exc, backend):
"""
Reraise TemplateDoesNotExist while maintaining template debug information.
"""
new = copy_exception(exc, backend)
raise new from exc
def get_template_tag_modules():
"""
Yield (module_name, module_path) pairs for all installed template tag
libraries.
"""
candidates = ["django.templatetags"]
candidates.extend(
f"{app_config.name}.templatetags" for app_config in apps.get_app_configs()
)
for candidate in candidates:
try:
pkg = import_module(candidate)
except ImportError:
# No templatetags package defined. This is safe to ignore.
continue
if hasattr(pkg, "__path__"):
for name in get_package_libraries(pkg):
yield name[len(candidate) + 1 :], name
def get_installed_libraries():
"""
Return the built-in template tag libraries and those from installed
applications. Libraries are stored in a dictionary where keys are the
individual module names, not the full module paths. Example:
django.templatetags.i18n is stored as i18n.
"""
return {
module_name: full_name for module_name, full_name in get_template_tag_modules()
}
def get_package_libraries(pkg):
"""
Recursively yield template tag libraries defined in submodules of a
package.
"""
for entry in walk_packages(pkg.__path__, pkg.__name__ + "."):
try:
module = import_module(entry[1])
except ImportError as e:
raise InvalidTemplateLibrary(
"Invalid template library specified. ImportError raised when "
"trying to load '%s': %s" % (entry[1], e)
) from e
if hasattr(module, "register"):
yield entry[1]

View File

@ -0,0 +1,51 @@
import string
from django.core.exceptions import ImproperlyConfigured
from django.template import Origin, TemplateDoesNotExist
from django.utils.html import conditional_escape
from .base import BaseEngine
from .utils import csrf_input_lazy, csrf_token_lazy
class TemplateStrings(BaseEngine):
app_dirname = "template_strings"
def __init__(self, params):
params = params.copy()
options = params.pop("OPTIONS").copy()
if options:
raise ImproperlyConfigured("Unknown options: {}".format(", ".join(options)))
super().__init__(params)
def from_string(self, template_code):
return Template(template_code)
def get_template(self, template_name):
tried = []
for template_file in self.iter_template_filenames(template_name):
try:
with open(template_file, encoding="utf-8") as fp:
template_code = fp.read()
except FileNotFoundError:
tried.append(
(
Origin(template_file, template_name, self),
"Source does not exist",
)
)
else:
return Template(template_code)
raise TemplateDoesNotExist(template_name, tried=tried, backend=self)
class Template(string.Template):
def render(self, context=None, request=None):
if context is None:
context = {}
else:
context = {k: conditional_escape(v) for k, v in context.items()}
if request is not None:
context["csrf_input"] = csrf_input_lazy(request)
context["csrf_token"] = csrf_token_lazy(request)
return self.safe_substitute(context)

View File

@ -0,0 +1,125 @@
from pathlib import Path
import jinja2
from django.conf import settings
from django.template import TemplateDoesNotExist, TemplateSyntaxError
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
from .base import BaseEngine
from .utils import csrf_input_lazy, csrf_token_lazy
class Jinja2(BaseEngine):
app_dirname = "jinja2"
def __init__(self, params):
params = params.copy()
options = params.pop("OPTIONS").copy()
super().__init__(params)
self.context_processors = options.pop("context_processors", [])
environment = options.pop("environment", "jinja2.Environment")
environment_cls = import_string(environment)
if "loader" not in options:
options["loader"] = jinja2.FileSystemLoader(self.template_dirs)
options.setdefault("autoescape", True)
options.setdefault("auto_reload", settings.DEBUG)
options.setdefault(
"undefined", jinja2.DebugUndefined if settings.DEBUG else jinja2.Undefined
)
self.env = environment_cls(**options)
def from_string(self, template_code):
return Template(self.env.from_string(template_code), self)
def get_template(self, template_name):
try:
return Template(self.env.get_template(template_name), self)
except jinja2.TemplateNotFound as exc:
raise TemplateDoesNotExist(exc.name, backend=self) from exc
except jinja2.TemplateSyntaxError as exc:
new = TemplateSyntaxError(exc.args)
new.template_debug = get_exception_info(exc)
raise new from exc
@cached_property
def template_context_processors(self):
return [import_string(path) for path in self.context_processors]
class Template:
def __init__(self, template, backend):
self.template = template
self.backend = backend
self.origin = Origin(
name=template.filename,
template_name=template.name,
)
def render(self, context=None, request=None):
if context is None:
context = {}
if request is not None:
context["request"] = request
context["csrf_input"] = csrf_input_lazy(request)
context["csrf_token"] = csrf_token_lazy(request)
for context_processor in self.backend.template_context_processors:
context.update(context_processor(request))
try:
return self.template.render(context)
except jinja2.TemplateSyntaxError as exc:
new = TemplateSyntaxError(exc.args)
new.template_debug = get_exception_info(exc)
raise new from exc
class Origin:
"""
A container to hold debug information as described in the template API
documentation.
"""
def __init__(self, name, template_name):
self.name = name
self.template_name = template_name
def get_exception_info(exception):
"""
Format exception information for display on the debug page using the
structure described in the template API documentation.
"""
context_lines = 10
lineno = exception.lineno
source = exception.source
if source is None:
exception_file = Path(exception.filename)
if exception_file.exists():
source = exception_file.read_text()
if source is not None:
lines = list(enumerate(source.strip().split("\n"), start=1))
during = lines[lineno - 1][1]
total = len(lines)
top = max(0, lineno - context_lines - 1)
bottom = min(total, lineno + context_lines)
else:
during = ""
lines = []
total = top = bottom = 0
return {
"name": exception.filename,
"message": exception.message,
"source_lines": lines[top:bottom],
"line": lineno,
"before": "",
"during": during,
"after": "",
"total": total,
"top": top,
"bottom": bottom,
}

View File

@ -0,0 +1,15 @@
from django.middleware.csrf import get_token
from django.utils.functional import lazy
from django.utils.html import format_html
from django.utils.safestring import SafeString
def csrf_input(request):
return format_html(
'<input type="hidden" name="csrfmiddlewaretoken" value="{}">',
get_token(request),
)
csrf_input_lazy = lazy(csrf_input, SafeString, str)
csrf_token_lazy = lazy(get_token, str)