slthcore 0.4.8__tar.gz → 0.5.0__tar.gz

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 slthcore might be problematic. Click here for more details.

Files changed (127) hide show
  1. {slthcore-0.4.8/slthcore.egg-info → slthcore-0.5.0}/PKG-INFO +1 -1
  2. {slthcore-0.4.8 → slthcore-0.5.0}/setup.py +1 -1
  3. {slthcore-0.4.8 → slthcore-0.5.0}/slth/__init__.py +2 -2
  4. {slthcore-0.4.8 → slthcore-0.5.0}/slth/application.py +78 -16
  5. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/__init__.py +1 -0
  6. {slthcore-0.4.8 → slthcore-0.5.0}/slth/components.py +2 -2
  7. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/__init__.py +72 -32
  8. slthcore-0.5.0/slth/endpoints/settings.py +60 -0
  9. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/user.py +6 -3
  10. {slthcore-0.4.8 → slthcore-0.5.0}/slth/factory.py +5 -5
  11. {slthcore-0.4.8 → slthcore-0.5.0}/slth/forms.py +34 -26
  12. slthcore-0.5.0/slth/integrations/deepseek/__init__.py +36 -0
  13. slthcore-0.5.0/slth/integrations/google/gemini.py +23 -0
  14. slthcore-0.5.0/slth/integrations/google/places.py +41 -0
  15. slthcore-0.5.0/slth/integrations/google/vision.py +18 -0
  16. slthcore-0.5.0/slth/integrations/justvoip/__init__.py +15 -0
  17. slthcore-0.5.0/slth/integrations/mercadopago/__init__.py +48 -0
  18. slthcore-0.5.0/slth/integrations/openai/chatgpt.py +30 -0
  19. slthcore-0.5.0/slth/integrations/viacep/__init__.py +6 -0
  20. slthcore-0.5.0/slth/integrations/whatsapp/__init__.py +9 -0
  21. slthcore-0.5.0/slth/management/commands/__init__.py +0 -0
  22. {slthcore-0.4.8 → slthcore-0.5.0}/slth/management/commands/api.py +26 -3
  23. slthcore-0.5.0/slth/middleware/__init__.py +0 -0
  24. slthcore-0.5.0/slth/migrations/0014_settings.py +40 -0
  25. slthcore-0.5.0/slth/migrations/__init__.py +0 -0
  26. {slthcore-0.4.8 → slthcore-0.5.0}/slth/models.py +24 -3
  27. {slthcore-0.4.8 → slthcore-0.5.0}/slth/oauth.py +10 -5
  28. {slthcore-0.4.8 → slthcore-0.5.0}/slth/queryset.py +81 -26
  29. {slthcore-0.4.8 → slthcore-0.5.0}/slth/serializer.py +95 -32
  30. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/css/slth.css +14 -7
  31. slthcore-0.5.0/slth/static/js/slth.min.js +270 -0
  32. {slthcore-0.4.8 → slthcore-0.5.0}/slth/templates/index.html +7 -15
  33. {slthcore-0.4.8 → slthcore-0.5.0}/slth/utils.py +8 -0
  34. {slthcore-0.4.8 → slthcore-0.5.0}/slth/views.py +1 -1
  35. {slthcore-0.4.8 → slthcore-0.5.0/slthcore.egg-info}/PKG-INFO +1 -1
  36. {slthcore-0.4.8 → slthcore-0.5.0}/slthcore.egg-info/SOURCES.txt +14 -0
  37. slthcore-0.4.8/slth/static/js/slth.min.js +0 -251
  38. {slthcore-0.4.8 → slthcore-0.5.0}/MANIFEST.in +0 -0
  39. {slthcore-0.4.8 → slthcore-0.5.0}/setup.cfg +0 -0
  40. {slthcore-0.4.8 → slthcore-0.5.0}/slth/apps.py +0 -0
  41. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/configure/__main__.py +0 -0
  42. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/__main__.py +0 -0
  43. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/__pycache__/__main__.cpython-312.pyc +0 -0
  44. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/.DS_Store +0 -0
  45. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/.gitignore +0 -0
  46. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/asgi.py +0 -0
  47. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/endpoints/__init__.py +0 -0
  48. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/models.py +0 -0
  49. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/settings.py +0 -0
  50. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/tests.py +0 -0
  51. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/urls.py +0 -0
  52. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/api/wsgi.py +0 -0
  53. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/entrypoint.sh +0 -0
  54. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/manage.py +0 -0
  55. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/backend/requirements.txt +0 -0
  56. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/base.env +0 -0
  57. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/docker-compose.yml +0 -0
  58. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/frontend/package.json +0 -0
  59. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/frontend/src/main.jsx +0 -0
  60. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/frontend/vite.config.js +0 -0
  61. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/local.env +0 -0
  62. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/run.sh +0 -0
  63. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/selenium/run.sh +0 -0
  64. {slthcore-0.4.8 → slthcore-0.5.0}/slth/cmd/init/boilerplate/test.sh +0 -0
  65. {slthcore-0.4.8 → slthcore-0.5.0}/slth/db/__init__.py +0 -0
  66. {slthcore-0.4.8 → slthcore-0.5.0}/slth/db/generic.py +0 -0
  67. {slthcore-0.4.8 → slthcore-0.5.0}/slth/db/models.py +0 -0
  68. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/auth.py +0 -0
  69. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/deletion.py +0 -0
  70. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/dev.py +0 -0
  71. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/email.py +0 -0
  72. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/job.py +0 -0
  73. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/log.py +0 -0
  74. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/profile.py +0 -0
  75. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/pushsubscription.py +0 -0
  76. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/report.py +0 -0
  77. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/role.py +0 -0
  78. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/task.py +0 -0
  79. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/timezone.py +0 -0
  80. {slthcore-0.4.8 → slthcore-0.5.0}/slth/endpoints/whatsappnotification.py +0 -0
  81. {slthcore-0.4.8 → slthcore-0.5.0}/slth/exceptions.py +0 -0
  82. {slthcore-0.4.8/slth/management → slthcore-0.5.0/slth/integrations}/__init__.py +0 -0
  83. {slthcore-0.4.8/slth/management/commands → slthcore-0.5.0/slth/integrations/google}/__init__.py +0 -0
  84. {slthcore-0.4.8/slth/middleware → slthcore-0.5.0/slth/integrations/openai}/__init__.py +0 -0
  85. {slthcore-0.4.8/slth/migrations → slthcore-0.5.0/slth/management}/__init__.py +0 -0
  86. {slthcore-0.4.8 → slthcore-0.5.0}/slth/management/commands/integration_test.py +0 -0
  87. {slthcore-0.4.8 → slthcore-0.5.0}/slth/management/commands/sync.py +0 -0
  88. {slthcore-0.4.8 → slthcore-0.5.0}/slth/management/commands/worker.py +0 -0
  89. {slthcore-0.4.8 → slthcore-0.5.0}/slth/middleware/timezone.py +0 -0
  90. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0001_initial.py +0 -0
  91. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0002_email_role_pushsubscription_error.py +0 -0
  92. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0003_rename_photo_profile_alter_profile_options.py +0 -0
  93. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0004_alter_profile_photo.py +0 -0
  94. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0005_alter_profile_photo.py +0 -0
  95. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0006_user.py +0 -0
  96. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0007_deletion_log.py +0 -0
  97. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0008_alter_deletion_datetime_alter_log_datetime.py +0 -0
  98. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py +0 -0
  99. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0010_email_key_alter_email_action_alter_email_attempt_and_more.py +0 -0
  100. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0011_usertimezone.py +0 -0
  101. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0012_timezone_remove_usertimezone_key_and_more.py +0 -0
  102. {slthcore-0.4.8 → slthcore-0.5.0}/slth/migrations/0013_whatsappnotification.py +0 -0
  103. {slthcore-0.4.8 → slthcore-0.5.0}/slth/notifications.py +0 -0
  104. {slthcore-0.4.8 → slthcore-0.5.0}/slth/pdf/__init__.py +0 -0
  105. {slthcore-0.4.8 → slthcore-0.5.0}/slth/pdf/tests.py +0 -0
  106. {slthcore-0.4.8 → slthcore-0.5.0}/slth/permissions.py +0 -0
  107. {slthcore-0.4.8 → slthcore-0.5.0}/slth/printer.py +0 -0
  108. {slthcore-0.4.8 → slthcore-0.5.0}/slth/roles.py +0 -0
  109. {slthcore-0.4.8 → slthcore-0.5.0}/slth/selenium/__init__.py +0 -0
  110. {slthcore-0.4.8 → slthcore-0.5.0}/slth/selenium/browser.py +0 -0
  111. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/.DS_Store +0 -0
  112. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/css/.DS_Store +0 -0
  113. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/images/placeholder.png +0 -0
  114. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/js/index.min.js +0 -0
  115. {slthcore-0.4.8 → slthcore-0.5.0}/slth/static/js/react.min.js +0 -0
  116. {slthcore-0.4.8 → slthcore-0.5.0}/slth/statistics.py +0 -0
  117. {slthcore-0.4.8 → slthcore-0.5.0}/slth/tasks.py +0 -0
  118. {slthcore-0.4.8 → slthcore-0.5.0}/slth/templates/email.html +0 -0
  119. {slthcore-0.4.8 → slthcore-0.5.0}/slth/templates/report.html +0 -0
  120. {slthcore-0.4.8 → slthcore-0.5.0}/slth/templates/service-worker.js +0 -0
  121. {slthcore-0.4.8 → slthcore-0.5.0}/slth/templates/signature.html +0 -0
  122. {slthcore-0.4.8 → slthcore-0.5.0}/slth/tests.py +0 -0
  123. {slthcore-0.4.8 → slthcore-0.5.0}/slth/threadlocal.py +0 -0
  124. {slthcore-0.4.8 → slthcore-0.5.0}/slth/tz.py +0 -0
  125. {slthcore-0.4.8 → slthcore-0.5.0}/slth/urls.py +0 -0
  126. {slthcore-0.4.8 → slthcore-0.5.0}/slthcore.egg-info/dependency_links.txt +0 -0
  127. {slthcore-0.4.8 → slthcore-0.5.0}/slthcore.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slthcore
3
- Version: 0.4.8
3
+ Version: 0.5.0
4
4
  Summary: API generator based on yml file
5
5
  Home-page: https://github.com/brenokcc
6
6
  Author: Breno Silva
@@ -4,7 +4,7 @@ install_requires = []
4
4
 
5
5
  setup(
6
6
  name='slthcore',
7
- version='0.4.8',
7
+ version='0.5.0',
8
8
  packages=find_packages(),
9
9
  install_requires=install_requires,
10
10
  include_package_data=True,
@@ -64,8 +64,8 @@ class JSONDecoder(json.JSONDecoder):
64
64
  return obj
65
65
 
66
66
 
67
- def dumps(data):
68
- return json.dumps(data, cls=JSONEncoder)
67
+ def dumps(data, indent=1, ensure_ascii=False):
68
+ return json.dumps(data, indent=indent, ensure_ascii=ensure_ascii, cls=JSONEncoder)
69
69
 
70
70
 
71
71
  def loads(data):
@@ -8,7 +8,8 @@ APPLICATION_CLASS = None
8
8
 
9
9
 
10
10
  class Style():
11
- def __init__(self, color="black", background="inherite", border="none"):
11
+ def __init__(self, name, color="black", background="inherite", border="none"):
12
+ self.name = name
12
13
  self.update(color=color, background=background, border=border)
13
14
 
14
15
  def update(self, color=None, background=None, border=None):
@@ -19,18 +20,70 @@ class Style():
19
20
  if border:
20
21
  self.border = border
21
22
 
22
-
23
- class Theme():
23
+ def to_css(self):
24
+ return f"""
25
+ --{self.name}-color: { self.color };
26
+ --{self.name}-border: { self.border };
27
+ --{self.name}-background: { self.background };
28
+ """
29
+
30
+ class ColorSchema:
31
+ def to_css(self):
32
+ css = []
33
+ css.append("<style>")
34
+ css.append(":root{")
35
+ css.append(f"--border-radius: {self.border_radius}px;")
36
+ css.append(self.default.to_css())
37
+ css.append(self.header.to_css())
38
+ css.append(self.footer.to_css())
39
+ css.append(self.fieldset.to_css())
40
+ css.append(self.input.to_css())
41
+ css.append(self.primary.to_css())
42
+ css.append(self.secondary.to_css())
43
+ css.append(self.auxiliary.to_css())
44
+ css.append(self.highlight.to_css())
45
+ css.append(self.info.to_css())
46
+ css.append(self.success.to_css())
47
+ css.append(self.warning.to_css())
48
+ css.append(self.danger.to_css())
49
+ css.append("</style>")
50
+ return "\n".join(css)
51
+
52
+
53
+ class Light(ColorSchema):
24
54
  def __init__(self):
25
- self.primary:Style = Style("#1351b4")
26
- self.secondary:Style = Style("#071e41")
27
- self.auxiliary:Style = Style("#2670e8")
28
- self.highlight:Style = Style("#0c326f")
29
-
30
- self.info:Style = Style("#1351b4", "#d4e5ff")
31
- self.success:Style = Style("#1351b4")
32
- self.warning:Style = Style("#fff5c2")
33
- self.danger:Style = Style("#e52207")
55
+ self.border_radius = 0
56
+ self.default: Style = Style("default", color="#383838", background="#FFFFFF")
57
+ self.header: Style = Style("header", color="#383838", background="#FFFFFF")
58
+ self.footer: Style = Style("footer", color="#383838", background="#FFFFFF")
59
+ self.fieldset: Style = Style("fieldset", color="#383838", background="#FFFFFF")
60
+ self.input: Style = Style("input", border="solid 1px #d9d9d9", background="#FFFFFF")
61
+ self.primary:Style = Style("primary", color="#1351b4", background="#1351b4")
62
+ self.secondary:Style = Style("secondary", color="#071e41")
63
+ self.auxiliary:Style = Style("auxiliary", color="#2670e8", background="#f8f8f8")
64
+ self.highlight:Style = Style("hightlight", color="#0c326f")
65
+ self.info:Style = Style("info", color="#1351b4", background="#d4e5ff")
66
+ self.success:Style = Style("success", color="#ffffff", background="#1351b4")
67
+ self.warning:Style = Style("warning", color="#fff5c2")
68
+ self.danger:Style = Style("danger", color="#e52207")
69
+
70
+
71
+ class Dark(ColorSchema):
72
+ def __init__(self):
73
+ self.border_radius = 3
74
+ self.default: Style = Style("default", color="#c3d0e5", background="#0D1117")
75
+ self.header: Style = Style("header", color="#383838", background="#FFFFFF")
76
+ self.footer: Style = Style("footer", color="#383838", background="#FFFFFF")
77
+ self.fieldset: Style = Style("fieldset", color="#91aad2", background="#262c35")
78
+ self.input: Style = Style("input", border="0", background="#0D1117")
79
+ self.primary:Style = Style("primary", color="#c3d0e5", background="#90C4F9")
80
+ self.secondary:Style = Style("secondary", color="#071e41")
81
+ self.auxiliary:Style = Style("auxiliary", color="#91aad2", background="#262c35")
82
+ self.highlight:Style = Style("hightlight", color="#0c326f")
83
+ self.info:Style = Style("info", color="#c3d0e5", background="#262c35")
84
+ self.success:Style = Style("success", color="#c3d0e5", background="#121f1a", border="1px solid #3b622b")
85
+ self.warning:Style = Style("warning", color="#fff5c2")
86
+ self.danger:Style = Style("danger", color="#e52207")
34
87
 
35
88
 
36
89
  class Groups(dict):
@@ -71,8 +124,8 @@ class Menu(dict):
71
124
  return items
72
125
 
73
126
  class Oauth(list):
74
- def add(self, name, client_id, client_secret, redirect_uri, authorize_url, access_token_url, user_data_url, user_logout_url, user_scope, user_create, user_username, user_email):
75
- super().append(dict(name=name, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, authorize_url=authorize_url, access_token_url=access_token_url, user_data_url=user_data_url, user_logout_url=user_logout_url, user_scope=user_scope, user_create=user_create, user_username=user_username, user_email=user_email))
127
+ def add(self, name, client_id, client_secret, redirect_uri, authorize_url, access_token_url, user_data_url, user_username, user_email=None, user_scope=None, user_create=False, user_logout_url=None):
128
+ super().append(dict(name=name, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, authorize_url=authorize_url, access_token_url=access_token_url, user_data_url=user_data_url, user_username=user_username, user_email=user_email, user_scope=user_scope, user_create=user_create, user_logout_url=user_logout_url))
76
129
 
77
130
  def serialize(self):
78
131
  data = []
@@ -96,6 +149,7 @@ class Dashboard():
96
149
  def __init__(self):
97
150
  self.actions:List = List()
98
151
  self.toolbar:List = List()
152
+ self.todo:List = List()
99
153
  self.top:List = List()
100
154
  self.center:List = List()
101
155
  self.boxes:List = List()
@@ -107,6 +161,12 @@ class Dashboard():
107
161
  self.index = "dashboard"
108
162
 
109
163
 
164
+ class Theme:
165
+ def __init__(self):
166
+ self.light = Light()
167
+ self.dark = Dark()
168
+
169
+
110
170
  class ApplicationMetaclass(type):
111
171
 
112
172
  def __new__(mcs, name, bases, attrs):
@@ -124,6 +184,7 @@ class Application(metaclass=ApplicationMetaclass):
124
184
  self.subtitle = "Take your time!"
125
185
  self.icon = "/static/images/logo.png"
126
186
  self.logo = "/static/images/logo.png"
187
+ self.brand = None
127
188
  self.version = "0.0.1"
128
189
  self.oauth:Oauth = Oauth()
129
190
  self.groups:Groups = Groups()
@@ -136,7 +197,8 @@ class Application(metaclass=ApplicationMetaclass):
136
197
 
137
198
  def serialize(self, request):
138
199
  icon = build_url(request, self.icon)
139
- logo = build_url(request, self.logo)
200
+ logo = build_url(request, self.brand or self.logo)
201
+ title = self.title if self.brand is None else None
140
202
  if request.user.is_authenticated:
141
203
  user = request.user.username.split()[0].split("@")[0]
142
204
  profile = apps.get_model("slth", "profile").objects.filter(user=request.user).first()
@@ -158,7 +220,7 @@ class Application(metaclass=ApplicationMetaclass):
158
220
  type="application",
159
221
  icon=icon,
160
222
  navbar=dict(
161
- type="navbar", title=self.title, subtitle=self.subtitle, logo=logo, user=user, **endpoints
223
+ type="navbar", title=title, subtitle=self.subtitle, logo=logo, user=user, **endpoints
162
224
  ),
163
225
  menu=dict(
164
226
  type="menu", items=self.menu.process(request), user=user, image=photo
@@ -13,6 +13,7 @@ class ApiApplication(Application):
13
13
  "pushsubscription.pushsubscriptions",
14
14
  "job.jobs",
15
15
  "deletion.deletions",
16
+ "settings.settings",
16
17
  "auth.logout",
17
18
  )
18
19
  self.dashboard.boxes.add("user.users")
@@ -95,9 +95,9 @@ class Indicators(dict):
95
95
 
96
96
 
97
97
  class Boxes(dict):
98
- def __init__(self, title):
98
+ def __init__(self, title=None):
99
99
  self["type"] = "boxes"
100
- self["title"] = str(title)
100
+ self["title"] = str(title) if title else None
101
101
  self["items"] = []
102
102
 
103
103
  def append(self, icon, label, url, style=None):
@@ -1,14 +1,13 @@
1
1
  import io
2
- import json
2
+ import os
3
3
  import inspect
4
4
  from ..models import Log
5
5
  from django.apps import apps
6
6
  from typing import TypeVar, Generic
7
7
  from django.core.cache import cache
8
- from django.conf import settings
9
8
  from django.utils.text import slugify
10
9
  from django.db import models
11
- from django.http import JsonResponse, HttpResponse
10
+ from django.http import JsonResponse, HttpResponse, StreamingHttpResponse
12
11
  from ..factory import FormFactory
13
12
  from django.core.exceptions import ValidationError
14
13
  from slth import forms
@@ -26,10 +25,9 @@ from ..components import (
26
25
  from slth.application import Application as ApplicationConfig
27
26
  from ..exceptions import JsonResponseException, ReadyResponseException
28
27
  from ..utils import build_url, append_url
29
- from ..models import Profile, Log, Job
28
+ from ..models import Log, Job
30
29
  from slth.queryset import QuerySet
31
- from slth import ENDPOINTS
32
- from .. import oauth
30
+ from slth import ENDPOINTS, dumps
33
31
  from ..threadlocal import tl
34
32
  from ..tasks import Task
35
33
 
@@ -44,7 +42,8 @@ class ApiResponse(JsonResponse):
44
42
  self["Access-Control-Allow-Headers"] = "*"
45
43
  self["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS, PUT, DELETE, PATCH"
46
44
  self["Access-Control-Max-Age"] = "600"
47
- # print(json.dumps(args[0], indent=1, ensure_ascii=False))
45
+ x = args[0]
46
+ #os.system('clear'); print(dumps(args[0]))
48
47
 
49
48
 
50
49
  class EnpointMetaclass(type):
@@ -65,6 +64,7 @@ class Endpoint(metaclass=EnpointMetaclass):
65
64
  cache = cache
66
65
 
67
66
  def __init__(self):
67
+ self.form: Form | ModelForm = None
68
68
  self.base_url = None
69
69
  self.request = None
70
70
  self.source = None
@@ -92,7 +92,8 @@ class Endpoint(metaclass=EnpointMetaclass):
92
92
  return self.formfactory().fields(*fields) if fields else {}
93
93
 
94
94
  def post(self):
95
- return Response(message="Ação realizada com sucesso")
95
+ redirect = '.' if 'only' in self.request.GET else self.form._redirect
96
+ return Response(message="Ação realizada com sucesso", redirect=redirect)
96
97
 
97
98
  def check_permission(self):
98
99
  return self.request.user.is_superuser
@@ -116,6 +117,7 @@ class Endpoint(metaclass=EnpointMetaclass):
116
117
  raise JsonResponseException(dict(type="redirect", url=url, autosubmit=self.request.GET.get('autosubmit')))
117
118
 
118
119
  def render(self, data, template=None, pdf=False, autoreload=None):
120
+ from django.conf import settings
119
121
  base_url=settings.SITE_URL
120
122
  data.update(base_url=base_url)
121
123
  if template is None:
@@ -150,15 +152,16 @@ class Endpoint(metaclass=EnpointMetaclass):
150
152
  elif isinstance(data, Serializer):
151
153
  data = data.contextualize(self.request).settitle(title)
152
154
  elif isinstance(data, FormFactory):
153
- form = self.getform(data.settitle(title).form(self))
154
- if self.request.method == "POST" or (title and self.request.GET.get("form") == form._key):
155
+ self.form = self.getform(data.settitle(title).build(self))
156
+ if self.request.method == "POST" or (title and self.request.GET.get("form") == self.form._key):
155
157
  try:
156
158
  if isinstance(self, DeleteEndpoint):
157
159
  return self.post()
158
160
  else:
159
- self.cleaned_data = form.submit()
160
- if form._message or form._redirect or form._dispose:
161
- return Response(form._message, form._redirect, dispose=form._dispose)
161
+ self.cleaned_data = self.form.submit()
162
+ if self.form._message or self.form._redirect or self.form._dispose:
163
+ redirect = '.' if 'only' in self.request.GET else self.form._redirect
164
+ return Response(self.form._message, redirect, dispose=self.form._dispose)
162
165
  else:
163
166
  return self.post()
164
167
  except ValidationError as e:
@@ -166,9 +169,11 @@ class Endpoint(metaclass=EnpointMetaclass):
166
169
  dict(type="error", text="\n".join(e.messages), errors={})
167
170
  )
168
171
  else:
169
- data = form
172
+ data = self.form
170
173
  elif isinstance(data, Form) or isinstance(data, ModelForm):
171
174
  data = data.settitle(title)
175
+ elif isinstance(data, HttpResponse) or isinstance(data, StreamingHttpResponse):
176
+ raise ReadyResponseException(data)
172
177
  elif self.request.method == "POST":# and not data:
173
178
  return self.post()
174
179
  return data
@@ -337,7 +342,6 @@ class PublicEndpoint(Endpoint):
337
342
  return True
338
343
 
339
344
 
340
-
341
345
  class ModelEndpoint(Endpoint):
342
346
  def __init__(self):
343
347
  self.model = self.__orig_bases__[0].__args__[0]
@@ -503,6 +507,43 @@ class ChildInstanceEndpoint(ChildEndpoint):
503
507
  return Serializer(self.get_instance()).contextualize(self.request)
504
508
 
505
509
 
510
+ class RelationEditEndpoint(Generic[T], ChildEndpoint):
511
+
512
+ def __init__(self, instance):
513
+ self.source = instance
514
+
515
+ def get(self) -> FormFactory:
516
+ return self.formfactory()
517
+
518
+ def formfactory(self) -> FormFactory:
519
+ return FormFactory(self.get_instance())
520
+
521
+ def get_instance(self):
522
+ return self.__orig_bases__[0].__args__[0].objects.get(pk=self.request.GET['id'])
523
+
524
+
525
+ class RelationDeleteEndpoint(Generic[T], ChildEndpoint):
526
+
527
+ def __init__(self, instance):
528
+ self.model = self.__orig_bases__[0].__args__[0]
529
+ self.source = instance
530
+
531
+ def get(self) -> FormFactory:
532
+ return FormFactory(self.get_instance()).fields()
533
+
534
+ def post(self):
535
+ self.get_instance().safe_delete(self.request.user.username)
536
+ return super().post()
537
+
538
+ def formfactory(self) -> FormFactory:
539
+ return FormFactory(self.get_instance())
540
+
541
+ def get_instance(self):
542
+ return self.model.objects.get(pk=self.request.GET['id'])
543
+
544
+
545
+
546
+
506
547
  class Search(Endpoint):
507
548
  def get(self):
508
549
  key = "_options_"
@@ -529,7 +570,6 @@ class Search(Endpoint):
529
570
  return result[0:10]
530
571
 
531
572
 
532
-
533
573
  class Home(PublicEndpoint):
534
574
  class Meta:
535
575
  verbose_name = ""
@@ -546,36 +586,36 @@ class Dashboard(Endpoint):
546
586
 
547
587
  def get(self):
548
588
  application = ApplicationConfig.get_instance()
549
- serializer = Serializer(request=self.request)
589
+ serializer = self.serializer()
590
+ if application.dashboard.actions:
591
+ serializer.actions(*application.dashboard.actions)
592
+ if application.dashboard.todo:
593
+ serializer.todo(*application.dashboard.todo)
594
+ if application.dashboard.top:
595
+ group = serializer.group("Top")
596
+ for name in application.dashboard.top:
597
+ cls = ENDPOINTS[name]
598
+ endpoint = cls.instantiate(self.request, self)
599
+ if endpoint.check_permission():
600
+ group.endpoint(cls)
601
+ group.parent()
550
602
  if application.dashboard.boxes:
551
603
  boxes = Boxes("Acesso Rápido")
552
604
  for name in application.dashboard.boxes:
553
605
  cls = ENDPOINTS[name]
554
606
  endpoint = cls().contextualize(self.request)
555
607
  if endpoint.check_permission():
556
- icon = endpoint.get_icon() or "check"
608
+ icon = endpoint.get_icon() or "link"
557
609
  label = endpoint.get_verbose_name()
558
610
  url = build_url(self.request, cls.get_api_url())
559
611
  boxes.append(icon, label, url)
560
- serializer.append("Acesso Rápido", boxes)
561
- if application.dashboard.top:
562
- group = serializer.group("Top")
563
- for name in application.dashboard.top:
564
- cls = ENDPOINTS[name]
565
- endpoint = cls.instantiate(self.request, self)
566
- if endpoint.check_permission():
567
- group.endpoint(
568
- endpoint.get_verbose_name(), cls, wrap=False
569
- )
570
- group.parent()
612
+ serializer.append(boxes)
571
613
  if application.dashboard.center:
572
614
  for name in application.dashboard.center:
573
615
  cls = ENDPOINTS[name]
574
616
  endpoint = cls.instantiate(self.request, self)
575
617
  if endpoint.check_permission():
576
- serializer.endpoint(
577
- endpoint.get_verbose_name(), cls, wrap=False
578
- )
618
+ serializer.endpoint(cls)
579
619
  return serializer
580
620
 
581
621
  def check_permission(self):
@@ -0,0 +1,60 @@
1
+ from slth import endpoints
2
+ from ..models import Settings as SettingsModel
3
+
4
+
5
+ class Settings(endpoints.ListEndpoint[SettingsModel]):
6
+ class Meta:
7
+ modal = False
8
+ verbose_name = 'Configurações'
9
+
10
+ def get(self):
11
+ return (
12
+ super().get()
13
+ .actions('settings.add', 'settings.view', 'settings.edit', 'settings.delete')
14
+ )
15
+
16
+
17
+ class Add(endpoints.AddEndpoint[SettingsModel]):
18
+ class Meta:
19
+ icon = 'plus'
20
+ verbose_name = 'Cadastrar Configuração'
21
+
22
+ def get(self):
23
+ return (
24
+ super().get()
25
+ )
26
+
27
+
28
+ class View(endpoints.ViewEndpoint[SettingsModel]):
29
+ class Meta:
30
+ modal = False
31
+ icon = 'eye'
32
+ verbose_name = 'Visualizar Configuração'
33
+
34
+ def get(self):
35
+ return (
36
+ super().get()
37
+ )
38
+
39
+
40
+ class Edit(endpoints.EditEndpoint[SettingsModel]):
41
+ class Meta:
42
+ icon = 'pen'
43
+ verbose_name = 'Editar Configuração'
44
+
45
+ def get(self):
46
+ return (
47
+ super().get()
48
+ )
49
+
50
+
51
+ class Delete(endpoints.DeleteEndpoint[SettingsModel]):
52
+ class Meta:
53
+ icon = 'trash'
54
+ verbose_name = 'Excluir Configuração'
55
+
56
+ def get(self):
57
+ return (
58
+ super().get()
59
+ )
60
+
@@ -9,7 +9,8 @@ class Users(endpoints.ListEndpoint[User]):
9
9
 
10
10
 
11
11
  class Add(endpoints.AddEndpoint[User]):
12
- pass
12
+ class Meta:
13
+ icon = "user-plus"
13
14
 
14
15
 
15
16
  class View(endpoints.ViewEndpoint[User]):
@@ -17,11 +18,13 @@ class View(endpoints.ViewEndpoint[User]):
17
18
 
18
19
 
19
20
  class Edit(endpoints.EditEndpoint[User]):
20
- pass
21
+ class Meta:
22
+ icon = "user-pen"
21
23
 
22
24
 
23
25
  class Delete(endpoints.DeleteEndpoint[User]):
24
- pass
26
+ class Meta:
27
+ icon = "user-minus"
25
28
 
26
29
 
27
30
  class ChangePassword(endpoints.ChildInstanceEndpoint):
@@ -3,7 +3,7 @@ from .serializer import Serializer
3
3
 
4
4
 
5
5
  class FormFactory:
6
- def __init__(self, instance, endpoint=None, method='POST'):
6
+ def __init__(self, instance, method='POST'):
7
7
  self._instance = instance
8
8
  self._fieldsets = {}
9
9
  self._values = {}
@@ -48,7 +48,7 @@ class FormFactory:
48
48
  self._append_field(field_name)
49
49
  for k in values:
50
50
  self._append_field(k)
51
- self.setvalue(**values)
51
+ self.values(**values)
52
52
  self._empty = not self._fieldlist
53
53
  return self
54
54
 
@@ -84,7 +84,7 @@ class FormFactory:
84
84
  self._actions.update(kwargs)
85
85
  return self
86
86
 
87
- def setvalue(self, **kwargs) -> 'FormFactory':
87
+ def values(self, **kwargs) -> 'FormFactory':
88
88
  self._values.update(kwargs)
89
89
  return self
90
90
 
@@ -106,7 +106,7 @@ class FormFactory:
106
106
  self._redirect = '.'
107
107
  return self
108
108
 
109
- def form(self, endpoint):
109
+ def build(self, endpoint):
110
110
  from .forms import ModelForm, Form
111
111
 
112
112
  if isinstance(self._instance, Model):
@@ -135,7 +135,7 @@ class FormFactory:
135
135
  for name, queryset in self._choices.items():
136
136
  form.fields[name].queryset = queryset
137
137
  form.fieldsets = self._fieldsets
138
- form.setvalue(**self._values)
138
+ form.values(**self._values)
139
139
  if self._display:
140
140
  serializer = Serializer(self._instance, request=endpoint.request)
141
141
  for title, fields in self._display.items():