meringue 1.2.0.dev4__tar.gz → 1.2.0.dev6__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.
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/PKG-INFO +1 -1
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/__init__.py +1 -1
- meringue-1.2.0.dev6/meringue/protected/fields.py +89 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/views.py +9 -12
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/pyproject.toml +2 -0
- meringue-1.2.0.dev4/meringue/protected/fields.py +0 -49
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/.gitignore +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/AUTHORS +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/LICENSE +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/README.md +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/apps.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/patchers.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/views.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/handlers.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/routers.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/utils.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/conf/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/conf/default_settings.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/apps.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/locale/en/LC_MESSAGES/django.po +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/locale/ru/LC_MESSAGES/django.po +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/models.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/options.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/query.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/templatetags/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/templatetags/meringue_base.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/translation.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/upload_handlers.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/crypt.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/datetime.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/frontend.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/views.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/apps.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/actions.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/apps.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/constants.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/drf_fields.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/exceptions.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/generators.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/images.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/properties.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/shortcuts.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/storage.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/templatetags/__init__.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/templatetags/m_thumbnails.py +0 -0
- {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: meringue
|
|
3
|
-
Version: 1.2.0.
|
|
3
|
+
Version: 1.2.0.dev6
|
|
4
4
|
Summary: A set of various functionality for a Django based web application.
|
|
5
5
|
Project-URL: Documentation, https://dd.github.io/Meringue
|
|
6
6
|
Project-URL: Repository, https://github.com/dd/Meringue
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from django.contrib.contenttypes.models import ContentType
|
|
2
|
+
from django.db.models.fields.files import FileField
|
|
3
|
+
from django.db.models.fields.files import FieldFile
|
|
4
|
+
from django.db.models.fields.files import ImageField
|
|
5
|
+
from django.db.models.fields.files import ImageFieldFile
|
|
6
|
+
from django.urls import reverse
|
|
7
|
+
try:
|
|
8
|
+
from django_hosts.resolvers import reverse as hosts_reverse
|
|
9
|
+
except ImportError:
|
|
10
|
+
hosts_reverse = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ProtectedFileMixin:
|
|
14
|
+
@property
|
|
15
|
+
def url(self):
|
|
16
|
+
self._require_file()
|
|
17
|
+
|
|
18
|
+
reverse_kwargs = {
|
|
19
|
+
"cid": ContentType.objects.get_for_model(self.instance.__class__).id,
|
|
20
|
+
"field": self.field.name,
|
|
21
|
+
"pk": self.instance.pk,
|
|
22
|
+
}
|
|
23
|
+
if self.field.m_protected_host_name:
|
|
24
|
+
result_url = hosts_reverse(
|
|
25
|
+
self.field.m_protected_view_name,
|
|
26
|
+
kwargs=reverse_kwargs,
|
|
27
|
+
host=self.field.m_protected_host_name,
|
|
28
|
+
)
|
|
29
|
+
else:
|
|
30
|
+
result_url = reverse(self.field.m_protected_view_name, kwargs=reverse_kwargs)
|
|
31
|
+
return result_url
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def original_url(self):
|
|
35
|
+
self._require_file()
|
|
36
|
+
return self.storage.url(self.name)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ProtectedFieldFile(ProtectedFileMixin, FieldFile):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ProtectedFileField(FileField):
|
|
44
|
+
"""
|
|
45
|
+
A field that adds the mechanism of a protected file.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
attr_class = ProtectedFieldFile
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
verbose_name=None,
|
|
53
|
+
name=None,
|
|
54
|
+
upload_to="protected",
|
|
55
|
+
storage=None,
|
|
56
|
+
protected_view_name="meringue-protected-file",
|
|
57
|
+
protected_host_name=None,
|
|
58
|
+
**kwargs,
|
|
59
|
+
):
|
|
60
|
+
self.m_protected_view_name = protected_view_name
|
|
61
|
+
self.m_protected_host_name = protected_host_name
|
|
62
|
+
super().__init__(verbose_name, name, upload_to, storage, **kwargs)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ProtectedImageFieldFile(ProtectedFileMixin, ImageFieldFile):
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ProtectedImageField(ImageField):
|
|
70
|
+
"""
|
|
71
|
+
A field that adds the mechanism of a protected image.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
attr_class = ProtectedImageFieldFile
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
verbose_name=None,
|
|
79
|
+
name=None,
|
|
80
|
+
width_field=None,
|
|
81
|
+
height_field=None,
|
|
82
|
+
protected_view_name="meringue-protected-file",
|
|
83
|
+
protected_host_name=None,
|
|
84
|
+
**kwargs,
|
|
85
|
+
):
|
|
86
|
+
kwargs.setdefault("upload_to", "protected")
|
|
87
|
+
self.m_protected_view_name = protected_view_name
|
|
88
|
+
self.m_protected_host_name = protected_host_name
|
|
89
|
+
super().__init__(verbose_name, name, width_field, height_field, **kwargs)
|
|
@@ -15,21 +15,18 @@ from meringue.protected.fields import ProtectedFieldFile
|
|
|
15
15
|
from meringue.protected.fields import ProtectedImageFieldFile
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def protected_file_view(request,
|
|
18
|
+
def protected_file_view(request, cid, field, pk):
|
|
19
19
|
"""
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
alias /home/rpl/rpl-2023-back/public/media/protected/;
|
|
28
|
-
}
|
|
29
|
-
```
|
|
20
|
+
The view checks the user's access to view and serves the file.
|
|
21
|
+
|
|
22
|
+
If you enable the parameter
|
|
23
|
+
[PROTECTED_SERVE_WITH_NGINX][meringue.conf.default_settings.PROTECTED_SERVE_WITH_NGINX], the
|
|
24
|
+
file will not be served; instead, the response will contain the X-Accel-Redirect header
|
|
25
|
+
pointing to the original file. It is expected that nginx will return the file using the
|
|
26
|
+
[internal](https://nginx.org/en/docs/http/ngx_http_core_module.html#internal) parameter.
|
|
30
27
|
"""
|
|
31
28
|
|
|
32
|
-
contenttype = ContentType.objects.get(id=
|
|
29
|
+
contenttype = ContentType.objects.get(id=cid)
|
|
33
30
|
|
|
34
31
|
if not request.user.has_perm(f"{contenttype.app_label}.view_{contenttype.model}"):
|
|
35
32
|
raise PermissionDenied()
|
|
@@ -157,6 +157,7 @@ dependencies = [
|
|
|
157
157
|
"djangorestframework-simplejwt==5.3.1",
|
|
158
158
|
"drf-spectacular==0.26.4",
|
|
159
159
|
"pillow==10.3.0",
|
|
160
|
+
"django_hosts==5.2",
|
|
160
161
|
]
|
|
161
162
|
[tool.hatch.envs.test.env-vars]
|
|
162
163
|
DJANGO_SETTINGS_MODULE = "test_project.settings"
|
|
@@ -177,6 +178,7 @@ dependencies = [
|
|
|
177
178
|
"pycryptodome==3.20.0",
|
|
178
179
|
"drf-spectacular==0.26.4",
|
|
179
180
|
"pillow==10.3.0",
|
|
181
|
+
"django_hosts==5.2",
|
|
180
182
|
]
|
|
181
183
|
[tool.hatch.envs.mtest.overrides]
|
|
182
184
|
matrix.django.dependencies = [
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
from django.contrib.contenttypes.models import ContentType
|
|
2
|
-
from django.db.models.fields.files import FileField
|
|
3
|
-
from django.db.models.fields.files import FieldFile
|
|
4
|
-
from django.db.models.fields.files import ImageField
|
|
5
|
-
from django.db.models.fields.files import ImageFieldFile
|
|
6
|
-
from django.urls import reverse
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ProtectedFileMixin:
|
|
10
|
-
@property
|
|
11
|
-
def url(self):
|
|
12
|
-
self._require_file()
|
|
13
|
-
result_url = reverse(
|
|
14
|
-
"meringue-protected-file",
|
|
15
|
-
kwargs={
|
|
16
|
-
"contenttype_id": ContentType.objects.get_for_model(self.instance.__class__).id,
|
|
17
|
-
"field": self.field.name,
|
|
18
|
-
"pk": self.instance.pk,
|
|
19
|
-
},
|
|
20
|
-
)
|
|
21
|
-
return result_url
|
|
22
|
-
|
|
23
|
-
@property
|
|
24
|
-
def original_url(self):
|
|
25
|
-
self._require_file()
|
|
26
|
-
return self.storage.url(self.name)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class ProtectedFieldFile(ProtectedFileMixin, FieldFile):
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class ProtectedFileField(FileField):
|
|
34
|
-
attr_class = ProtectedFieldFile
|
|
35
|
-
|
|
36
|
-
def __init__(self, verbose_name=None, name=None, upload_to="protected", storage=None, **kwargs):
|
|
37
|
-
super().__init__(verbose_name, name, upload_to, storage, **kwargs)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class ProtectedImageFieldFile(ProtectedFileMixin, ImageFieldFile):
|
|
41
|
-
pass
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class ProtectedImageField(ImageField):
|
|
45
|
-
attr_class = ProtectedImageFieldFile
|
|
46
|
-
|
|
47
|
-
def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
|
|
48
|
-
kwargs.setdefault("upload_to", "protected")
|
|
49
|
-
super().__init__(verbose_name, name, width_field, height_field, **kwargs)
|
|
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
|
|
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
|