slthcore 0.1.9__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.
- {slthcore-0.1.9/slthcore.egg-info → slthcore-0.2.1}/PKG-INFO +1 -1
- {slthcore-0.1.9 → slthcore-0.2.1}/setup.py +1 -1
- slthcore-0.2.1/slth/apps.py +9 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/components.py +2 -2
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/db/models.py +14 -1
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/endpoints.py +9 -4
- slthcore-0.2.1/slth/middleware/timezone.py +25 -0
- slthcore-0.2.1/slth/migrations/0008_alter_deletion_datetime_alter_log_datetime.py +24 -0
- slthcore-0.2.1/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py +43 -0
- slthcore-0.2.1/slth/migrations/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/models.py +42 -15
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/pdf/__init__.py +5 -5
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/js/slth.min.js +15 -15
- slthcore-0.2.1/slth/templates/email.html +155 -0
- {slthcore-0.1.9 → slthcore-0.2.1/slthcore.egg-info}/PKG-INFO +1 -1
- {slthcore-0.1.9 → slthcore-0.2.1}/slthcore.egg-info/SOURCES.txt +6 -1
- slthcore-0.1.9/slth/middleware.py +0 -24
- {slthcore-0.1.9 → slthcore-0.2.1}/MANIFEST.in +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/setup.cfg +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/configure/__main__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/__main__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/.DS_Store +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/.gitignore +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/asgi.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/endpoints.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/models.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/settings.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/tests.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/urls.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/api/wsgi.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/application.yml +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/entrypoint.sh +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/manage.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/backend/requirements.txt +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/base.env +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/docker-compose.yml +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/package.json +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/src/main.jsx +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/frontend/vite.config.js +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/local.env +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/run.sh +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/selenium/run.sh +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/cmd/init/boilerplate/test.sh +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/db/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/db/generic.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/exceptions.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/factory.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/forms.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/management/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/management/commands/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/management/commands/integration_test.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/management/commands/sync.py +0 -0
- {slthcore-0.1.9/slth/migrations → slthcore-0.2.1/slth/middleware}/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0001_initial.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0002_email_role_pushsubscription_error.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0003_rename_photo_profile_alter_profile_options.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0004_alter_profile_photo.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0005_alter_profile_photo.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0006_user.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/migrations/0007_deletion_log.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/notifications.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/oauth.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/pdf/tests.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/permissions.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/printer.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/queryset.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/roles.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/selenium/__init__.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/selenium/browser.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/serializer.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/.DS_Store +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/css/.DS_Store +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/css/slth.css +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/js/index.min.js +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/static/js/react.min.js +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/statistics.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/tasks.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/templates/index.html +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/templates/report.html +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/templates/service-worker.js +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/templates/signature.html +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/tests.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/threadlocal.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/urls.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/utils.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slth/views.py +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slthcore.egg-info/dependency_links.txt +0 -0
- {slthcore-0.1.9 → slthcore-0.2.1}/slthcore.egg-info/top_level.txt +0 -0
|
@@ -210,10 +210,10 @@ class WebConf(dict):
|
|
|
210
210
|
|
|
211
211
|
|
|
212
212
|
class ZoomMeet(dict):
|
|
213
|
-
def __init__(self, token,
|
|
213
|
+
def __init__(self, token, username):
|
|
214
214
|
self["type"] = "zoommeet"
|
|
215
215
|
self["token"] = token
|
|
216
|
-
self["
|
|
216
|
+
self["username"] = username
|
|
217
217
|
|
|
218
218
|
|
|
219
219
|
class Navbar(dict):
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from uuid import uuid1
|
|
2
|
-
|
|
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
|
|
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
|
|
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
|
+
]
|
slthcore-0.2.1/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py
ADDED
|
@@ -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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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 ]
|
|
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
|
|
51
|
-
for offset in sum([[int(n) for n in re.findall(b'
|
|
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
|
|
55
|
-
self.size = int(re.findall(b'/Size
|
|
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):
|