arthexis 0.1.9__py3-none-any.whl → 0.1.26__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.
Potentially problematic release.
This version of arthexis might be problematic. Click here for more details.
- arthexis-0.1.26.dist-info/METADATA +272 -0
- arthexis-0.1.26.dist-info/RECORD +111 -0
- {arthexis-0.1.9.dist-info → arthexis-0.1.26.dist-info}/licenses/LICENSE +674 -674
- config/__init__.py +5 -5
- config/active_app.py +15 -15
- config/asgi.py +29 -29
- config/auth_app.py +7 -7
- config/celery.py +32 -25
- config/context_processors.py +67 -68
- config/horologia_app.py +7 -7
- config/loadenv.py +11 -11
- config/logging.py +59 -48
- config/middleware.py +71 -25
- config/offline.py +49 -49
- config/settings.py +676 -492
- config/settings_helpers.py +109 -0
- config/urls.py +228 -159
- config/wsgi.py +17 -17
- core/admin.py +4052 -2066
- core/admin_history.py +50 -50
- core/admindocs.py +192 -151
- core/apps.py +350 -223
- core/auto_upgrade.py +72 -0
- core/backends.py +311 -124
- core/changelog.py +403 -0
- core/entity.py +149 -133
- core/environment.py +60 -43
- core/fields.py +168 -75
- core/form_fields.py +75 -0
- core/github_helper.py +188 -25
- core/github_issues.py +183 -172
- core/github_repos.py +72 -0
- core/lcd_screen.py +78 -78
- core/liveupdate.py +25 -25
- core/log_paths.py +114 -100
- core/mailer.py +89 -83
- core/middleware.py +91 -91
- core/models.py +5041 -2195
- core/notifications.py +105 -105
- core/public_wifi.py +267 -227
- core/reference_utils.py +107 -0
- core/release.py +940 -346
- core/rfid_import_export.py +113 -0
- core/sigil_builder.py +149 -131
- core/sigil_context.py +20 -20
- core/sigil_resolver.py +250 -284
- core/system.py +1425 -230
- core/tasks.py +538 -199
- core/temp_passwords.py +181 -0
- core/test_system_info.py +202 -43
- core/tests.py +2673 -1069
- core/tests_liveupdate.py +17 -17
- core/urls.py +11 -11
- core/user_data.py +681 -495
- core/views.py +2484 -789
- core/widgets.py +213 -51
- nodes/admin.py +2236 -445
- nodes/apps.py +98 -70
- nodes/backends.py +160 -53
- nodes/dns.py +203 -0
- nodes/feature_checks.py +133 -0
- nodes/lcd.py +165 -165
- nodes/models.py +2375 -870
- nodes/reports.py +411 -0
- nodes/rfid_sync.py +210 -0
- nodes/signals.py +18 -0
- nodes/tasks.py +141 -46
- nodes/tests.py +5045 -1489
- nodes/urls.py +29 -13
- nodes/utils.py +172 -73
- nodes/views.py +1768 -304
- ocpp/admin.py +1775 -481
- ocpp/apps.py +25 -25
- ocpp/consumers.py +1843 -630
- ocpp/evcs.py +844 -928
- ocpp/evcs_discovery.py +158 -0
- ocpp/models.py +1417 -640
- ocpp/network.py +398 -0
- ocpp/reference_utils.py +42 -0
- ocpp/routing.py +11 -9
- ocpp/simulator.py +745 -368
- ocpp/status_display.py +26 -0
- ocpp/store.py +603 -403
- ocpp/tasks.py +479 -31
- ocpp/test_export_import.py +131 -130
- ocpp/test_rfid.py +1072 -540
- ocpp/tests.py +5494 -2296
- ocpp/transactions_io.py +197 -165
- ocpp/urls.py +50 -50
- ocpp/views.py +2024 -912
- pages/admin.py +1123 -396
- pages/apps.py +45 -10
- pages/checks.py +40 -40
- pages/context_processors.py +151 -85
- pages/defaults.py +13 -0
- pages/forms.py +221 -0
- pages/middleware.py +213 -153
- pages/models.py +720 -252
- pages/module_defaults.py +156 -0
- pages/site_config.py +137 -0
- pages/tasks.py +74 -0
- pages/tests.py +4009 -1389
- pages/urls.py +38 -20
- pages/utils.py +93 -12
- pages/views.py +1736 -762
- arthexis-0.1.9.dist-info/METADATA +0 -168
- arthexis-0.1.9.dist-info/RECORD +0 -92
- core/workgroup_urls.py +0 -17
- core/workgroup_views.py +0 -94
- nodes/actions.py +0 -70
- {arthexis-0.1.9.dist-info → arthexis-0.1.26.dist-info}/WHEEL +0 -0
- {arthexis-0.1.9.dist-info → arthexis-0.1.26.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Utility helpers shared by :mod:`config.settings` and related tests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import contextlib
|
|
6
|
+
import ipaddress
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Mapping, MutableMapping
|
|
10
|
+
|
|
11
|
+
from django.core.management.utils import get_random_secret_key
|
|
12
|
+
from django.http import request as http_request
|
|
13
|
+
from django.http.request import split_domain_port
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"extract_ip_from_host",
|
|
18
|
+
"install_validate_host_with_subnets",
|
|
19
|
+
"load_secret_key",
|
|
20
|
+
"strip_ipv6_brackets",
|
|
21
|
+
"validate_host_with_subnets",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def strip_ipv6_brackets(host: str) -> str:
|
|
26
|
+
"""Return ``host`` without IPv6 URL literal brackets."""
|
|
27
|
+
|
|
28
|
+
if host.startswith("[") and host.endswith("]"):
|
|
29
|
+
return host[1:-1]
|
|
30
|
+
return host
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def extract_ip_from_host(host: str):
|
|
34
|
+
"""Return an :mod:`ipaddress` object for ``host`` when possible."""
|
|
35
|
+
|
|
36
|
+
candidate = strip_ipv6_brackets(host)
|
|
37
|
+
try:
|
|
38
|
+
return ipaddress.ip_address(candidate)
|
|
39
|
+
except ValueError:
|
|
40
|
+
domain, _port = split_domain_port(host)
|
|
41
|
+
if domain and domain != host:
|
|
42
|
+
candidate = strip_ipv6_brackets(domain)
|
|
43
|
+
try:
|
|
44
|
+
return ipaddress.ip_address(candidate)
|
|
45
|
+
except ValueError:
|
|
46
|
+
return None
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def validate_host_with_subnets(host, allowed_hosts, original_validate=None):
|
|
51
|
+
"""Extend Django's host validation to honor subnet CIDR notation."""
|
|
52
|
+
|
|
53
|
+
if original_validate is None:
|
|
54
|
+
original_validate = http_request.validate_host
|
|
55
|
+
|
|
56
|
+
ip = extract_ip_from_host(host)
|
|
57
|
+
if ip is None:
|
|
58
|
+
return original_validate(host, allowed_hosts)
|
|
59
|
+
|
|
60
|
+
for pattern in allowed_hosts:
|
|
61
|
+
try:
|
|
62
|
+
network = ipaddress.ip_network(pattern)
|
|
63
|
+
except ValueError:
|
|
64
|
+
continue
|
|
65
|
+
if ip in network:
|
|
66
|
+
return True
|
|
67
|
+
return original_validate(host, allowed_hosts)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def install_validate_host_with_subnets() -> None:
|
|
71
|
+
"""Monkeypatch Django's host validator to recognize subnet patterns."""
|
|
72
|
+
|
|
73
|
+
original_validate = http_request.validate_host
|
|
74
|
+
|
|
75
|
+
def _patched(host, allowed_hosts):
|
|
76
|
+
return validate_host_with_subnets(host, allowed_hosts, original_validate)
|
|
77
|
+
|
|
78
|
+
http_request.validate_host = _patched
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def load_secret_key(
|
|
82
|
+
base_dir: Path,
|
|
83
|
+
env: Mapping[str, str] | MutableMapping[str, str] | None = None,
|
|
84
|
+
secret_file: Path | None = None,
|
|
85
|
+
) -> str:
|
|
86
|
+
"""Load the Django secret key from the environment or a persisted file."""
|
|
87
|
+
|
|
88
|
+
if env is None:
|
|
89
|
+
env = os.environ
|
|
90
|
+
|
|
91
|
+
for env_var in ("DJANGO_SECRET_KEY", "SECRET_KEY"):
|
|
92
|
+
value = env.get(env_var)
|
|
93
|
+
if value:
|
|
94
|
+
return value
|
|
95
|
+
|
|
96
|
+
if secret_file is None:
|
|
97
|
+
secret_file = base_dir / "locks" / "django-secret.key"
|
|
98
|
+
|
|
99
|
+
with contextlib.suppress(OSError):
|
|
100
|
+
stored_key = secret_file.read_text(encoding="utf-8").strip()
|
|
101
|
+
if stored_key:
|
|
102
|
+
return stored_key
|
|
103
|
+
|
|
104
|
+
generated_key = get_random_secret_key()
|
|
105
|
+
with contextlib.suppress(OSError):
|
|
106
|
+
secret_file.parent.mkdir(parents=True, exist_ok=True)
|
|
107
|
+
secret_file.write_text(generated_key, encoding="utf-8")
|
|
108
|
+
|
|
109
|
+
return generated_key
|
config/urls.py
CHANGED
|
@@ -1,159 +1,228 @@
|
|
|
1
|
-
"""Project URL configuration with automatic app discovery.
|
|
2
|
-
|
|
3
|
-
This module includes URL patterns from any installed application that exposes
|
|
4
|
-
an internal ``urls`` module. This allows new apps with URL configurations to be
|
|
5
|
-
added without editing this file, except for top-level routes such as the admin
|
|
6
|
-
interface or the main pages.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from importlib import import_module
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
from django.apps import apps
|
|
13
|
-
from django.conf import settings
|
|
14
|
-
from django.conf.urls.static import static
|
|
15
|
-
from django.contrib import
|
|
16
|
-
from django.
|
|
17
|
-
|
|
18
|
-
from django.
|
|
19
|
-
from django.
|
|
20
|
-
|
|
21
|
-
from django.
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
path(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
1
|
+
"""Project URL configuration with automatic app discovery.
|
|
2
|
+
|
|
3
|
+
This module includes URL patterns from any installed application that exposes
|
|
4
|
+
an internal ``urls`` module. This allows new apps with URL configurations to be
|
|
5
|
+
added without editing this file, except for top-level routes such as the admin
|
|
6
|
+
interface or the main pages.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from importlib import import_module
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from django.apps import apps
|
|
13
|
+
from django.conf import settings
|
|
14
|
+
from django.conf.urls.static import static
|
|
15
|
+
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
|
16
|
+
from django.contrib import admin
|
|
17
|
+
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
|
|
18
|
+
from django.db.utils import DatabaseError, OperationalError, ProgrammingError
|
|
19
|
+
from django.urls import include, path
|
|
20
|
+
import teams.admin # noqa: F401
|
|
21
|
+
from django.views.decorators.csrf import csrf_exempt
|
|
22
|
+
from django.views.generic import RedirectView
|
|
23
|
+
from django.views.i18n import set_language
|
|
24
|
+
from django.utils.translation import gettext_lazy as _
|
|
25
|
+
from core import views as core_views
|
|
26
|
+
from core.admindocs import (
|
|
27
|
+
CommandsView,
|
|
28
|
+
ModelGraphIndexView,
|
|
29
|
+
OrderedModelIndexView,
|
|
30
|
+
)
|
|
31
|
+
from pages import views as pages_views
|
|
32
|
+
|
|
33
|
+
try: # Gate optional GraphQL dependency for roles that do not install it
|
|
34
|
+
from api.views import EnergyGraphQLView
|
|
35
|
+
except ModuleNotFoundError as exc: # pragma: no cover - dependency intentionally optional
|
|
36
|
+
if exc.name in {"graphene_django", "graphene"}:
|
|
37
|
+
EnergyGraphQLView = None # type: ignore[assignment]
|
|
38
|
+
else: # pragma: no cover - unrelated import error
|
|
39
|
+
raise
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _graphql_feature_enabled() -> bool:
|
|
43
|
+
"""Return ``True`` when the GraphQL endpoint should be exposed."""
|
|
44
|
+
|
|
45
|
+
if EnergyGraphQLView is None:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
from nodes.models import Node, NodeFeature
|
|
50
|
+
except (ModuleNotFoundError, AppRegistryNotReady, ImproperlyConfigured):
|
|
51
|
+
return True
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
feature = NodeFeature.objects.filter(slug="graphql").first()
|
|
55
|
+
except (DatabaseError, OperationalError, ProgrammingError):
|
|
56
|
+
return True
|
|
57
|
+
|
|
58
|
+
if feature is None:
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
node = Node.get_local()
|
|
63
|
+
except (DatabaseError, OperationalError, ProgrammingError):
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
if node and not node.has_feature("graphql"):
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
admin.site.site_header = _("Constellation")
|
|
72
|
+
admin.site.site_title = _("Constellation")
|
|
73
|
+
|
|
74
|
+
# Apps that require a custom prefix for their URLs
|
|
75
|
+
URL_PREFIX_OVERRIDES = {"core": "api/rfid"}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def autodiscovered_urlpatterns():
|
|
79
|
+
"""Collect URL patterns from project apps automatically.
|
|
80
|
+
|
|
81
|
+
Scans all installed apps located inside the project directory. If an app
|
|
82
|
+
exposes a ``urls`` module, it is included under ``/<app_label>/`` unless a
|
|
83
|
+
custom prefix is defined in :data:`URL_PREFIX_OVERRIDES`.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
patterns = []
|
|
87
|
+
base_dir = Path(settings.BASE_DIR).resolve()
|
|
88
|
+
for app_config in apps.get_app_configs():
|
|
89
|
+
app_path = Path(app_config.path).resolve()
|
|
90
|
+
try:
|
|
91
|
+
app_path.relative_to(base_dir)
|
|
92
|
+
except ValueError:
|
|
93
|
+
# Skip third-party apps outside of the project
|
|
94
|
+
continue
|
|
95
|
+
|
|
96
|
+
if app_config.label == "pages":
|
|
97
|
+
# Root pages URLs are handled explicitly below
|
|
98
|
+
continue
|
|
99
|
+
|
|
100
|
+
module_name = f"{app_config.name}.urls"
|
|
101
|
+
try:
|
|
102
|
+
import_module(module_name)
|
|
103
|
+
except ModuleNotFoundError:
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
prefix = URL_PREFIX_OVERRIDES.get(app_config.label, app_config.label)
|
|
107
|
+
patterns.append(path(f"{prefix}/", include(module_name)))
|
|
108
|
+
|
|
109
|
+
return patterns
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
urlpatterns = [
|
|
113
|
+
path(
|
|
114
|
+
"admin/doc/manuals/",
|
|
115
|
+
pages_views.admin_manual_list,
|
|
116
|
+
name="django-admindocs-manuals",
|
|
117
|
+
),
|
|
118
|
+
path(
|
|
119
|
+
"admin/doc/manuals/<slug:slug>/",
|
|
120
|
+
pages_views.admin_manual_detail,
|
|
121
|
+
name="django-admindocs-manual-detail",
|
|
122
|
+
),
|
|
123
|
+
path(
|
|
124
|
+
"admin/doc/manuals/<slug:slug>/pdf/",
|
|
125
|
+
pages_views.manual_pdf,
|
|
126
|
+
name="django-admindocs-manual-pdf",
|
|
127
|
+
),
|
|
128
|
+
path(
|
|
129
|
+
"admin/doc/commands/",
|
|
130
|
+
CommandsView.as_view(),
|
|
131
|
+
name="django-admindocs-commands",
|
|
132
|
+
),
|
|
133
|
+
path(
|
|
134
|
+
"admin/doc/commands/",
|
|
135
|
+
RedirectView.as_view(pattern_name="django-admindocs-commands"),
|
|
136
|
+
),
|
|
137
|
+
path(
|
|
138
|
+
"admin/doc/model-graphs/",
|
|
139
|
+
ModelGraphIndexView.as_view(),
|
|
140
|
+
name="django-admindocs-model-graphs",
|
|
141
|
+
),
|
|
142
|
+
path(
|
|
143
|
+
"admindocs/model-graphs/",
|
|
144
|
+
RedirectView.as_view(pattern_name="django-admindocs-model-graphs"),
|
|
145
|
+
),
|
|
146
|
+
path(
|
|
147
|
+
"admindocs/models/",
|
|
148
|
+
OrderedModelIndexView.as_view(),
|
|
149
|
+
name="django-admindocs-models-index",
|
|
150
|
+
),
|
|
151
|
+
path("admindocs/", include("django.contrib.admindocs.urls")),
|
|
152
|
+
path(
|
|
153
|
+
"admin/doc/",
|
|
154
|
+
RedirectView.as_view(pattern_name="django-admindocs-docroot"),
|
|
155
|
+
),
|
|
156
|
+
path(
|
|
157
|
+
"admin/model-graph/<str:app_label>/",
|
|
158
|
+
admin.site.admin_view(pages_views.admin_model_graph),
|
|
159
|
+
name="admin-model-graph",
|
|
160
|
+
),
|
|
161
|
+
path("version/", core_views.version_info, name="version-info"),
|
|
162
|
+
path(
|
|
163
|
+
"admin/core/releases/<int:pk>/<str:action>/",
|
|
164
|
+
core_views.release_progress,
|
|
165
|
+
name="release-progress",
|
|
166
|
+
),
|
|
167
|
+
path(
|
|
168
|
+
"admin/core/todos/<int:pk>/focus/",
|
|
169
|
+
core_views.todo_focus,
|
|
170
|
+
name="todo-focus",
|
|
171
|
+
),
|
|
172
|
+
path(
|
|
173
|
+
"admin/core/todos/<int:pk>/done/",
|
|
174
|
+
core_views.todo_done,
|
|
175
|
+
name="todo-done",
|
|
176
|
+
),
|
|
177
|
+
path(
|
|
178
|
+
"admin/core/todos/<int:pk>/delete/",
|
|
179
|
+
core_views.todo_delete,
|
|
180
|
+
name="todo-delete",
|
|
181
|
+
),
|
|
182
|
+
path(
|
|
183
|
+
"admin/core/todos/<int:pk>/snapshot/",
|
|
184
|
+
core_views.todo_snapshot,
|
|
185
|
+
name="todo-snapshot",
|
|
186
|
+
),
|
|
187
|
+
path(
|
|
188
|
+
"admin/core/odoo-products/",
|
|
189
|
+
core_views.odoo_products,
|
|
190
|
+
name="odoo-products",
|
|
191
|
+
),
|
|
192
|
+
path(
|
|
193
|
+
"admin/core/odoo-quote-report/",
|
|
194
|
+
core_views.odoo_quote_report,
|
|
195
|
+
name="odoo-quote-report",
|
|
196
|
+
),
|
|
197
|
+
path(
|
|
198
|
+
"admin/request-temp-password/",
|
|
199
|
+
core_views.request_temp_password,
|
|
200
|
+
name="admin-request-temp-password",
|
|
201
|
+
),
|
|
202
|
+
path("admin/", admin.site.urls),
|
|
203
|
+
path("i18n/setlang/", csrf_exempt(set_language), name="set_language"),
|
|
204
|
+
path("", include("pages.urls")),
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
if _graphql_feature_enabled():
|
|
208
|
+
urlpatterns.append(path("graphql/", EnergyGraphQLView.as_view(), name="graphql"))
|
|
209
|
+
|
|
210
|
+
urlpatterns += autodiscovered_urlpatterns()
|
|
211
|
+
|
|
212
|
+
if settings.DEBUG:
|
|
213
|
+
try:
|
|
214
|
+
import debug_toolbar
|
|
215
|
+
except ModuleNotFoundError: # pragma: no cover - optional dependency
|
|
216
|
+
pass
|
|
217
|
+
else:
|
|
218
|
+
urlpatterns = [
|
|
219
|
+
path(
|
|
220
|
+
"__debug__/",
|
|
221
|
+
include(
|
|
222
|
+
("debug_toolbar.urls", "debug_toolbar"), namespace="debug_toolbar"
|
|
223
|
+
),
|
|
224
|
+
)
|
|
225
|
+
] + urlpatterns
|
|
226
|
+
|
|
227
|
+
urlpatterns += staticfiles_urlpatterns()
|
|
228
|
+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
config/wsgi.py
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"""
|
|
2
|
-
WSGI config for config project.
|
|
3
|
-
|
|
4
|
-
It exposes the WSGI callable as a module-level variable named ``application``.
|
|
5
|
-
|
|
6
|
-
For more information on this file, see
|
|
7
|
-
https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import os
|
|
11
|
-
from config.loadenv import loadenv
|
|
12
|
-
from django.core.wsgi import get_wsgi_application
|
|
13
|
-
|
|
14
|
-
loadenv()
|
|
15
|
-
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
|
16
|
-
|
|
17
|
-
application = get_wsgi_application()
|
|
1
|
+
"""
|
|
2
|
+
WSGI config for config project.
|
|
3
|
+
|
|
4
|
+
It exposes the WSGI callable as a module-level variable named ``application``.
|
|
5
|
+
|
|
6
|
+
For more information on this file, see
|
|
7
|
+
https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from config.loadenv import loadenv
|
|
12
|
+
from django.core.wsgi import get_wsgi_application
|
|
13
|
+
|
|
14
|
+
loadenv()
|
|
15
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
|
16
|
+
|
|
17
|
+
application = get_wsgi_application()
|