slthcore 0.2.1__tar.gz → 0.2.2__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 (89) hide show
  1. {slthcore-0.2.1/slthcore.egg-info → slthcore-0.2.2}/PKG-INFO +1 -1
  2. {slthcore-0.2.1 → slthcore-0.2.2}/setup.py +1 -1
  3. {slthcore-0.2.1 → slthcore-0.2.2}/slth/endpoints.py +94 -70
  4. {slthcore-0.2.1 → slthcore-0.2.2}/slth/forms.py +3 -2
  5. {slthcore-0.2.1 → slthcore-0.2.2}/slth/pdf/__init__.py +3 -0
  6. {slthcore-0.2.1 → slthcore-0.2.2}/slth/queryset.py +7 -5
  7. {slthcore-0.2.1 → slthcore-0.2.2}/slth/serializer.py +9 -6
  8. {slthcore-0.2.1 → slthcore-0.2.2}/slth/urls.py +6 -2
  9. {slthcore-0.2.1 → slthcore-0.2.2}/slth/views.py +2 -1
  10. {slthcore-0.2.1 → slthcore-0.2.2/slthcore.egg-info}/PKG-INFO +1 -1
  11. {slthcore-0.2.1 → slthcore-0.2.2}/MANIFEST.in +0 -0
  12. {slthcore-0.2.1 → slthcore-0.2.2}/setup.cfg +0 -0
  13. {slthcore-0.2.1 → slthcore-0.2.2}/slth/__init__.py +0 -0
  14. {slthcore-0.2.1 → slthcore-0.2.2}/slth/apps.py +0 -0
  15. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/configure/__main__.py +0 -0
  16. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/__main__.py +0 -0
  17. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/.DS_Store +0 -0
  18. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/.gitignore +0 -0
  19. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/__init__.py +0 -0
  20. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/asgi.py +0 -0
  21. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/endpoints.py +0 -0
  22. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/models.py +0 -0
  23. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/settings.py +0 -0
  24. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/tests.py +0 -0
  25. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/urls.py +0 -0
  26. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/api/wsgi.py +0 -0
  27. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/application.yml +0 -0
  28. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/entrypoint.sh +0 -0
  29. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/manage.py +0 -0
  30. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/backend/requirements.txt +0 -0
  31. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/base.env +0 -0
  32. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/docker-compose.yml +0 -0
  33. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/frontend/package.json +0 -0
  34. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/frontend/src/main.jsx +0 -0
  35. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/frontend/vite.config.js +0 -0
  36. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/local.env +0 -0
  37. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/run.sh +0 -0
  38. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/selenium/run.sh +0 -0
  39. {slthcore-0.2.1 → slthcore-0.2.2}/slth/cmd/init/boilerplate/test.sh +0 -0
  40. {slthcore-0.2.1 → slthcore-0.2.2}/slth/components.py +0 -0
  41. {slthcore-0.2.1 → slthcore-0.2.2}/slth/db/__init__.py +0 -0
  42. {slthcore-0.2.1 → slthcore-0.2.2}/slth/db/generic.py +0 -0
  43. {slthcore-0.2.1 → slthcore-0.2.2}/slth/db/models.py +0 -0
  44. {slthcore-0.2.1 → slthcore-0.2.2}/slth/exceptions.py +0 -0
  45. {slthcore-0.2.1 → slthcore-0.2.2}/slth/factory.py +0 -0
  46. {slthcore-0.2.1 → slthcore-0.2.2}/slth/management/__init__.py +0 -0
  47. {slthcore-0.2.1 → slthcore-0.2.2}/slth/management/commands/__init__.py +0 -0
  48. {slthcore-0.2.1 → slthcore-0.2.2}/slth/management/commands/integration_test.py +0 -0
  49. {slthcore-0.2.1 → slthcore-0.2.2}/slth/management/commands/sync.py +0 -0
  50. {slthcore-0.2.1 → slthcore-0.2.2}/slth/middleware/__init__.py +0 -0
  51. {slthcore-0.2.1 → slthcore-0.2.2}/slth/middleware/timezone.py +0 -0
  52. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0001_initial.py +0 -0
  53. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0002_email_role_pushsubscription_error.py +0 -0
  54. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0003_rename_photo_profile_alter_profile_options.py +0 -0
  55. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0004_alter_profile_photo.py +0 -0
  56. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0005_alter_profile_photo.py +0 -0
  57. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0006_user.py +0 -0
  58. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0007_deletion_log.py +0 -0
  59. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0008_alter_deletion_datetime_alter_log_datetime.py +0 -0
  60. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py +0 -0
  61. {slthcore-0.2.1 → slthcore-0.2.2}/slth/migrations/__init__.py +0 -0
  62. {slthcore-0.2.1 → slthcore-0.2.2}/slth/models.py +0 -0
  63. {slthcore-0.2.1 → slthcore-0.2.2}/slth/notifications.py +0 -0
  64. {slthcore-0.2.1 → slthcore-0.2.2}/slth/oauth.py +0 -0
  65. {slthcore-0.2.1 → slthcore-0.2.2}/slth/pdf/tests.py +0 -0
  66. {slthcore-0.2.1 → slthcore-0.2.2}/slth/permissions.py +0 -0
  67. {slthcore-0.2.1 → slthcore-0.2.2}/slth/printer.py +0 -0
  68. {slthcore-0.2.1 → slthcore-0.2.2}/slth/roles.py +0 -0
  69. {slthcore-0.2.1 → slthcore-0.2.2}/slth/selenium/__init__.py +0 -0
  70. {slthcore-0.2.1 → slthcore-0.2.2}/slth/selenium/browser.py +0 -0
  71. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/.DS_Store +0 -0
  72. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/css/.DS_Store +0 -0
  73. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/css/slth.css +0 -0
  74. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/js/index.min.js +0 -0
  75. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/js/react.min.js +0 -0
  76. {slthcore-0.2.1 → slthcore-0.2.2}/slth/static/js/slth.min.js +0 -0
  77. {slthcore-0.2.1 → slthcore-0.2.2}/slth/statistics.py +0 -0
  78. {slthcore-0.2.1 → slthcore-0.2.2}/slth/tasks.py +0 -0
  79. {slthcore-0.2.1 → slthcore-0.2.2}/slth/templates/email.html +0 -0
  80. {slthcore-0.2.1 → slthcore-0.2.2}/slth/templates/index.html +0 -0
  81. {slthcore-0.2.1 → slthcore-0.2.2}/slth/templates/report.html +0 -0
  82. {slthcore-0.2.1 → slthcore-0.2.2}/slth/templates/service-worker.js +0 -0
  83. {slthcore-0.2.1 → slthcore-0.2.2}/slth/templates/signature.html +0 -0
  84. {slthcore-0.2.1 → slthcore-0.2.2}/slth/tests.py +0 -0
  85. {slthcore-0.2.1 → slthcore-0.2.2}/slth/threadlocal.py +0 -0
  86. {slthcore-0.2.1 → slthcore-0.2.2}/slth/utils.py +0 -0
  87. {slthcore-0.2.1 → slthcore-0.2.2}/slthcore.egg-info/SOURCES.txt +0 -0
  88. {slthcore-0.2.1 → slthcore-0.2.2}/slthcore.egg-info/dependency_links.txt +0 -0
  89. {slthcore-0.2.1 → slthcore-0.2.2}/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.2.1
3
+ Version: 0.2.2
4
4
  Summary: API generator based on yml file
5
5
  Home-page: https://github.com/brenokcc
6
6
  Author: Breno Silva
@@ -5,7 +5,7 @@ install_requires = []
5
5
 
6
6
  setup(
7
7
  name='slthcore',
8
- version='0.2.1',
8
+ version='0.2.2',
9
9
  packages=find_packages(),
10
10
  install_requires=install_requires,
11
11
  include_package_data=True,
@@ -62,41 +62,9 @@ class EnpointMetaclass(type):
62
62
  name not in ("Endpoint", "ChildEndpoint")
63
63
  and "_ChildEndpoint" not in bases_names
64
64
  ):
65
- ENDPOINTS[cls.__name__.lower()] = cls
66
- if "AdminEndpoint" in bases_names[0:1]:
67
- model = cls.__orig_bases__[0].__args__[0]
68
- items = (
69
- ("Cadastrar", AddEndpoint[model], "plus", "add"),
70
- ("Editar", EditEndpoint[model], "pen", "edit"),
71
- ("Visualizar", ViewEndpoint[model], "eye", "view"),
72
- ("Excluir", DeleteEndpoint[model], "trash", "delete"),
73
- )
74
- for prefix, base, icon, action in items:
75
- endpoint = types.new_class(f"{prefix}{model.__name__}", (base,), {})
76
- endpoint.__admin__ = cls
77
- endpoint.__action__ = action
78
- endpoint.check_permission = lambda self: (
79
- getattr(self.__admin__.instantiate(self.request, self), f'check_{self.__action__}_permission')()
80
- )
81
- endpoint.Meta = type(
82
- "Meta",
83
- (),
84
- dict(
85
- icon=icon,
86
- modal=prefix != "Visualizar",
87
- verbose_name=f"{prefix} {model._meta.verbose_name}",
88
- ),
89
- )
90
- if "Meta" not in attrs:
91
- cls.Meta = type(
92
- "Meta",
93
- (),
94
- dict(
95
- icon=getattr(model._meta, "icon", None),
96
- modal=False,
97
- verbose_name=f"{model._meta.verbose_name_plural}",
98
- ),
99
- )
65
+ module = cls.__module__.split('.')[-1]
66
+ key = cls.__name__.lower() if module == 'endpoints' else f'{module}.{cls.__name__.lower()}'
67
+ ENDPOINTS[key] = cls
100
68
  return cls
101
69
 
102
70
 
@@ -230,12 +198,34 @@ class Endpoint(metaclass=EnpointMetaclass):
230
198
  @classmethod
231
199
  def get_api_name(cls):
232
200
  return cls.__name__.lower()
201
+
202
+ @classmethod
203
+ def get_key_name(cls):
204
+ module = cls.__module__.split('.')[-1]
205
+ if module == 'endpoints':
206
+ return cls.get_api_name()
207
+ else:
208
+ return "{}.{}".format(module, cls.get_api_name())
209
+
210
+ @classmethod
211
+ def get_default_actions(cls):
212
+ actions = ['add', 'view', 'edit', 'delete']
213
+ module = cls.__module__.split('.')[-1]
214
+ if module == 'endpoints':
215
+ return actions
216
+ else:
217
+ return [f'{module}.{name}' for name in actions if f'{module}.{name}' in ENDPOINTS]
233
218
 
234
219
  @classmethod
235
220
  def get_api_url(cls, arg=None):
221
+ module = cls.__module__.split('.')[-1]
222
+ if module == 'endpoints':
223
+ url = "/api/{}/".format(cls.get_api_name())
224
+ else:
225
+ url = "/api/{}/{}/".format(module, cls.get_api_name())
236
226
  if arg:
237
- return f"/api/{cls.get_api_name()}/{arg}/"
238
- return f"/api/{cls.get_api_name()}/"
227
+ url = f"{url}{arg}/"
228
+ return url
239
229
 
240
230
  @classmethod
241
231
  def get_pretty_name(cls):
@@ -246,10 +236,6 @@ class Endpoint(metaclass=EnpointMetaclass):
246
236
  name.append(c)
247
237
  return "".join(name)
248
238
 
249
- @classmethod
250
- def get_qualified_name(cls):
251
- return "{}.{}".format(cls.__module__, cls.__name__).lower()
252
-
253
239
  @classmethod
254
240
  def instantiate(cls, request, source):
255
241
  args = ()
@@ -266,28 +252,31 @@ class Endpoint(metaclass=EnpointMetaclass):
266
252
  @classmethod
267
253
  def get_api_url_pattern(cls):
268
254
  args = inspect.getfullargspec(cls.__init__).args[1:]
269
- pattern = "{}/".format(cls.get_api_name())
255
+ module = cls.__module__.split('.')[-1]
256
+ if module == 'endpoints':
257
+ pattern = "{}/".format(cls.get_api_name())
258
+ else:
259
+ pattern = "{}/{}/".format(module, cls.get_api_name())
270
260
  for arg in args:
271
261
  pattern = "{}{}/".format(pattern, "<str:{}>".format(arg))
272
262
  return pattern
273
263
 
274
- @classmethod
275
- def get_api_metadata(cls, request, base_url, pk=None):
276
- action_name = cls.get_metadata("verbose_name")
277
- icon = cls.get_metadata("icon")
278
- modal = cls.get_metadata("modal")
279
- if cls.is_child():
280
- url = append_url(base_url, f"action={cls.get_api_name()}")
264
+ def get_api_metadata(self, request, base_url, pk=None):
265
+ action_name = self.get_verbose_name()
266
+ icon = self.get_metadata("icon")
267
+ modal = self.get_metadata("modal")
268
+ if self.is_child():
269
+ url = append_url(base_url, f"action={self.get_key_name()}")
281
270
  url = f"{url}&id={pk}" if pk else url
282
271
  else:
283
- url = build_url(request, f"/api/{cls.get_api_name()}/")
272
+ url = build_url(request, self.get_api_url())
284
273
  url = f"{url}{pk}/" if pk else url
285
274
  return dict(
286
275
  type="action",
287
276
  title=action_name,
288
277
  name=action_name,
289
278
  url=url,
290
- key=cls.get_api_name(),
279
+ key=self.get_api_name(),
291
280
  icon=icon,
292
281
  modal=modal,
293
282
  )
@@ -299,8 +288,6 @@ class Endpoint(metaclass=EnpointMetaclass):
299
288
  if metaclass:
300
289
  value = getattr(metaclass, key, None)
301
290
  if value is None:
302
- if key == "verbose_name":
303
- value = cls.get_pretty_name()
304
291
  if key == "modal":
305
292
  value = (
306
293
  issubclass(cls, EditEndpoint)
@@ -313,6 +300,9 @@ class Endpoint(metaclass=EnpointMetaclass):
313
300
  def get_verbose_name(self):
314
301
  return self.get_metadata("verbose_name")
315
302
 
303
+ def get_icon(self):
304
+ return self.get_metadata("icon")
305
+
316
306
  def get_instance(self):
317
307
  return None
318
308
 
@@ -362,6 +352,9 @@ class ModelEndpoint(Endpoint):
362
352
  self.model = self.objects(self.model).get(pk=self.pk)
363
353
  super().__init__()
364
354
 
355
+ def get_icon(self):
356
+ return self.model._meta.icon or super().get_icon()
357
+
365
358
 
366
359
  class AdminEndpoint(Generic[T], ModelEndpoint):
367
360
 
@@ -385,12 +378,33 @@ class AdminEndpoint(Generic[T], ModelEndpoint):
385
378
  return self.check_permission()
386
379
 
387
380
 
388
- class ListEndpoint(Generic[T], ModelEndpoint):
381
+ class QuerySetEndpoint(Generic[T], ModelEndpoint):
382
+ class Meta:
383
+ modal = False
384
+
389
385
  def get(self) -> QuerySet:
390
386
  return self.model.objects.contextualize(self.request)
387
+
388
+ def get_verbose_name(self):
389
+ return self.get_metadata('verbose_name', self.model._meta.verbose_name_plural)
390
+
391
+
392
+ class ListEndpoint(Generic[T], ModelEndpoint):
393
+ class Meta:
394
+ modal = False
395
+
396
+ def get(self) -> QuerySet:
397
+ return self.model.objects.all().contextualize(self.request).actions(*self.get_default_actions())
398
+
399
+ def get_verbose_name(self):
400
+ return self.get_metadata('verbose_name', self.model._meta.verbose_name_plural)
391
401
 
392
402
 
393
403
  class AddEndpoint(Generic[T], ModelEndpoint):
404
+ class Meta:
405
+ icon = 'plus'
406
+ modal = True
407
+
394
408
  def __init__(self):
395
409
  super().__init__()
396
410
  self.instance = self.model()
@@ -403,6 +417,9 @@ class AddEndpoint(Generic[T], ModelEndpoint):
403
417
 
404
418
  def formfactory(self):
405
419
  return self.instance.formfactory()
420
+
421
+ def get_verbose_name(self):
422
+ return f'Cadastrar {self.model._meta.verbose_name}'
406
423
 
407
424
 
408
425
  class ModelInstanceEndpoint(ModelEndpoint):
@@ -428,21 +445,28 @@ class ViewEndpoint(Generic[T], ModelInstanceEndpoint):
428
445
  class Meta:
429
446
  icon = "eye"
430
447
  modal = False
431
- verbose_name = "Visualizar"
448
+ verbose_name = 'Visualizar'
432
449
 
433
450
  def get(self) -> Serializer:
434
451
  return self.get_instance().serializer().contextualize(self.request)
435
452
 
436
- def get_verbose_name(self):
437
- return str(self.get_instance())
438
-
439
453
 
440
454
  class EditEndpoint(Generic[T], ModelInstanceEndpoint):
455
+ class Meta:
456
+ modal = True
457
+ icon = 'pen'
458
+ verbose_name = 'Editar'
459
+
441
460
  def get(self) -> FormFactory:
442
461
  return self.get_instance().formfactory()
443
462
 
444
463
 
445
464
  class DeleteEndpoint(Generic[T], ModelInstanceEndpoint):
465
+ class Meta:
466
+ modal = True
467
+ icon = 'trash'
468
+ verbose_name = 'Excluir'
469
+
446
470
  def get(self) -> FormFactory:
447
471
  return self.formfactory(self.get_instance()).fields()
448
472
 
@@ -741,28 +765,28 @@ class Dashboard(Endpoint):
741
765
  serializer = Serializer(request=self.request)
742
766
  if APPLICATON["dashboard"]["boxes"]:
743
767
  boxes = Boxes("Acesso Rápido")
744
- for endpoint in APPLICATON["dashboard"]["boxes"]:
745
- cls = ENDPOINTS[endpoint]
746
- if cls().contextualize(self.request).check_permission():
747
- icon = cls.get_metadata("icon", "check")
748
- label = cls.get_metadata("verbose_name")
768
+ for name in APPLICATON["dashboard"]["boxes"]:
769
+ cls = ENDPOINTS[name]
770
+ endpoint = cls().contextualize(self.request)
771
+ if endpoint.check_permission():
772
+ icon = endpoint.get_icon() or "check"
773
+ label = endpoint.get_verbose_name()
749
774
  url = build_url(self.request, cls.get_api_url())
750
775
  boxes.append(icon, label, url)
751
776
  serializer.append("Acesso Rápido", boxes)
752
777
  if APPLICATON["dashboard"]["top"]:
753
778
  group = serializer.group("Top")
754
- for endpoint in APPLICATON["dashboard"]["top"]:
755
- cls = ENDPOINTS[endpoint]
756
- if cls.instantiate(
757
- self.request, self.request.user
758
- ).check_permission():
779
+ for name in APPLICATON["dashboard"]["top"]:
780
+ cls = ENDPOINTS[name]
781
+ endpoint = cls.instantiate(self.request, self.request.user)
782
+ if endpoint.check_permission():
759
783
  group.endpoint(
760
784
  cls.get_metadata("verbose_name"), cls, wrap=False
761
785
  )
762
786
  group.parent()
763
787
  if APPLICATON["dashboard"]["center"]:
764
- for endpoint in APPLICATON["dashboard"]["center"]:
765
- cls = ENDPOINTS[endpoint]
788
+ for name in APPLICATON["dashboard"]["center"]:
789
+ cls = ENDPOINTS[name]
766
790
  serializer.endpoint(
767
791
  cls.get_metadata("verbose_name"), cls, wrap=False
768
792
  )
@@ -386,9 +386,10 @@ class FormMixin:
386
386
  data["onchange"] = absolute_url(self.request, f"on_change={name}")
387
387
  if name in self._actions:
388
388
  cls = ENDPOINTS[self._actions[name]]
389
- if cls.instantiate(self.request, self).check_permission():
389
+ endpoint = cls.instantiate(self.request, self)
390
+ if endpoint.check_permission():
390
391
  data.update(
391
- action=cls.get_api_metadata(
392
+ action=endpoint.get_api_metadata(
392
393
  self.request, absolute_url(self.request)
393
394
  )
394
395
  )
@@ -28,6 +28,9 @@ class PdfWriter:
28
28
  def render(self, template_name, context):
29
29
  context.update(base_url=settings.SITE_URL)
30
30
  html = render_to_string(template_name, context)
31
+ self.write(html)
32
+
33
+ def write(self, html):
31
34
  self.pdf.write_html(html, tag_styles=STYLE, font_family="Courier")
32
35
 
33
36
  def save(self, path):
@@ -261,9 +261,10 @@ class QuerySet(models.QuerySet):
261
261
  queryset_actions.append(cls)
262
262
 
263
263
  for cls in queryset_actions:
264
- if cls.instantiate(self.request, self).check_permission():
265
- action = cls.get_api_metadata(self.request, base_url)
266
- action['name'] = action['name'].replace(" {}".format(self.model._meta.verbose_name.title()), "")
264
+ endpoint = cls.instantiate(self.request, self)
265
+ if endpoint.check_permission():
266
+ action = endpoint.get_api_metadata(self.request, base_url)
267
+ #action['name'] = action['name'].replace(" {}".format(self.model._meta.verbose_name.title()), "")
267
268
  if relations and cls.get_metadata('modal'):
268
269
  params = '&'.join(f'{k}={v}' for k, v in relations.items())
269
270
  action['url'] = append_url(action['url'], params)
@@ -357,8 +358,9 @@ class QuerySet(models.QuerySet):
357
358
  serializer.obj = obj
358
359
  serialized = serializer.serialize(forward_exception=True)
359
360
  for cls in instance_actions:
360
- if cls.instantiate(self.request, obj).check_permission():
361
- action = cls.get_api_metadata(self.request, base_url, obj.pk)
361
+ endpoint = cls.instantiate(self.request, obj)
362
+ if endpoint.check_permission():
363
+ action = endpoint.get_api_metadata(self.request, base_url, obj.pk)
362
364
  action['name'] = action['name'].replace(" {}".format(self.model._meta.verbose_name), "")
363
365
  if relations and cls.get_metadata('modal'):
364
366
  params = '&'.join(f'{k}={v}' for k, v in relations.items())
@@ -170,7 +170,8 @@ class Serializer:
170
170
  return self
171
171
 
172
172
  def settitle(self, title) -> 'Serializer':
173
- self.title = title
173
+ if title != 'Visualizar':
174
+ self.title = title
174
175
  return self
175
176
 
176
177
  def serialize(self, debug=False, forward_exception=False):
@@ -214,7 +215,7 @@ class Serializer:
214
215
 
215
216
  if self.request and 'action' in self.request.GET:
216
217
  cls = slth.ENDPOINTS[self.request.GET.get('action')]
217
- if cls and cls.get_api_name() in self.metadata['allow']:
218
+ if cls:### and cls.get_key_name() in self.metadata['allow']:
218
219
  endpoint = cls.instantiate(self.request, self.obj)
219
220
  if endpoint.check_permission():
220
221
  raise JsonResponseException(endpoint.serialize())
@@ -224,8 +225,9 @@ class Serializer:
224
225
  leaf = only and only[-1] == 'actions'
225
226
  for qualified_name in self.metadata['actions']:
226
227
  cls = slth.ENDPOINTS[qualified_name]
227
- if cls.instantiate(self.request, self.obj).check_permission():
228
- action = cls.get_api_metadata(self.request, base_url, self.obj.pk)
228
+ endpoint = cls.instantiate(self.request, self.obj)
229
+ if endpoint.check_permission():
230
+ action = endpoint.get_api_metadata(self.request, base_url, self.obj.pk)
229
231
  action['name'] = action['name'].replace(' {}'.format(self.obj._meta.verbose_name), '')
230
232
  actions.append(action)
231
233
  if leaf:
@@ -278,8 +280,9 @@ class Serializer:
278
280
  fieldset_fields.append(getfield(obj, name, self.request))
279
281
  for qualified_name in item['actions']:
280
282
  cls = slth.ENDPOINTS[qualified_name]
281
- if obj and cls.instantiate(self.request, obj).check_permission():
282
- fieldset_actions.append(cls.get_api_metadata(self.request, base_url, obj.pk))
283
+ endpoint = cls.instantiate(self.request, obj)
284
+ if obj and endpoint.check_permission():
285
+ fieldset_actions.append(endpoint.get_api_metadata(self.request, base_url, obj.pk))
283
286
  data = dict(type='fieldset', title=title, key=key, url=url if reload else None, actions=fieldset_actions, data=fieldset_fields)
284
287
  if leaf: raise JsonResponseException(data)
285
288
  elif datatype == 'queryset':
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import slth
2
3
  from django.apps import apps
3
4
  from django.conf import settings
@@ -13,8 +14,11 @@ for app_label in settings.INSTALLED_APPS:
13
14
  app = apps.get_app_config(app_label.split('.')[-1])
14
15
  fromlist = app.module.__package__.split('.')
15
16
  if app_label != 'slth':
16
- __import__('{}.{}'.format(app_label, 'endpoints'), fromlist=fromlist)
17
- except ImportError as e:
17
+ module = __import__('{}.{}'.format(app_label, 'endpoints'), fromlist=fromlist)
18
+ if os.path.dirname(module.__file__).endswith('endpoints'):
19
+ for name in [name for name in os.listdir(os.path.dirname(module.__file__)) if name.endswith('.py') and not name.startswith('__init__')]:
20
+ __import__('{}.{}.{}'.format(app_label, 'endpoints', name[0:-3]), fromlist=fromlist)
21
+ except ModuleNotFoundError as e:
18
22
  if not e.name.endswith('endpoints'):
19
23
  raise e
20
24
  except BaseException as e:
@@ -39,7 +39,8 @@ def dispatcher(request, **kwargs):
39
39
  url = build_url(request, cls.get_api_url())
40
40
  return ApiResponse(dict(type='redirect', url=url))
41
41
  else:
42
- cls = slth.ENDPOINTS.get(request.path.split('/')[2])
42
+ tokens = [token for token in request.path.split('/')[2:] if token and not token.isdigit()]
43
+ cls = slth.ENDPOINTS.get('.'.join(tokens))
43
44
  if cls:
44
45
  endpoint = None
45
46
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slthcore
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: API generator based on yml file
5
5
  Home-page: https://github.com/brenokcc
6
6
  Author: Breno Silva
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes