arthexis 0.1.13__py3-none-any.whl → 0.1.15__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 (108) hide show
  1. {arthexis-0.1.13.dist-info → arthexis-0.1.15.dist-info}/METADATA +224 -221
  2. arthexis-0.1.15.dist-info/RECORD +110 -0
  3. {arthexis-0.1.13.dist-info → arthexis-0.1.15.dist-info}/licenses/LICENSE +674 -674
  4. config/__init__.py +5 -5
  5. config/active_app.py +15 -15
  6. config/asgi.py +43 -43
  7. config/auth_app.py +7 -7
  8. config/celery.py +32 -32
  9. config/context_processors.py +67 -69
  10. config/horologia_app.py +7 -7
  11. config/loadenv.py +11 -11
  12. config/logging.py +59 -48
  13. config/middleware.py +25 -25
  14. config/offline.py +49 -49
  15. config/settings.py +691 -682
  16. config/settings_helpers.py +109 -109
  17. config/urls.py +171 -166
  18. config/wsgi.py +17 -17
  19. core/admin.py +3795 -2809
  20. core/admin_history.py +50 -50
  21. core/admindocs.py +151 -151
  22. core/apps.py +356 -272
  23. core/auto_upgrade.py +57 -57
  24. core/backends.py +265 -236
  25. core/changelog.py +342 -0
  26. core/entity.py +149 -133
  27. core/environment.py +61 -61
  28. core/fields.py +168 -168
  29. core/form_fields.py +75 -75
  30. core/github_helper.py +188 -25
  31. core/github_issues.py +178 -172
  32. core/github_repos.py +72 -0
  33. core/lcd_screen.py +78 -78
  34. core/liveupdate.py +25 -25
  35. core/log_paths.py +114 -100
  36. core/mailer.py +85 -85
  37. core/middleware.py +91 -91
  38. core/models.py +3637 -2795
  39. core/notifications.py +105 -105
  40. core/public_wifi.py +267 -227
  41. core/reference_utils.py +108 -108
  42. core/release.py +840 -368
  43. core/rfid_import_export.py +113 -0
  44. core/sigil_builder.py +149 -149
  45. core/sigil_context.py +20 -20
  46. core/sigil_resolver.py +315 -315
  47. core/system.py +952 -493
  48. core/tasks.py +408 -394
  49. core/temp_passwords.py +181 -181
  50. core/test_system_info.py +186 -139
  51. core/tests.py +2168 -1521
  52. core/tests_liveupdate.py +17 -17
  53. core/urls.py +11 -11
  54. core/user_data.py +641 -633
  55. core/views.py +2201 -1417
  56. core/widgets.py +213 -94
  57. core/workgroup_urls.py +17 -17
  58. core/workgroup_views.py +94 -94
  59. nodes/admin.py +1720 -1161
  60. nodes/apps.py +87 -85
  61. nodes/backends.py +160 -160
  62. nodes/dns.py +203 -203
  63. nodes/feature_checks.py +133 -133
  64. nodes/lcd.py +165 -165
  65. nodes/models.py +1764 -1597
  66. nodes/reports.py +411 -411
  67. nodes/rfid_sync.py +195 -0
  68. nodes/signals.py +18 -0
  69. nodes/tasks.py +46 -46
  70. nodes/tests.py +3830 -3116
  71. nodes/urls.py +15 -14
  72. nodes/utils.py +121 -105
  73. nodes/views.py +683 -619
  74. ocpp/admin.py +948 -948
  75. ocpp/apps.py +25 -25
  76. ocpp/consumers.py +1565 -1459
  77. ocpp/evcs.py +844 -844
  78. ocpp/evcs_discovery.py +158 -158
  79. ocpp/models.py +917 -917
  80. ocpp/reference_utils.py +42 -42
  81. ocpp/routing.py +11 -11
  82. ocpp/simulator.py +745 -745
  83. ocpp/status_display.py +26 -26
  84. ocpp/store.py +601 -541
  85. ocpp/tasks.py +31 -31
  86. ocpp/test_export_import.py +130 -130
  87. ocpp/test_rfid.py +913 -702
  88. ocpp/tests.py +4445 -4094
  89. ocpp/transactions_io.py +189 -189
  90. ocpp/urls.py +50 -50
  91. ocpp/views.py +1479 -1251
  92. pages/admin.py +769 -539
  93. pages/apps.py +10 -10
  94. pages/checks.py +40 -40
  95. pages/context_processors.py +127 -119
  96. pages/defaults.py +13 -13
  97. pages/forms.py +198 -198
  98. pages/middleware.py +209 -153
  99. pages/models.py +643 -426
  100. pages/tasks.py +74 -0
  101. pages/tests.py +3025 -2200
  102. pages/urls.py +26 -25
  103. pages/utils.py +23 -12
  104. pages/views.py +1176 -1128
  105. arthexis-0.1.13.dist-info/RECORD +0 -105
  106. nodes/actions.py +0 -70
  107. {arthexis-0.1.13.dist-info → arthexis-0.1.15.dist-info}/WHEEL +0 -0
  108. {arthexis-0.1.13.dist-info → arthexis-0.1.15.dist-info}/top_level.txt +0 -0
core/admin_history.py CHANGED
@@ -1,50 +1,50 @@
1
- import json
2
- from django.contrib.admin.options import ModelAdmin
3
- from django.contrib.admin.models import LogEntry
4
- from django.utils.encoding import smart_str
5
-
6
-
7
- def patch_admin_history():
8
- if getattr(ModelAdmin, "_history_patched", False):
9
- return
10
-
11
- def construct_change_message(self, request, form, formsets, add=False):
12
- fields = []
13
- if add:
14
- for name, value in form.cleaned_data.items():
15
- fields.append({"field": name, "old": None, "new": smart_str(value)})
16
- if not fields:
17
- return ""
18
- return json.dumps({"added": fields})
19
- for name in form.changed_data:
20
- fields.append(
21
- {
22
- "field": name,
23
- "old": smart_str(form.initial.get(name)),
24
- "new": smart_str(form.cleaned_data.get(name)),
25
- }
26
- )
27
- if not fields:
28
- return ""
29
- return json.dumps({"changed": fields})
30
-
31
- def get_change_message(self):
32
- try:
33
- data = json.loads(self.change_message)
34
- except Exception:
35
- return self.change_message
36
- if isinstance(data, dict):
37
- if "added" in data:
38
- parts = [f"{d['field']}='{d['new']}'" for d in data["added"]]
39
- return "Added " + ", ".join(parts)
40
- if "changed" in data:
41
- parts = [
42
- f"{d['field']}: '{d['old']}' -> '{d['new']}'"
43
- for d in data["changed"]
44
- ]
45
- return "Changed " + ", ".join(parts)
46
- return self.change_message
47
-
48
- ModelAdmin.construct_change_message = construct_change_message
49
- LogEntry.get_change_message = get_change_message
50
- ModelAdmin._history_patched = True
1
+ import json
2
+ from django.contrib.admin.options import ModelAdmin
3
+ from django.contrib.admin.models import LogEntry
4
+ from django.utils.encoding import smart_str
5
+
6
+
7
+ def patch_admin_history():
8
+ if getattr(ModelAdmin, "_history_patched", False):
9
+ return
10
+
11
+ def construct_change_message(self, request, form, formsets, add=False):
12
+ fields = []
13
+ if add:
14
+ for name, value in form.cleaned_data.items():
15
+ fields.append({"field": name, "old": None, "new": smart_str(value)})
16
+ if not fields:
17
+ return ""
18
+ return json.dumps({"added": fields})
19
+ for name in form.changed_data:
20
+ fields.append(
21
+ {
22
+ "field": name,
23
+ "old": smart_str(form.initial.get(name)),
24
+ "new": smart_str(form.cleaned_data.get(name)),
25
+ }
26
+ )
27
+ if not fields:
28
+ return ""
29
+ return json.dumps({"changed": fields})
30
+
31
+ def get_change_message(self):
32
+ try:
33
+ data = json.loads(self.change_message)
34
+ except Exception:
35
+ return self.change_message
36
+ if isinstance(data, dict):
37
+ if "added" in data:
38
+ parts = [f"{d['field']}='{d['new']}'" for d in data["added"]]
39
+ return "Added " + ", ".join(parts)
40
+ if "changed" in data:
41
+ parts = [
42
+ f"{d['field']}: '{d['old']}' -> '{d['new']}'"
43
+ for d in data["changed"]
44
+ ]
45
+ return "Changed " + ", ".join(parts)
46
+ return self.change_message
47
+
48
+ ModelAdmin.construct_change_message = construct_change_message
49
+ LogEntry.get_change_message = get_change_message
50
+ ModelAdmin._history_patched = True
core/admindocs.py CHANGED
@@ -1,151 +1,151 @@
1
- import argparse
2
- import inspect
3
- from types import SimpleNamespace
4
-
5
- from django.apps import apps
6
- from django.contrib import admin
7
- from django.core.management import get_commands, load_command_class
8
- from django.contrib.admindocs.views import (
9
- BaseAdminDocsView,
10
- user_has_model_view_permission,
11
- )
12
- from django.urls import NoReverseMatch, reverse
13
-
14
-
15
- class CommandsView(BaseAdminDocsView):
16
- template_name = "admin_doc/commands.html"
17
-
18
- def get_context_data(self, **kwargs):
19
- commands = []
20
- for name, app_name in sorted(get_commands().items()):
21
- try:
22
- cmd = load_command_class(app_name, name)
23
- parser = cmd.create_parser("manage.py", name)
24
- except Exception: # pragma: no cover - command import issues
25
- continue
26
- args = []
27
- options = []
28
- for action in parser._actions:
29
- if isinstance(action, argparse._HelpAction):
30
- continue
31
- if action.option_strings:
32
- options.append(
33
- {
34
- "opts": ", ".join(action.option_strings),
35
- "help": action.help or "",
36
- }
37
- )
38
- else:
39
- args.append(
40
- {
41
- "name": action.metavar or action.dest,
42
- "help": action.help or "",
43
- }
44
- )
45
- commands.append(
46
- {
47
- "name": name,
48
- "help": getattr(cmd, "help", ""),
49
- "args": args,
50
- "options": options,
51
- }
52
- )
53
- return super().get_context_data(**{**kwargs, "commands": commands})
54
-
55
-
56
- class OrderedModelIndexView(BaseAdminDocsView):
57
- template_name = "admin_doc/model_index.html"
58
-
59
- GROUP_OVERRIDES = {
60
- "ocpp.location": "core",
61
- "core.rfid": "ocpp",
62
- "core.package": "teams",
63
- "core.packagerelease": "teams",
64
- }
65
-
66
- def _get_docs_app_config(self, meta):
67
- override_label = self.GROUP_OVERRIDES.get(meta.label_lower)
68
- if override_label:
69
- return apps.get_app_config(override_label)
70
- return meta.app_config
71
-
72
- def get_context_data(self, **kwargs):
73
- models = []
74
- for m in apps.get_models():
75
- if user_has_model_view_permission(self.request.user, m._meta):
76
- meta = m._meta
77
- meta.docstring = inspect.getdoc(m) or ""
78
- app_config = self._get_docs_app_config(meta)
79
- models.append(
80
- SimpleNamespace(
81
- app_label=meta.app_label,
82
- model_name=meta.model_name,
83
- object_name=meta.object_name,
84
- docstring=meta.docstring,
85
- app_config=app_config,
86
- )
87
- )
88
- models.sort(key=lambda m: str(m.app_config.verbose_name))
89
- return super().get_context_data(**{**kwargs, "models": models})
90
-
91
-
92
- class ModelGraphIndexView(BaseAdminDocsView):
93
- template_name = "admin_doc/model_graphs.html"
94
-
95
- def get_context_data(self, **kwargs):
96
- sections = {}
97
- user = self.request.user
98
-
99
- for model in admin.site._registry:
100
- meta = model._meta
101
- if not user_has_model_view_permission(user, meta):
102
- continue
103
-
104
- app_config = apps.get_app_config(meta.app_label)
105
- section = sections.setdefault(
106
- app_config.label,
107
- {
108
- "app_label": app_config.label,
109
- "verbose_name": str(app_config.verbose_name),
110
- "models": [],
111
- },
112
- )
113
-
114
- section["models"].append(
115
- {
116
- "object_name": meta.object_name,
117
- "verbose_name": str(meta.verbose_name),
118
- "doc_url": reverse(
119
- "django-admindocs-models-detail",
120
- kwargs={
121
- "app_label": meta.app_label,
122
- "model_name": meta.model_name,
123
- },
124
- ),
125
- }
126
- )
127
-
128
- graph_sections = []
129
- for section in sections.values():
130
- section_models = section["models"]
131
- section_models.sort(key=lambda model: model["verbose_name"])
132
-
133
- try:
134
- app_list_url = reverse("admin:app_list", args=[section["app_label"]])
135
- except NoReverseMatch:
136
- app_list_url = ""
137
-
138
- graph_sections.append(
139
- {
140
- **section,
141
- "graph_url": reverse(
142
- "admin-model-graph", args=[section["app_label"]]
143
- ),
144
- "app_list_url": app_list_url,
145
- "model_count": len(section_models),
146
- }
147
- )
148
-
149
- graph_sections.sort(key=lambda section: section["verbose_name"])
150
-
151
- return super().get_context_data(**{**kwargs, "sections": graph_sections})
1
+ import argparse
2
+ import inspect
3
+ from types import SimpleNamespace
4
+
5
+ from django.apps import apps
6
+ from django.contrib import admin
7
+ from django.core.management import get_commands, load_command_class
8
+ from django.contrib.admindocs.views import (
9
+ BaseAdminDocsView,
10
+ user_has_model_view_permission,
11
+ )
12
+ from django.urls import NoReverseMatch, reverse
13
+
14
+
15
+ class CommandsView(BaseAdminDocsView):
16
+ template_name = "admin_doc/commands.html"
17
+
18
+ def get_context_data(self, **kwargs):
19
+ commands = []
20
+ for name, app_name in sorted(get_commands().items()):
21
+ try:
22
+ cmd = load_command_class(app_name, name)
23
+ parser = cmd.create_parser("manage.py", name)
24
+ except Exception: # pragma: no cover - command import issues
25
+ continue
26
+ args = []
27
+ options = []
28
+ for action in parser._actions:
29
+ if isinstance(action, argparse._HelpAction):
30
+ continue
31
+ if action.option_strings:
32
+ options.append(
33
+ {
34
+ "opts": ", ".join(action.option_strings),
35
+ "help": action.help or "",
36
+ }
37
+ )
38
+ else:
39
+ args.append(
40
+ {
41
+ "name": action.metavar or action.dest,
42
+ "help": action.help or "",
43
+ }
44
+ )
45
+ commands.append(
46
+ {
47
+ "name": name,
48
+ "help": getattr(cmd, "help", ""),
49
+ "args": args,
50
+ "options": options,
51
+ }
52
+ )
53
+ return super().get_context_data(**{**kwargs, "commands": commands})
54
+
55
+
56
+ class OrderedModelIndexView(BaseAdminDocsView):
57
+ template_name = "admin_doc/model_index.html"
58
+
59
+ GROUP_OVERRIDES = {
60
+ "ocpp.location": "core",
61
+ "core.rfid": "ocpp",
62
+ "core.package": "teams",
63
+ "core.packagerelease": "teams",
64
+ }
65
+
66
+ def _get_docs_app_config(self, meta):
67
+ override_label = self.GROUP_OVERRIDES.get(meta.label_lower)
68
+ if override_label:
69
+ return apps.get_app_config(override_label)
70
+ return meta.app_config
71
+
72
+ def get_context_data(self, **kwargs):
73
+ models = []
74
+ for m in apps.get_models():
75
+ if user_has_model_view_permission(self.request.user, m._meta):
76
+ meta = m._meta
77
+ meta.docstring = inspect.getdoc(m) or ""
78
+ app_config = self._get_docs_app_config(meta)
79
+ models.append(
80
+ SimpleNamespace(
81
+ app_label=meta.app_label,
82
+ model_name=meta.model_name,
83
+ object_name=meta.object_name,
84
+ docstring=meta.docstring,
85
+ app_config=app_config,
86
+ )
87
+ )
88
+ models.sort(key=lambda m: str(m.app_config.verbose_name))
89
+ return super().get_context_data(**{**kwargs, "models": models})
90
+
91
+
92
+ class ModelGraphIndexView(BaseAdminDocsView):
93
+ template_name = "admin_doc/model_graphs.html"
94
+
95
+ def get_context_data(self, **kwargs):
96
+ sections = {}
97
+ user = self.request.user
98
+
99
+ for model in admin.site._registry:
100
+ meta = model._meta
101
+ if not user_has_model_view_permission(user, meta):
102
+ continue
103
+
104
+ app_config = apps.get_app_config(meta.app_label)
105
+ section = sections.setdefault(
106
+ app_config.label,
107
+ {
108
+ "app_label": app_config.label,
109
+ "verbose_name": str(app_config.verbose_name),
110
+ "models": [],
111
+ },
112
+ )
113
+
114
+ section["models"].append(
115
+ {
116
+ "object_name": meta.object_name,
117
+ "verbose_name": str(meta.verbose_name),
118
+ "doc_url": reverse(
119
+ "django-admindocs-models-detail",
120
+ kwargs={
121
+ "app_label": meta.app_label,
122
+ "model_name": meta.model_name,
123
+ },
124
+ ),
125
+ }
126
+ )
127
+
128
+ graph_sections = []
129
+ for section in sections.values():
130
+ section_models = section["models"]
131
+ section_models.sort(key=lambda model: model["verbose_name"])
132
+
133
+ try:
134
+ app_list_url = reverse("admin:app_list", args=[section["app_label"]])
135
+ except NoReverseMatch:
136
+ app_list_url = ""
137
+
138
+ graph_sections.append(
139
+ {
140
+ **section,
141
+ "graph_url": reverse(
142
+ "admin-model-graph", args=[section["app_label"]]
143
+ ),
144
+ "app_list_url": app_list_url,
145
+ "model_count": len(section_models),
146
+ }
147
+ )
148
+
149
+ graph_sections.sort(key=lambda section: section["verbose_name"])
150
+
151
+ return super().get_context_data(**{**kwargs, "sections": graph_sections})