df_config 1.2.55__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. df_config/__init__.py +22 -0
  2. df_config/__main__.py +3 -0
  3. df_config/application.py +24 -0
  4. df_config/apps/__init__.py +15 -0
  5. df_config/apps/allauth.py +28 -0
  6. df_config/apps/backends.py +72 -0
  7. df_config/apps/middleware.py +136 -0
  8. df_config/apps/pipeline.py +180 -0
  9. df_config/checks.py +26 -0
  10. df_config/config/__init__.py +15 -0
  11. df_config/config/base.py +27 -0
  12. df_config/config/defaults.py +675 -0
  13. df_config/config/dynamic_settings.py +598 -0
  14. df_config/config/fields.py +257 -0
  15. df_config/config/fields_providers.py +71 -0
  16. df_config/config/merger.py +250 -0
  17. df_config/config/url.py +292 -0
  18. df_config/config/values_providers.py +296 -0
  19. df_config/context_processors.py +29 -0
  20. df_config/extra/__init__.py +0 -0
  21. df_config/extra/loki.py +21 -0
  22. df_config/guesses/__init__.py +15 -0
  23. df_config/guesses/apps.py +235 -0
  24. df_config/guesses/auth.py +248 -0
  25. df_config/guesses/databases.py +244 -0
  26. df_config/guesses/djt.py +32 -0
  27. df_config/guesses/log.py +717 -0
  28. df_config/guesses/misc.py +513 -0
  29. df_config/guesses/pipeline.py +95 -0
  30. df_config/guesses/social_providers.py +258 -0
  31. df_config/guesses/staticfiles.py +207 -0
  32. df_config/iniconf.py +512 -0
  33. df_config/manage.py +152 -0
  34. df_config/management/__init__.py +15 -0
  35. df_config/management/commands/__init__.py +15 -0
  36. df_config/management/commands/collectstatic.py +29 -0
  37. df_config/management/commands/config.py +231 -0
  38. df_config/management/commands/server.py +156 -0
  39. df_config/models.py +45 -0
  40. df_config/root_urls.py +115 -0
  41. df_config/static/favicon/apple-touch-icon-precomposed.png +0 -0
  42. df_config/static/favicon/apple-touch-icon.png +0 -0
  43. df_config/static/favicon/favicon.ico +0 -0
  44. df_config/static/favicon/robots.txt +2 -0
  45. df_config/static/js/df_config.min.js +2 -0
  46. df_config/static/js/df_config.min.js.map +1 -0
  47. df_config/urls.py +1 -0
  48. df_config/utils.py +311 -0
  49. df_config-1.2.55.dist-info/LICENSE +515 -0
  50. df_config-1.2.55.dist-info/METADATA +296 -0
  51. df_config-1.2.55.dist-info/RECORD +52 -0
  52. df_config-1.2.55.dist-info/WHEEL +4 -0
df_config/__init__.py ADDED
@@ -0,0 +1,22 @@
1
+ # #############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # #############################################################################
16
+ """__init__ file."""
17
+ from importlib.metadata import PackageNotFoundError, version
18
+
19
+ try:
20
+ __version__ = version("df_config")
21
+ except PackageNotFoundError:
22
+ __version__ = "1.0.0"
df_config/__main__.py ADDED
@@ -0,0 +1,3 @@
1
+ from df_config.manage import manage
2
+
3
+ manage()
@@ -0,0 +1,24 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+ from django.core.wsgi import get_wsgi_application
17
+
18
+ try:
19
+ from django.core.asgi import get_asgi_application
20
+ except ImportError:
21
+ get_asgi_application = get_wsgi_application
22
+
23
+ wsgi_application = get_wsgi_application()
24
+ asgi_application = get_asgi_application()
@@ -0,0 +1,15 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
@@ -0,0 +1,28 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+
17
+ from django.conf import settings
18
+
19
+ try:
20
+ from allauth.account.adapter import DefaultAccountAdapter
21
+ except ImportError:
22
+ DefaultAccountAdapter = object
23
+
24
+
25
+ class AccountAdapter(DefaultAccountAdapter):
26
+ # noinspection PyMethodMayBeStatic,PyUnusedLocal
27
+ def is_open_for_signup(self, request):
28
+ return settings.DF_ALLOW_USER_CREATION and settings.DF_ALLOW_LOCAL_USERS
@@ -0,0 +1,72 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+ import logging
17
+
18
+ from django.conf import settings
19
+ from django.contrib.auth.backends import RemoteUserBackend
20
+ from django.contrib.auth.models import Group
21
+ from django.utils.functional import cached_property
22
+
23
+ logger = logging.getLogger("django.request")
24
+
25
+ _CACHED_GROUPS = {}
26
+
27
+
28
+ class DefaultGroupsRemoteUserBackend(RemoteUserBackend):
29
+ """Add groups to new users.
30
+ Based on :class:`django.contrib.auth.backends.RemoteUserBackend`.
31
+ Only overrides the `configure_user` method to add the required groups.
32
+
33
+ """
34
+
35
+ @property
36
+ def create_unknown_user(self):
37
+ return settings.DF_ALLOW_USER_CREATION
38
+
39
+ @cached_property
40
+ def ldap_backend(self):
41
+ # noinspection PyUnresolvedReferences
42
+ from django_auth_ldap.backend import LDAPBackend
43
+
44
+ return LDAPBackend()
45
+
46
+ def authenticate(self, *args, **kwargs):
47
+ remote_user = kwargs.get("remote_user")
48
+ if (
49
+ remote_user
50
+ and settings.AUTH_LDAP_SERVER_URI
51
+ and settings.AUTH_LDAP_ALWAYS_UPDATE_USER
52
+ ):
53
+ user = self.ldap_backend.populate_user(remote_user)
54
+ if user:
55
+ return user
56
+ return super().authenticate(*args, remote_user)
57
+
58
+ def configure_user(self, request, user=None, created=True):
59
+ """
60
+ Configure a user after creation and returns the updated user.
61
+
62
+ By default, returns the user unmodified; only add it to the default group.
63
+ """
64
+ if user is None: # compatibility
65
+ user = request
66
+ for group_name in settings.DF_DEFAULT_GROUPS:
67
+ if group_name not in _CACHED_GROUPS:
68
+ _CACHED_GROUPS[group_name] = Group.objects.get_or_create(
69
+ name=str(group_name)
70
+ )[0]
71
+ user.groups.add(_CACHED_GROUPS[group_name])
72
+ return user
@@ -0,0 +1,136 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+ import base64
17
+ import binascii
18
+ import logging
19
+ from functools import lru_cache
20
+
21
+ from django.conf import settings
22
+ from django.contrib import auth
23
+ from django.contrib.auth.middleware import (
24
+ RemoteUserMiddleware as BaseRemoteUserMiddleware,
25
+ )
26
+ from django.core.exceptions import ImproperlyConfigured
27
+ from django.http import HttpRequest
28
+ from django.utils.functional import cached_property
29
+
30
+ logger = logging.getLogger("django.request")
31
+
32
+
33
+ class DFConfigMiddleware(BaseRemoteUserMiddleware):
34
+ """Like :class:`django.contrib.auth.middleware.RemoteUserMiddleware` but:
35
+
36
+ * can use any header defined by the setting `DF_REMOTE_USER_HEADER`,
37
+ * handle the HTTP_X_FORWARDED_FOR HTTP header (set the right client IP)
38
+ * handle HTTP basic authentication
39
+ * set response header for Internet Explorer (to use its most recent render engine)
40
+ """
41
+
42
+ @lru_cache()
43
+ def get_remoteuser_header(self):
44
+ # avoid cached_property to ease unittests
45
+ header = settings.DF_REMOTE_USER_HEADER
46
+ if header:
47
+ header = header.upper().replace("-", "_")
48
+ return header
49
+
50
+ def process_request(self, request: HttpRequest):
51
+ request.remote_username = None
52
+
53
+ if settings.USE_X_FORWARDED_FOR and "HTTP_X_FORWARDED_FOR" in request.META:
54
+ request.META["REMOTE_ADDR"] = (
55
+ request.META["HTTP_X_FORWARDED_FOR"].split(",")[0].strip()
56
+ )
57
+
58
+ if settings.USE_HTTP_BASIC_AUTH and "HTTP_AUTHORIZATION" in request.META:
59
+ authentication = request.META["HTTP_AUTHORIZATION"]
60
+ authmeth, sep, auth_data = authentication.partition(" ")
61
+ if sep == " " and authmeth.lower() == "basic":
62
+ try:
63
+ auth_data = base64.b64decode(auth_data.strip()).decode("utf-8")
64
+ except binascii.Error:
65
+ auth_data = ""
66
+ except UnicodeDecodeError:
67
+ auth_data = ""
68
+ username, sep, password = auth_data.partition(":")
69
+ if sep == ":":
70
+ user = auth.authenticate(username=username, password=password)
71
+ if user:
72
+ request.user = user
73
+ auth.login(request, user)
74
+ username = getattr(settings, "DF_FAKE_AUTHENTICATION_USERNAME", None)
75
+
76
+ header = self.get_remoteuser_header()
77
+ if header and username and settings.DEBUG:
78
+ remote_addr = request.META.get("REMOTE_ADDR")
79
+ if remote_addr in settings.INTERNAL_IPS:
80
+ request.META[header] = username
81
+ elif remote_addr:
82
+ logger.warning(
83
+ "Unable to use `settings.DF_FAKE_AUTHENTICATION_USERNAME`. "
84
+ "You should add %s to the list `settings.INTERNAL_IPS`."
85
+ % remote_addr
86
+ )
87
+
88
+ if header and header in request.META:
89
+ remote_username = request.META.get(header)
90
+ if (
91
+ not remote_username or remote_username == "(null)"
92
+ ): # special case due to apache2+auth_mod_kerb :-(
93
+ return
94
+ remote_username = self.format_remote_username(remote_username)
95
+ # noinspection PyTypeChecker
96
+ self.remote_user_authentication(request, remote_username)
97
+
98
+ # noinspection PyUnusedLocal,PyMethodMayBeStatic
99
+ def process_response(self, request, response):
100
+ response["X-UA-Compatible"] = "IE=edge,chrome=1"
101
+ return response
102
+
103
+ def remote_user_authentication(self, request, username):
104
+ # AuthenticationMiddleware is required so that request.user exists.
105
+ # noinspection PyTypeChecker
106
+ if not hasattr(request, "user"):
107
+ raise ImproperlyConfigured(
108
+ "The Django remote user auth middleware requires the"
109
+ " authentication middleware to be installed. Edit your"
110
+ " MIDDLEWARE_CLASSES setting to insert"
111
+ " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
112
+ " before the RemoteUserMiddleware class."
113
+ )
114
+ # If the user is already authenticated and that user is the user we are
115
+ # getting passed in the headers, then the correct user is already
116
+ # persisted in the session and we don't need to continue.
117
+ if request.user.is_authenticated:
118
+ cleaned_username = self.clean_username(username, request)
119
+ if request.user.get_username() == cleaned_username:
120
+ request.remote_username = cleaned_username
121
+ return
122
+ else:
123
+ self._remove_invalid_user(request)
124
+ # We are seeing this user for the first time in this session, attempt
125
+ # to authenticate the user.
126
+ user = auth.authenticate(remote_user=username)
127
+ if user:
128
+ # User is valid. Set request.user and persist user in the session
129
+ # by logging the user in.
130
+ request.user = user
131
+ auth.login(request, user)
132
+ request.remote_username = user.username
133
+
134
+ # noinspection PyMethodMayBeStatic
135
+ def format_remote_username(self, remote_username):
136
+ return remote_username.partition("@")[0]
@@ -0,0 +1,180 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+ """Define extra compressors or compilers for django-pipeline."""
17
+
18
+ import os
19
+ from pathlib import Path
20
+
21
+ from django.conf import settings
22
+
23
+ if settings.USE_PIPELINE:
24
+ from pipeline.compilers import SubProcessCompiler
25
+ from pipeline.compressors import SubProcessCompressor
26
+ from pipeline.storage import PipelineManifestStorage, PipelineMixin
27
+ else:
28
+ SubProcessCompressor = object
29
+ SubProcessCompiler = object
30
+ PipelineManifestStorage = None
31
+ PipelineMixin = None
32
+
33
+
34
+ if settings.USE_WHITENOISE:
35
+ # noinspection PyPackageRequirements,PyUnresolvedReferences
36
+ from whitenoise.storage import CompressedManifestStaticFilesStorage
37
+ else:
38
+ CompressedManifestStaticFilesStorage = None
39
+
40
+
41
+ class RcssCompressor(SubProcessCompressor):
42
+ """CSS compressor based on the Python library rcssmin.
43
+
44
+ (https://github.com/ndparker/rcssmin).
45
+ """
46
+
47
+ def filter_css(self, css):
48
+ """Not implemented."""
49
+ raise NotImplementedError
50
+
51
+ def filter_js(self, js):
52
+ """Not implemented."""
53
+ raise NotImplementedError
54
+
55
+ # noinspection PyMethodMayBeStatic
56
+ def compress_css(self, css):
57
+ """Compress a block of CSS code using the "rcssmin" module."""
58
+ # noinspection PyUnresolvedReferences,PyPackageRequirements
59
+ from rcssmin import cssmin
60
+
61
+ return cssmin(css)
62
+
63
+
64
+ class CssNanoCompressor(SubProcessCompressor):
65
+ """CSS compressor based on the "cssnano" command."""
66
+
67
+ def compress_css(self, css):
68
+ """Compress a block of CSS code using the "cssnano" command."""
69
+ command = [settings.CSSNANO_BINARY] + settings.CSSNANO_ARGUMENTS
70
+ return self.execute_command(command, css)
71
+
72
+ def filter_css(self, css):
73
+ """Not implemented."""
74
+ raise NotImplementedError
75
+
76
+ def filter_js(self, js):
77
+ """Not implemented."""
78
+ raise NotImplementedError
79
+
80
+
81
+ class TerserCompressor(SubProcessCompressor):
82
+ """JavaScript compressor based on the "terser" command."""
83
+
84
+ def compress_js(self, js):
85
+ """Compress a block of JavaScript code using the "terser" command."""
86
+ command = [settings.TERSER_BINARY, settings.TERSER_ARGUMENTS, "--"]
87
+ if self.verbose:
88
+ command += ["--verbose"]
89
+ return self.execute_command(command, js)
90
+
91
+ def filter_css(self, css):
92
+ """Not implemented."""
93
+ raise NotImplementedError
94
+
95
+ def filter_js(self, js):
96
+ """Not implemented."""
97
+ raise NotImplementedError
98
+
99
+
100
+ class PyScssCompiler(SubProcessCompiler):
101
+ """SASS (.scss) compiler based on the Python library pyScss.
102
+
103
+ (http://pyscss.readthedocs.io/en/latest/ ).
104
+ However, this compiler is limited to SASS 3.2 and cannot compile modern projets like Bootstrap 4.
105
+ Please use :class:`pipeline.compilers.sass.SASSCompiler` if you use modern SCSS files.
106
+
107
+ """
108
+
109
+ output_extension = "css"
110
+
111
+ # noinspection PyMethodMayBeStatic
112
+ def match_file(self, filename):
113
+ """Return True if the file is a SASS file."""
114
+ return filename.endswith(".scss") or filename.endswith(".sass")
115
+
116
+ # noinspection PyUnusedLocal
117
+ def compile_file(self, infile, outfile, outdated=False, force=False):
118
+ """Compile a SASS file using the "scss" command."""
119
+ # noinspection PyUnresolvedReferences,PyUnresolvedReferences,PyPackageRequirements
120
+ from scss import Compiler
121
+
122
+ root = Path(os.path.abspath(settings.STATIC_ROOT))
123
+ compiler = Compiler(root=root, search_path=("./",))
124
+ css_content = compiler.compile(infile)
125
+ with open(outfile, "w") as fd:
126
+ fd.write(css_content)
127
+ # noinspection PyUnresolvedReferences
128
+ if self.verbose:
129
+ print(css_content)
130
+
131
+
132
+ class TypescriptCompiler(SubProcessCompiler):
133
+ """TypeScript (.ts) compiler using "tsc" (https://www.typescriptlang.org)."""
134
+
135
+ output_extension = "js"
136
+
137
+ # noinspection PyMethodMayBeStatic
138
+ def match_file(self, filename):
139
+ """Return True if the file is a TypeScript file."""
140
+ return filename.endswith(".ts")
141
+
142
+ # noinspection PyMethodMayBeStatic,PyUnusedLocal
143
+ def compile_file(self, infile, outfile, outdated=False, force=False):
144
+ """Compile a TypeScript file using the "tsc" command."""
145
+ command = (
146
+ [settings.TYPESCRIPT_BINARY]
147
+ + settings.TYPESCRIPT_ARGUMENTS
148
+ + ["--outFile", outfile, infile]
149
+ )
150
+ self.execute_command(command)
151
+
152
+
153
+ if PipelineManifestStorage:
154
+
155
+ class NicerPipelineCachedStorage(PipelineManifestStorage):
156
+ """Display a better exception."""
157
+
158
+ def hashed_name(self, name, content=None, filename=None):
159
+ """Display a better exception if the file is not found."""
160
+ try:
161
+ return super().hashed_name(name, content=content)
162
+ except ValueError as e:
163
+ raise ValueError(
164
+ "%s. Did you run the command 'collectstatic'?" % e.args[0]
165
+ )
166
+
167
+ else:
168
+ NicerPipelineCachedStorage = None
169
+
170
+ if PipelineMixin and CompressedManifestStaticFilesStorage:
171
+
172
+ class PipelineCompressedManifestStaticFilesStorage(
173
+ PipelineMixin, CompressedManifestStaticFilesStorage
174
+ ):
175
+ """Mix django-pipeline and whitenoise."""
176
+
177
+ pass
178
+
179
+ else:
180
+ PipelineCompressedManifestStaticFilesStorage = None
df_config/checks.py ADDED
@@ -0,0 +1,26 @@
1
+ # ##############################################################################
2
+ # This file is part of Interdiode #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <matthieu.gallet@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # ##############################################################################
8
+ import os
9
+ import sys
10
+
11
+ from django.core.checks import Warning
12
+
13
+ settings_check_results = []
14
+
15
+
16
+ def missing_package(package_name, desc=""):
17
+ if hasattr(sys, "real_prefix"): # inside a virtualenv
18
+ cmd = f"Try 'python -m pip install {package_name}' to install it."
19
+ elif __file__.startswith(os.environ.get("HOME", "/home")):
20
+ cmd = f"Try 'python3 -m pip install --user {package_name}' to install it."
21
+ else:
22
+ cmd = f"Try 'sudo python3 -m pip install {package_name}' to install it."
23
+ return Warning(
24
+ f"Python package '{package_name}' is required{desc}. {cmd}",
25
+ obj="configuration",
26
+ )
@@ -0,0 +1,15 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
@@ -0,0 +1,27 @@
1
+ # ##############################################################################
2
+ # This file is part of df_config #
3
+ # #
4
+ # Copyright (C) 2020 Matthieu Gallet <df_config@19pouces.net> #
5
+ # All Rights Reserved #
6
+ # #
7
+ # You may use, distribute and modify this code under the #
8
+ # terms of the (BSD-like) CeCILL-B license. #
9
+ # #
10
+ # You should have received a copy of the CeCILL-B license with #
11
+ # this file. If not, please visit: #
12
+ # https://cecill.info/licences/Licence_CeCILL-B_V1-en.txt (English) #
13
+ # or https://cecill.info/licences/Licence_CeCILL-B_V1-fr.txt (French) #
14
+ # #
15
+ # ##############################################################################
16
+ """This module should be used as DJANGO_SETTINGS_MODULE.
17
+
18
+ Merge several sources of settings: env. variable, Python modules or .ini files.
19
+ """
20
+ from df_config.manage import get_merger_from_env
21
+
22
+ merger = get_merger_from_env()
23
+ merger.process()
24
+ merger.post_process()
25
+
26
+ __settings = globals()
27
+ __settings.update(merger.settings)