arthexis 0.1.8__py3-none-any.whl → 0.1.10__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.

Files changed (84) hide show
  1. {arthexis-0.1.8.dist-info → arthexis-0.1.10.dist-info}/METADATA +87 -6
  2. arthexis-0.1.10.dist-info/RECORD +95 -0
  3. arthexis-0.1.10.dist-info/licenses/LICENSE +674 -0
  4. config/__init__.py +0 -1
  5. config/auth_app.py +0 -1
  6. config/celery.py +1 -2
  7. config/context_processors.py +1 -1
  8. config/offline.py +2 -0
  9. config/settings.py +352 -37
  10. config/urls.py +71 -6
  11. core/admin.py +1601 -200
  12. core/admin_history.py +50 -0
  13. core/admindocs.py +108 -1
  14. core/apps.py +161 -3
  15. core/auto_upgrade.py +57 -0
  16. core/backends.py +123 -7
  17. core/entity.py +62 -48
  18. core/fields.py +98 -0
  19. core/github_helper.py +25 -0
  20. core/github_issues.py +172 -0
  21. core/lcd_screen.py +1 -0
  22. core/liveupdate.py +25 -0
  23. core/log_paths.py +100 -0
  24. core/mailer.py +83 -0
  25. core/middleware.py +57 -0
  26. core/models.py +1279 -267
  27. core/notifications.py +11 -1
  28. core/public_wifi.py +227 -0
  29. core/reference_utils.py +97 -0
  30. core/release.py +27 -20
  31. core/sigil_builder.py +144 -0
  32. core/sigil_context.py +20 -0
  33. core/sigil_resolver.py +284 -0
  34. core/system.py +162 -29
  35. core/tasks.py +269 -27
  36. core/test_system_info.py +59 -1
  37. core/tests.py +644 -73
  38. core/tests_liveupdate.py +17 -0
  39. core/urls.py +2 -2
  40. core/user_data.py +425 -168
  41. core/views.py +627 -59
  42. core/widgets.py +51 -0
  43. core/workgroup_urls.py +7 -3
  44. core/workgroup_views.py +43 -6
  45. nodes/actions.py +0 -2
  46. nodes/admin.py +168 -285
  47. nodes/apps.py +9 -15
  48. nodes/backends.py +145 -0
  49. nodes/lcd.py +24 -10
  50. nodes/models.py +579 -179
  51. nodes/tasks.py +1 -5
  52. nodes/tests.py +894 -130
  53. nodes/utils.py +13 -2
  54. nodes/views.py +204 -28
  55. ocpp/admin.py +212 -63
  56. ocpp/apps.py +1 -1
  57. ocpp/consumers.py +642 -68
  58. ocpp/evcs.py +30 -10
  59. ocpp/models.py +452 -70
  60. ocpp/simulator.py +75 -11
  61. ocpp/store.py +288 -30
  62. ocpp/tasks.py +11 -7
  63. ocpp/test_export_import.py +8 -7
  64. ocpp/test_rfid.py +211 -16
  65. ocpp/tests.py +1576 -137
  66. ocpp/transactions_io.py +68 -22
  67. ocpp/urls.py +35 -2
  68. ocpp/views.py +701 -123
  69. pages/admin.py +173 -13
  70. pages/checks.py +0 -1
  71. pages/context_processors.py +39 -6
  72. pages/forms.py +131 -0
  73. pages/middleware.py +153 -0
  74. pages/models.py +37 -9
  75. pages/tests.py +1182 -42
  76. pages/urls.py +4 -0
  77. pages/utils.py +0 -1
  78. pages/views.py +844 -51
  79. arthexis-0.1.8.dist-info/RECORD +0 -80
  80. arthexis-0.1.8.dist-info/licenses/LICENSE +0 -21
  81. config/workgroup_app.py +0 -7
  82. core/checks.py +0 -29
  83. {arthexis-0.1.8.dist-info → arthexis-0.1.10.dist-info}/WHEEL +0 -0
  84. {arthexis-0.1.8.dist-info → arthexis-0.1.10.dist-info}/top_level.txt +0 -0
core/widgets.py ADDED
@@ -0,0 +1,51 @@
1
+ from django import forms
2
+ import json
3
+
4
+
5
+ class CopyColorWidget(forms.TextInput):
6
+ input_type = "color"
7
+ template_name = "widgets/copy_color.html"
8
+
9
+ class Media:
10
+ js = ["core/copy_color.js"]
11
+
12
+
13
+ class CodeEditorWidget(forms.Textarea):
14
+ """Simple code editor widget for editing recipes."""
15
+
16
+ def __init__(self, attrs=None):
17
+ default_attrs = {"class": "code-editor"}
18
+ if attrs:
19
+ default_attrs.update(attrs)
20
+ super().__init__(attrs=default_attrs)
21
+
22
+ class Media:
23
+ css = {"all": ["core/code_editor.css"]}
24
+ js = ["core/code_editor.js"]
25
+
26
+
27
+ class OdooProductWidget(forms.Select):
28
+ """Widget for selecting an Odoo product."""
29
+
30
+ template_name = "widgets/odoo_product.html"
31
+
32
+ class Media:
33
+ js = ["core/odoo_product.js"]
34
+
35
+ def get_context(self, name, value, attrs):
36
+ attrs = attrs or {}
37
+ if isinstance(value, dict):
38
+ attrs["data-current-id"] = str(value.get("id", ""))
39
+ value = json.dumps(value)
40
+ elif not value:
41
+ value = ""
42
+ return super().get_context(name, value, attrs)
43
+
44
+ def value_from_datadict(self, data, files, name):
45
+ raw = data.get(name)
46
+ if not raw:
47
+ return {}
48
+ try:
49
+ return json.loads(raw)
50
+ except Exception:
51
+ return {}
core/workgroup_urls.py CHANGED
@@ -1,4 +1,4 @@
1
- """URL routes for chat profile endpoints."""
1
+ """URL routes for assistant profile endpoints."""
2
2
 
3
3
  from django.urls import path
4
4
 
@@ -7,7 +7,11 @@ from . import workgroup_views as views
7
7
  app_name = "workgroup"
8
8
 
9
9
  urlpatterns = [
10
- path("chat-profiles/<int:user_id>/", views.issue_key, name="chatprofile-issue"),
10
+ path(
11
+ "assistant-profiles/<int:user_id>/",
12
+ views.issue_key,
13
+ name="assistantprofile-issue",
14
+ ),
11
15
  path("assistant/test/", views.assistant_test, name="assistant-test"),
16
+ path("chat/", views.chat, name="chat"),
12
17
  ]
13
-
core/workgroup_views.py CHANGED
@@ -1,15 +1,17 @@
1
- """REST endpoints for ChatProfile issuance and authentication."""
1
+ """REST endpoints for AssistantProfile issuance and authentication."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
5
  from functools import wraps
6
6
 
7
+ from django.apps import apps
7
8
  from django.contrib.auth import get_user_model
9
+ from django.forms.models import model_to_dict
8
10
  from django.http import HttpResponse, JsonResponse
9
11
  from django.views.decorators.csrf import csrf_exempt
10
12
  from django.views.decorators.http import require_GET, require_POST
11
13
 
12
- from .models import ChatProfile, hash_key
14
+ from .models import AssistantProfile, hash_key
13
15
 
14
16
 
15
17
  @csrf_exempt
@@ -21,7 +23,7 @@ def issue_key(request, user_id: int) -> JsonResponse:
21
23
  """
22
24
 
23
25
  user = get_user_model().objects.get(pk=user_id)
24
- profile, key = ChatProfile.issue_key(user)
26
+ profile, key = AssistantProfile.issue_key(user)
25
27
  return JsonResponse({"user_id": user_id, "user_key": key})
26
28
 
27
29
 
@@ -36,11 +38,14 @@ def authenticate(view_func):
36
38
 
37
39
  key_hash = hash_key(header.split(" ", 1)[1])
38
40
  try:
39
- profile = ChatProfile.objects.get(user_key_hash=key_hash, is_active=True)
40
- except ChatProfile.DoesNotExist:
41
+ profile = AssistantProfile.objects.get(
42
+ user_key_hash=key_hash, is_active=True
43
+ )
44
+ except AssistantProfile.DoesNotExist:
41
45
  return HttpResponse(status=401)
42
46
 
43
47
  profile.touch()
48
+ request.assistant_profile = profile
44
49
  request.chat_profile = profile
45
50
  return view_func(request, *args, **kwargs)
46
51
 
@@ -52,6 +57,38 @@ def authenticate(view_func):
52
57
  def assistant_test(request):
53
58
  """Return a simple greeting to confirm authentication."""
54
59
 
55
- user_id = request.chat_profile.user_id
60
+ profile = getattr(request, "assistant_profile", None)
61
+ user_id = profile.user_id if profile else None
56
62
  return JsonResponse({"message": f"Hello from user {user_id}"})
57
63
 
64
+
65
+ @require_GET
66
+ @authenticate
67
+ def chat(request):
68
+ """Return serialized data from any model.
69
+
70
+ Clients must provide ``model`` as ``app_label.ModelName`` and may include a
71
+ ``pk`` to fetch a specific record. When ``pk`` is omitted, the view returns
72
+ up to 100 records.
73
+ """
74
+
75
+ model_label = request.GET.get("model")
76
+ if not model_label:
77
+ return JsonResponse({"error": "model parameter required"}, status=400)
78
+ try:
79
+ model = apps.get_model(model_label)
80
+ except LookupError:
81
+ return JsonResponse({"error": "unknown model"}, status=400)
82
+
83
+ qs = model.objects.all()
84
+ pk = request.GET.get("pk")
85
+ if pk is not None:
86
+ try:
87
+ obj = qs.get(pk=pk)
88
+ except model.DoesNotExist:
89
+ return JsonResponse({"error": "object not found"}, status=404)
90
+ data = model_to_dict(obj)
91
+ else:
92
+ data = [model_to_dict(o) for o in qs[:100]]
93
+
94
+ return JsonResponse({"data": data})
nodes/actions.py CHANGED
@@ -68,5 +68,3 @@ class CaptureScreenshotAction(NodeAction):
68
68
  path = capture_screenshot(url)
69
69
  save_screenshot(path, node=node, method="NODE_ACTION")
70
70
  return path
71
-
72
-