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.
Files changed (52) hide show
  1. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/PKG-INFO +1 -1
  2. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/__init__.py +1 -1
  3. meringue-1.2.0.dev6/meringue/protected/fields.py +89 -0
  4. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/views.py +9 -12
  5. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/pyproject.toml +2 -0
  6. meringue-1.2.0.dev4/meringue/protected/fields.py +0 -49
  7. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/.gitignore +0 -0
  8. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/AUTHORS +0 -0
  9. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/LICENSE +0 -0
  10. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/README.md +0 -0
  11. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/__init__.py +0 -0
  12. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/apps.py +0 -0
  13. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/__init__.py +0 -0
  14. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/patchers.py +0 -0
  15. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/docs/views.py +0 -0
  16. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/handlers.py +0 -0
  17. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/routers.py +0 -0
  18. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/api/utils.py +0 -0
  19. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/conf/__init__.py +0 -0
  20. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/conf/default_settings.py +0 -0
  21. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/__init__.py +0 -0
  22. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/apps.py +0 -0
  23. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/locale/en/LC_MESSAGES/django.po +0 -0
  24. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/locale/ru/LC_MESSAGES/django.po +0 -0
  25. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/models.py +0 -0
  26. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/options.py +0 -0
  27. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/query.py +0 -0
  28. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/templatetags/__init__.py +0 -0
  29. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/templatetags/meringue_base.py +0 -0
  30. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/translation.py +0 -0
  31. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/upload_handlers.py +0 -0
  32. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/__init__.py +0 -0
  33. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/crypt.py +0 -0
  34. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/datetime.py +0 -0
  35. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/utils/frontend.py +0 -0
  36. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/core/views.py +0 -0
  37. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/__init__.py +0 -0
  38. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/protected/apps.py +0 -0
  39. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/__init__.py +0 -0
  40. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/actions.py +0 -0
  41. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/apps.py +0 -0
  42. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/constants.py +0 -0
  43. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/drf_fields.py +0 -0
  44. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/exceptions.py +0 -0
  45. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/generators.py +0 -0
  46. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/images.py +0 -0
  47. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/properties.py +0 -0
  48. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/shortcuts.py +0 -0
  49. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/storage.py +0 -0
  50. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/templatetags/__init__.py +0 -0
  51. {meringue-1.2.0.dev4 → meringue-1.2.0.dev6}/meringue/thumbnail/templatetags/m_thumbnails.py +0 -0
  52. {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.dev4
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
@@ -1,4 +1,4 @@
1
- __version__ = "1.2.0.dev4"
1
+ __version__ = "1.2.0.dev6"
2
2
  """
3
3
  To update the version, use [hatch version](https://hatch.pypa.io/latest/version/#updating)
4
4
 
@@ -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, contenttype_id, field, pk):
18
+ def protected_file_view(request, cid, field, pk):
19
19
  """
20
- В продакшен моде вьха редиректит на урл файла, где нжинкс отдаёт этот файл
21
- Защита работает за счёт параметра internal
22
- https://nginx.org/en/docs/http/ngx_http_core_module.html#internal
23
-
24
- ```conf
25
- location /media/protected/ {
26
- internal;
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=contenttype_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