slthcore 0.2.0__tar.gz → 0.2.1__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 (90) hide show
  1. {slthcore-0.2.0/slthcore.egg-info → slthcore-0.2.1}/PKG-INFO +1 -1
  2. {slthcore-0.2.0 → slthcore-0.2.1}/setup.py +1 -1
  3. slthcore-0.2.1/slth/apps.py +9 -0
  4. {slthcore-0.2.0 → slthcore-0.2.1}/slth/db/models.py +14 -1
  5. {slthcore-0.2.0 → slthcore-0.2.1}/slth/endpoints.py +9 -4
  6. slthcore-0.2.1/slth/middleware/timezone.py +25 -0
  7. slthcore-0.2.1/slth/migrations/0008_alter_deletion_datetime_alter_log_datetime.py +24 -0
  8. slthcore-0.2.1/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py +43 -0
  9. slthcore-0.2.1/slth/migrations/__init__.py +0 -0
  10. {slthcore-0.2.0 → slthcore-0.2.1}/slth/models.py +42 -15
  11. {slthcore-0.2.0 → slthcore-0.2.1}/slth/pdf/__init__.py +5 -5
  12. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/js/slth.min.js +15 -15
  13. slthcore-0.2.1/slth/templates/email.html +155 -0
  14. {slthcore-0.2.0 → slthcore-0.2.1/slthcore.egg-info}/PKG-INFO +1 -1
  15. {slthcore-0.2.0 → slthcore-0.2.1}/slthcore.egg-info/SOURCES.txt +6 -1
  16. slthcore-0.2.0/slth/middleware.py +0 -24
  17. {slthcore-0.2.0 → slthcore-0.2.1}/MANIFEST.in +0 -0
  18. {slthcore-0.2.0 → slthcore-0.2.1}/setup.cfg +0 -0
  19. {slthcore-0.2.0 → slthcore-0.2.1}/slth/__init__.py +0 -0
  20. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/configure/__main__.py +0 -0
  21. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/__main__.py +0 -0
  22. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/.DS_Store +0 -0
  23. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/.gitignore +0 -0
  24. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/__init__.py +0 -0
  25. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/asgi.py +0 -0
  26. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/endpoints.py +0 -0
  27. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/models.py +0 -0
  28. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/settings.py +0 -0
  29. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/tests.py +0 -0
  30. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/urls.py +0 -0
  31. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/wsgi.py +0 -0
  32. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/application.yml +0 -0
  33. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/entrypoint.sh +0 -0
  34. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/manage.py +0 -0
  35. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/requirements.txt +0 -0
  36. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/base.env +0 -0
  37. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/docker-compose.yml +0 -0
  38. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/package.json +0 -0
  39. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/src/main.jsx +0 -0
  40. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/vite.config.js +0 -0
  41. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/local.env +0 -0
  42. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/run.sh +0 -0
  43. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/selenium/run.sh +0 -0
  44. {slthcore-0.2.0 → slthcore-0.2.1}/slth/cmd/init/boilerplate/test.sh +0 -0
  45. {slthcore-0.2.0 → slthcore-0.2.1}/slth/components.py +0 -0
  46. {slthcore-0.2.0 → slthcore-0.2.1}/slth/db/__init__.py +0 -0
  47. {slthcore-0.2.0 → slthcore-0.2.1}/slth/db/generic.py +0 -0
  48. {slthcore-0.2.0 → slthcore-0.2.1}/slth/exceptions.py +0 -0
  49. {slthcore-0.2.0 → slthcore-0.2.1}/slth/factory.py +0 -0
  50. {slthcore-0.2.0 → slthcore-0.2.1}/slth/forms.py +0 -0
  51. {slthcore-0.2.0 → slthcore-0.2.1}/slth/management/__init__.py +0 -0
  52. {slthcore-0.2.0 → slthcore-0.2.1}/slth/management/commands/__init__.py +0 -0
  53. {slthcore-0.2.0 → slthcore-0.2.1}/slth/management/commands/integration_test.py +0 -0
  54. {slthcore-0.2.0 → slthcore-0.2.1}/slth/management/commands/sync.py +0 -0
  55. {slthcore-0.2.0/slth/migrations → slthcore-0.2.1/slth/middleware}/__init__.py +0 -0
  56. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0001_initial.py +0 -0
  57. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0002_email_role_pushsubscription_error.py +0 -0
  58. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0003_rename_photo_profile_alter_profile_options.py +0 -0
  59. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0004_alter_profile_photo.py +0 -0
  60. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0005_alter_profile_photo.py +0 -0
  61. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0006_user.py +0 -0
  62. {slthcore-0.2.0 → slthcore-0.2.1}/slth/migrations/0007_deletion_log.py +0 -0
  63. {slthcore-0.2.0 → slthcore-0.2.1}/slth/notifications.py +0 -0
  64. {slthcore-0.2.0 → slthcore-0.2.1}/slth/oauth.py +0 -0
  65. {slthcore-0.2.0 → slthcore-0.2.1}/slth/pdf/tests.py +0 -0
  66. {slthcore-0.2.0 → slthcore-0.2.1}/slth/permissions.py +0 -0
  67. {slthcore-0.2.0 → slthcore-0.2.1}/slth/printer.py +0 -0
  68. {slthcore-0.2.0 → slthcore-0.2.1}/slth/queryset.py +0 -0
  69. {slthcore-0.2.0 → slthcore-0.2.1}/slth/roles.py +0 -0
  70. {slthcore-0.2.0 → slthcore-0.2.1}/slth/selenium/__init__.py +0 -0
  71. {slthcore-0.2.0 → slthcore-0.2.1}/slth/selenium/browser.py +0 -0
  72. {slthcore-0.2.0 → slthcore-0.2.1}/slth/serializer.py +0 -0
  73. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/.DS_Store +0 -0
  74. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/css/.DS_Store +0 -0
  75. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/css/slth.css +0 -0
  76. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/js/index.min.js +0 -0
  77. {slthcore-0.2.0 → slthcore-0.2.1}/slth/static/js/react.min.js +0 -0
  78. {slthcore-0.2.0 → slthcore-0.2.1}/slth/statistics.py +0 -0
  79. {slthcore-0.2.0 → slthcore-0.2.1}/slth/tasks.py +0 -0
  80. {slthcore-0.2.0 → slthcore-0.2.1}/slth/templates/index.html +0 -0
  81. {slthcore-0.2.0 → slthcore-0.2.1}/slth/templates/report.html +0 -0
  82. {slthcore-0.2.0 → slthcore-0.2.1}/slth/templates/service-worker.js +0 -0
  83. {slthcore-0.2.0 → slthcore-0.2.1}/slth/templates/signature.html +0 -0
  84. {slthcore-0.2.0 → slthcore-0.2.1}/slth/tests.py +0 -0
  85. {slthcore-0.2.0 → slthcore-0.2.1}/slth/threadlocal.py +0 -0
  86. {slthcore-0.2.0 → slthcore-0.2.1}/slth/urls.py +0 -0
  87. {slthcore-0.2.0 → slthcore-0.2.1}/slth/utils.py +0 -0
  88. {slthcore-0.2.0 → slthcore-0.2.1}/slth/views.py +0 -0
  89. {slthcore-0.2.0 → slthcore-0.2.1}/slthcore.egg-info/dependency_links.txt +0 -0
  90. {slthcore-0.2.0 → slthcore-0.2.1}/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.0
3
+ Version: 0.2.1
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.0',
8
+ version='0.2.1',
9
9
  packages=find_packages(),
10
10
  install_requires=install_requires,
11
11
  include_package_data=True,
@@ -0,0 +1,9 @@
1
+ from django.conf import settings
2
+ from django.apps import AppConfig
3
+
4
+
5
+ class AppConfig(AppConfig):
6
+ name = 'slth'
7
+
8
+ def ready(self):
9
+ settings.SLOTH = True
@@ -1,5 +1,8 @@
1
1
  from uuid import uuid1
2
- from django.db.models import Model as DjangoModel
2
+ import pytz
3
+ from datetime import datetime, timedelta
4
+ from django.utils import timezone
5
+ from django.db.models import Model as DjangoModel, fields as DjangoFields
3
6
  from django.db.models import *
4
7
  from django.utils.translation import gettext_lazy as _
5
8
  from . import generic
@@ -107,6 +110,16 @@ class TextField(TextField):
107
110
  self.formatted= kwargs.pop('formatted', False)
108
111
  super().__init__(*args, **kwargs)
109
112
 
113
+
114
+ class DateTimeField(DateTimeField):
115
+
116
+ def get_db_prep_value(self, value, *args, **kwargs):
117
+ return pytz.timezone(timezone.get_current_timezone_name()).localize(value).astimezone(timezone.get_default_timezone()).replace(tzinfo=None) if value else None
118
+
119
+ def from_db_value(self, value, *args, **kwargs):
120
+ return pytz.timezone(timezone.get_default_timezone_name()).localize(value).astimezone(timezone.get_current_timezone()).replace(tzinfo=None) if value else None
121
+
122
+
110
123
  class FileField(FileField):
111
124
  def __init__(self, *args, extensions=('pdf',), max_size=5, **kwargs):
112
125
  self.extensions= extensions
@@ -34,7 +34,7 @@ from .components import (
34
34
  )
35
35
  from .exceptions import JsonResponseException, ReadyResponseException
36
36
  from .utils import build_url, append_url
37
- from .models import PushSubscription, Profile, User, Log
37
+ from .models import PushSubscription, Profile, User, Log, Email
38
38
  from slth.queryset import QuerySet
39
39
  from slth import APPLICATON, ENDPOINTS
40
40
  from . import oauth
@@ -203,7 +203,7 @@ class Endpoint(metaclass=EnpointMetaclass):
203
203
  data = form
204
204
  elif isinstance(data, Form) or isinstance(data, ModelForm):
205
205
  data = data.settitle(title)
206
- elif self.request.method == "POST" and not data:
206
+ elif self.request.method == "POST":# and not data:
207
207
  return self.post()
208
208
  return data
209
209
 
@@ -387,7 +387,7 @@ class AdminEndpoint(Generic[T], ModelEndpoint):
387
387
 
388
388
  class ListEndpoint(Generic[T], ModelEndpoint):
389
389
  def get(self) -> QuerySet:
390
- return self.model.objects#.contextualize(self.request)
390
+ return self.model.objects.contextualize(self.request)
391
391
 
392
392
 
393
393
  class AddEndpoint(Generic[T], ModelEndpoint):
@@ -891,7 +891,12 @@ class PushSubscribe(Endpoint):
891
891
  return True
892
892
 
893
893
 
894
- class PushSubscriptions(ListEndpoint[PushSubscription]):
894
+ class Emails(AdminEndpoint[Email]):
895
+ class Meta:
896
+ verbose_name = "E-mails"
897
+
898
+
899
+ class PushSubscriptions(AdminEndpoint[PushSubscription]):
895
900
  class Meta:
896
901
  verbose_name = "Notificações"
897
902
 
@@ -0,0 +1,25 @@
1
+ import pytz
2
+ from datetime import datetime
3
+ from django.utils import timezone
4
+
5
+ class Middleware:
6
+ def __init__(self, get_response):
7
+ self.get_response = get_response
8
+
9
+ def __call__(self, request):
10
+ tz = request.path[0] == '/' and (request.META.get('HTTP_TZ') or request.META.get('TZ'))
11
+ if tz:
12
+ timezone.activate(pytz.timezone(tz))
13
+ response = self.get_response(request)
14
+ if tz:
15
+ timezone.deactivate()
16
+ return response
17
+
18
+ def now():
19
+ return datetime.now().astimezone(timezone.get_current_timezone()).replace(tzinfo=None)
20
+
21
+ def today():
22
+ return now().date()
23
+
24
+ def local_datetime(dt, tz):
25
+ pass
@@ -0,0 +1,24 @@
1
+ # Generated by Django 4.2.6 on 2024-09-09 07:10
2
+
3
+ from django.db import migrations
4
+ import slth.db.models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('slth', '0007_deletion_log'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name='deletion',
16
+ name='datetime',
17
+ field=slth.db.models.DateTimeField(null=True, verbose_name='Data/Hora'),
18
+ ),
19
+ migrations.AlterField(
20
+ model_name='log',
21
+ name='datetime',
22
+ field=slth.db.models.DateTimeField(null=True, verbose_name='Data/Hora'),
23
+ ),
24
+ ]
@@ -0,0 +1,43 @@
1
+ # Generated by Django 5.1.1 on 2024-09-16 11:01
2
+
3
+ import slth.db.models
4
+ from django.db import migrations
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('slth', '0008_alter_deletion_datetime_alter_log_datetime'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.RemoveField(
15
+ model_name='email',
16
+ name='from_email',
17
+ ),
18
+ migrations.AddField(
19
+ model_name='email',
20
+ name='action',
21
+ field=slth.db.models.CharField(max_length=255, null=True, verbose_name='Ação'),
22
+ ),
23
+ migrations.AddField(
24
+ model_name='email',
25
+ name='attempt',
26
+ field=slth.db.models.IntegerField(default=0, verbose_name='Tentativa de Envio'),
27
+ ),
28
+ migrations.AddField(
29
+ model_name='email',
30
+ name='error',
31
+ field=slth.db.models.TextField(null=True, verbose_name='Erro'),
32
+ ),
33
+ migrations.AddField(
34
+ model_name='email',
35
+ name='send_at',
36
+ field=slth.db.models.DateTimeField(null=True, verbose_name='Data/Hora'),
37
+ ),
38
+ migrations.AddField(
39
+ model_name='email',
40
+ name='url',
41
+ field=slth.db.models.CharField(max_length=255, null=True, verbose_name='URL'),
42
+ ),
43
+ ]
File without changes
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import json
3
3
  import binascii
4
+ import traceback
4
5
  from .db import models, meta
5
6
  from django.conf import settings
6
7
  from django.utils.translation import gettext_lazy as _
@@ -10,6 +11,7 @@ from django.apps import apps
10
11
  from datetime import datetime
11
12
  from django.utils.html import strip_tags
12
13
  from django.core import serializers
14
+ from django.template.loader import render_to_string
13
15
  from django.core.mail import EmailMultiAlternatives
14
16
  from .notifications import send_push_web_notification
15
17
  from slth import APPLICATON
@@ -103,15 +105,6 @@ class Role(models.Model):
103
105
  return '{} - {}'.format(self.get_verbose_name(), scope_value) if scope_value else self.get_verbose_name()
104
106
 
105
107
 
106
- class EmailManager(models.Manager):
107
- def all(self):
108
- return self.order_by('-id')
109
-
110
- def send(self, to, subject, content, from_email=None):
111
- to = [to] if isinstance(to, str) else list(to)
112
- return self.create(from_email=from_email or 'no-replay@mail.com', to=', '.join(to), subject=subject, content=content)
113
-
114
-
115
108
  class PushSubscription(models.Model):
116
109
  user = models.ForeignKey('auth.user', verbose_name='Usuário', on_delete=models.CASCADE)
117
110
  device = models.CharField(verbose_name='Dispositivo')
@@ -144,12 +137,27 @@ class Error(models.Model):
144
137
  verbose_name_plural = 'Erros'
145
138
 
146
139
 
140
+ class EmailManager(models.Manager):
141
+ def all(self):
142
+ return self.order_by('-id')
143
+
144
+ def send(self, to, subject, content, send_at=None, action=None, url=None):
145
+ to = [to] if isinstance(to, str) else list(to)
146
+ return self.create(to=', '.join(to), subject=subject, content=content, send_at=send_at, action=action, url=url)
147
+
148
+
147
149
  class Email(models.Model):
148
- from_email = models.EmailField('Remetente')
149
150
  to = models.TextField('Destinatário', help_text='Separar endereços de e-mail por ",".')
150
151
  subject = models.CharField('Assunto')
151
152
  content = models.TextField('Conteúdo', formatted=True)
153
+ send_at = models.DateTimeField('Data/Hora', null=True)
152
154
  sent_at = models.DateTimeField('Data/Hora', null=True)
155
+ attempt = models.IntegerField('Tentativa de Envio', default=0)
156
+
157
+ action = models.CharField('Ação', null=True)
158
+ url = models.CharField('URL', null=True)
159
+
160
+ error = models.TextField('Erro', null=True)
153
161
 
154
162
  objects = EmailManager()
155
163
 
@@ -161,13 +169,32 @@ class Email(models.Model):
161
169
  return self.subject
162
170
 
163
171
  def save(self, *args, **kwargs):
172
+ self.from_email = settings.DEFAULT_FROM_EMAIL
173
+ if 1 or self.sent_at is None:
174
+ self.send()
175
+ super().save(*args, **kwargs)
176
+
177
+ def send(self):
164
178
  to = [email.strip() for email in self.to.split(',')]
165
179
  msg = EmailMultiAlternatives(self.subject, strip_tags(self.content), self.from_email, to)
166
- msg.attach_alternative(self.content, "text/html")
167
- if self.sent_at is None:
168
- msg.send(fail_silently=True)
169
- self.sent_at = datetime.now()
170
- super().save(*args, **kwargs)
180
+ content = render_to_string('email.html', dict(email=self, title=APPLICATON['title']))
181
+ msg.attach_alternative(content, "text/html")
182
+ self.send_at = datetime.now()
183
+ self.attempt = self.attempt + 1
184
+ try:
185
+ msg.send(fail_silently=False)
186
+ self.sent_at = self.send_at
187
+ except Exception as e:
188
+ self.error = str(e)
189
+ traceback.print_exc()
190
+ super().save()
191
+
192
+ def formfactory(self):
193
+ return super().formfactory().fieldset(
194
+ 'Dados Gerais', ('subject', 'to', 'content')
195
+ ).fieldset(
196
+ 'Botão', ('action', 'url')
197
+ )
171
198
 
172
199
 
173
200
  class Profile(models.Model):
@@ -45,14 +45,14 @@ class PdfSigner:
45
45
  self.offset = len(self.content)
46
46
  self.byterange = []
47
47
  self.path = path.split('.')[0]
48
- self.startxref = [int(x[9:].strip()) for x in re.findall(b'startxref[\n\r ]*\d+', self.content)]
48
+ self.startxref = [int(x[9:].strip()) for x in re.findall(b'startxref[\n\r ]*\\d+', self.content)]
49
49
  self.objects = {}
50
- for xref in re.findall(b'xref[\n\r\w\d ]*trailer', self.content[self.startxref[0]:]):
51
- for offset in sum([[int(n) for n in re.findall(b'\d{10}', xref) if int(n)]], []):
50
+ for xref in re.findall(b'xref[\n\r\\w\\d ]*trailer', self.content[self.startxref[0]:]):
51
+ for offset in sum([[int(n) for n in re.findall(b'\\d{10}', xref) if int(n)]], []):
52
52
  self.objects[b' '.join(self.content[offset:offset + 15].split()[0:2]).decode()] = offset
53
53
  self.trailer = self.content[self.startxref[-1]:].split(b'trailer')[1].split(b'startxref')[0].strip()
54
- self.root = root = re.findall(b'/Root \d+ \d+ R', self.trailer)[-1][6:-2].decode()
55
- self.size = int(re.findall(b'/Size \d+', self.trailer)[-1][5:].strip())
54
+ self.root = root = re.findall(b'/Root \\d+ \\d+ R', self.trailer)[-1][6:-2].decode()
55
+ self.size = int(re.findall(b'/Size \\d+', self.trailer)[-1][5:].strip())
56
56
  self.page()
57
57
 
58
58
  def obj(self, key=None):