meringue 1.2.0.dev8__tar.gz → 1.3.0.dev0__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.dev8 → meringue-1.3.0.dev0}/PKG-INFO +10 -5
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/README.md +4 -1
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/__init__.py +1 -1
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/handlers.py +2 -1
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/utils.py +1 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/conf/__init__.py +2 -1
- meringue-1.3.0.dev0/meringue/core/db.py +77 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/query.py +1 -3
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/protected/fields.py +7 -5
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/protected/views.py +7 -6
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/shortcuts.py +2 -2
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/pyproject.toml +83 -55
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/.gitignore +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/AUTHORS +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/LICENSE +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/apps.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/docs/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/docs/patchers.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/docs/views.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/api/routers.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/conf/default_settings.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/apps.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/locale/en/LC_MESSAGES/django.po +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/locale/ru/LC_MESSAGES/django.po +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/models.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/options.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/templatetags/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/templatetags/meringue_base.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/translation.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/upload_handlers.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/utils/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/utils/crypt.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/utils/datetime.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/utils/frontend.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/core/views.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/protected/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/protected/apps.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/protected/utils.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/actions.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/apps.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/constants.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/drf_fields.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/exceptions.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/generators.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/images.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/properties.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/storage.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/templatetags/__init__.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/templatetags/m_thumbnails.py +0 -0
- {meringue-1.2.0.dev8 → meringue-1.3.0.dev0}/meringue/thumbnail/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: meringue
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0.dev0
|
|
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
|
|
@@ -15,8 +15,6 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
15
15
|
Classifier: Environment :: Plugins
|
|
16
16
|
Classifier: Environment :: Web Environment
|
|
17
17
|
Classifier: Framework :: Django
|
|
18
|
-
Classifier: Framework :: Django :: 1
|
|
19
|
-
Classifier: Framework :: Django :: 1.11
|
|
20
18
|
Classifier: Framework :: Django :: 2
|
|
21
19
|
Classifier: Framework :: Django :: 2.0
|
|
22
20
|
Classifier: Framework :: Django :: 2.1
|
|
@@ -29,6 +27,7 @@ Classifier: Framework :: Django :: 4
|
|
|
29
27
|
Classifier: Framework :: Django :: 4.0
|
|
30
28
|
Classifier: Framework :: Django :: 4.1
|
|
31
29
|
Classifier: Framework :: Django :: 4.2
|
|
30
|
+
Classifier: Framework :: Django :: 5.0
|
|
32
31
|
Classifier: Intended Audience :: Developers
|
|
33
32
|
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
|
|
34
33
|
Classifier: Natural Language :: English
|
|
@@ -38,6 +37,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
38
37
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
39
38
|
Classifier: Programming Language :: Python :: 3.10
|
|
40
39
|
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
41
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
42
42
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
43
43
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
@@ -45,9 +45,11 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
|
45
45
|
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
|
|
46
46
|
Classifier: Topic :: Software Development :: Libraries
|
|
47
47
|
Requires-Python: >=3.10
|
|
48
|
-
Requires-Dist: django
|
|
48
|
+
Requires-Dist: django<6,>=2.0.0
|
|
49
49
|
Provides-Extra: cryptodome
|
|
50
50
|
Requires-Dist: pycryptodome==3.20.0; extra == 'cryptodome'
|
|
51
|
+
Provides-Extra: django-hosts
|
|
52
|
+
Requires-Dist: django-hosts<7,>=5.2; extra == 'django-hosts'
|
|
51
53
|
Provides-Extra: drf
|
|
52
54
|
Requires-Dist: djangorestframework<4,>=3.13; extra == 'drf'
|
|
53
55
|
Provides-Extra: drf-spectacular
|
|
@@ -74,6 +76,9 @@ Description-Content-Type: text/markdown
|
|
|
74
76
|
<a href="https://pypi.org/project/meringue">
|
|
75
77
|
<img src="https://img.shields.io/pypi/pyversions/meringue.svg" alt="PyPI - Python Version" />
|
|
76
78
|
</a>
|
|
79
|
+
<a href="https://pypi.org/project/meringue">
|
|
80
|
+
<img src="https://img.shields.io/pypi/frameworkversions/django/meringue" alt="PyPI - Versions from Framework Classifiers" />
|
|
81
|
+
</a>
|
|
77
82
|
<!-- <a href="https://pypi.org/project/meringue">
|
|
78
83
|
<img src="https://img.shields.io/pypi/format/meringue.svg" alt="PyPI - Format" />
|
|
79
84
|
</a> -->
|
|
@@ -94,7 +99,7 @@ Description-Content-Type: text/markdown
|
|
|
94
99
|
<img src="https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg" alt="Hatch project" />
|
|
95
100
|
</a>
|
|
96
101
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank">
|
|
97
|
-
<img src="https://img.shields.io/badge
|
|
102
|
+
<img src="https://img.shields.io/badge/-Material_for_MkDocs-526CFE?logo=MaterialForMkDocs&logoColor=white&labelColor=gray" alt="Built with Material for MkDocs" />
|
|
98
103
|
</a>
|
|
99
104
|
<a href="https://github.com/charliermarsh/ruff" target="_blank">
|
|
100
105
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json" alt="linting - Ruff" />
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
<a href="https://pypi.org/project/meringue">
|
|
17
17
|
<img src="https://img.shields.io/pypi/pyversions/meringue.svg" alt="PyPI - Python Version" />
|
|
18
18
|
</a>
|
|
19
|
+
<a href="https://pypi.org/project/meringue">
|
|
20
|
+
<img src="https://img.shields.io/pypi/frameworkversions/django/meringue" alt="PyPI - Versions from Framework Classifiers" />
|
|
21
|
+
</a>
|
|
19
22
|
<!-- <a href="https://pypi.org/project/meringue">
|
|
20
23
|
<img src="https://img.shields.io/pypi/format/meringue.svg" alt="PyPI - Format" />
|
|
21
24
|
</a> -->
|
|
@@ -36,7 +39,7 @@
|
|
|
36
39
|
<img src="https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg" alt="Hatch project" />
|
|
37
40
|
</a>
|
|
38
41
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank">
|
|
39
|
-
<img src="https://img.shields.io/badge
|
|
42
|
+
<img src="https://img.shields.io/badge/-Material_for_MkDocs-526CFE?logo=MaterialForMkDocs&logoColor=white&labelColor=gray" alt="Built with Material for MkDocs" />
|
|
40
43
|
</a>
|
|
41
44
|
<a href="https://github.com/charliermarsh/ruff" target="_blank">
|
|
42
45
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json" alt="linting - Ruff" />
|
|
@@ -6,6 +6,7 @@ from rest_framework import views
|
|
|
6
6
|
|
|
7
7
|
from meringue.api.utils import render_error_details
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
try:
|
|
10
11
|
from rest_framework_simplejwt.exceptions import DetailDictMixin
|
|
11
12
|
except ImportError:
|
|
@@ -24,7 +25,7 @@ def exception_handler(exc, context):
|
|
|
24
25
|
if response is None:
|
|
25
26
|
return response
|
|
26
27
|
|
|
27
|
-
if isinstance(exc,
|
|
28
|
+
if isinstance(exc, Http404 | PermissionDenied):
|
|
28
29
|
# django Http404 and PermissionDenied errors are substituted for drf errors,
|
|
29
30
|
# in `rest_framework.views.exception_handler` method.
|
|
30
31
|
response.data = render_error_details(response.data["detail"])
|
|
@@ -202,7 +202,8 @@ class Settings:
|
|
|
202
202
|
"""
|
|
203
203
|
|
|
204
204
|
if attr not in self.defaults:
|
|
205
|
-
|
|
205
|
+
msg = f"Invalid setting key: '{attr}'"
|
|
206
|
+
raise AttributeError(msg)
|
|
206
207
|
|
|
207
208
|
if attr in self.deprecated_params:
|
|
208
209
|
warnings.warn(self.deprecated_params[attr], DeprecationWarning, stacklevel=2)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from functools import wraps
|
|
3
|
+
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
from django.db import connections
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PgAdvisoryLock:
|
|
9
|
+
"""
|
|
10
|
+
A context manager and decorator for using PostgreSQL advisory locks in Django.
|
|
11
|
+
|
|
12
|
+
This class provides a way to use PostgreSQL advisory locks, ensuring that the lock
|
|
13
|
+
is acquired and released correctly. It supports usage as both a context manager
|
|
14
|
+
and a function decorator. The class also checks if the database is PostgreSQL and
|
|
15
|
+
issues a warning if it is not.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, table: str, value: str, field: str = "id", using: str = "default"):
|
|
19
|
+
"""
|
|
20
|
+
Attributes:
|
|
21
|
+
table: The name of the table to query for the lock ID.
|
|
22
|
+
value: The value to match in the field to retrieve the lock ID.
|
|
23
|
+
field: The name of the field to query for the lock ID.
|
|
24
|
+
using: The database alias to use.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
self.table = table
|
|
28
|
+
self.value = value
|
|
29
|
+
self.field = field
|
|
30
|
+
self.db_name = using
|
|
31
|
+
self.is_postgresql = self._check_postgresql()
|
|
32
|
+
|
|
33
|
+
def __enter__(self):
|
|
34
|
+
self.lock()
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
38
|
+
self.unlock()
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def __call__(self, func):
|
|
42
|
+
@wraps(func)
|
|
43
|
+
def wrapped(*args, **kwargs):
|
|
44
|
+
with self:
|
|
45
|
+
return func(*args, **kwargs)
|
|
46
|
+
|
|
47
|
+
return wrapped
|
|
48
|
+
|
|
49
|
+
def _check_postgresql(self) -> bool:
|
|
50
|
+
engine = settings.DATABASES[self.db_name]["ENGINE"]
|
|
51
|
+
return "postgresql" in engine
|
|
52
|
+
|
|
53
|
+
def lock(self) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Acquires the advisory lock.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
if not self.is_postgresql:
|
|
59
|
+
msg = "pg_advisory_lock is only supported with PostgreSQL databases."
|
|
60
|
+
warnings.warn(msg, UserWarning, stacklevel=2)
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
sql = f"SELECT pg_advisory_lock({self.field}) FROM {self.table} WHERE {self.field} = %s" # noqa: S608
|
|
64
|
+
with connections[self.db_name].cursor() as cursor:
|
|
65
|
+
cursor.execute(sql, [self.value])
|
|
66
|
+
|
|
67
|
+
def unlock(self) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Releases the advisory lock.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
if not self.is_postgresql:
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
sql = f"SELECT pg_advisory_unlock({self.field}) FROM {self.table} WHERE {self.field} = %s" # noqa: S608
|
|
76
|
+
with connections[self.db_name].cursor() as cursor:
|
|
77
|
+
cursor.execute(sql, [self.value])
|
|
@@ -18,12 +18,10 @@ class SortingQuerySet(QuerySet):
|
|
|
18
18
|
The selection for updating sorting can be pre-limited by filtering the list.
|
|
19
19
|
"""
|
|
20
20
|
items = []
|
|
21
|
-
sorting
|
|
22
|
-
for item in self:
|
|
21
|
+
for sorting, item in enumerate(self):
|
|
23
22
|
if item.sorting != sorting:
|
|
24
23
|
item.sorting = sorting
|
|
25
24
|
items.append(item)
|
|
26
|
-
sorting += 1
|
|
27
25
|
|
|
28
26
|
return self.bulk_update(items, ["sorting"])
|
|
29
27
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
from django.contrib.contenttypes.models import ContentType
|
|
2
|
-
from django.db.models.fields.files import FileField
|
|
3
2
|
from django.db.models.fields.files import FieldFile
|
|
3
|
+
from django.db.models.fields.files import FileField
|
|
4
4
|
from django.db.models.fields.files import ImageField
|
|
5
5
|
from django.db.models.fields.files import ImageFieldFile
|
|
6
6
|
from django.urls import reverse
|
|
7
|
+
|
|
8
|
+
from meringue.conf import m_settings
|
|
9
|
+
|
|
10
|
+
|
|
7
11
|
try:
|
|
8
12
|
from django_hosts.resolvers import reverse as hosts_reverse
|
|
9
13
|
except ImportError:
|
|
10
14
|
hosts_reverse = None
|
|
11
15
|
|
|
12
|
-
from meringue.conf import m_settings
|
|
13
|
-
|
|
14
16
|
|
|
15
17
|
class ProtectedFileMixin:
|
|
16
18
|
@property
|
|
@@ -86,7 +88,7 @@ class ProtectedFileField(FileField):
|
|
|
86
88
|
|
|
87
89
|
def deconstruct(self):
|
|
88
90
|
name, path, args, kwargs = super().deconstruct()
|
|
89
|
-
kwargs[
|
|
91
|
+
kwargs["view_name"] = self.m_protected_view_name
|
|
90
92
|
return name, path, args, kwargs
|
|
91
93
|
|
|
92
94
|
|
|
@@ -122,5 +124,5 @@ class ProtectedImageField(ImageField):
|
|
|
122
124
|
|
|
123
125
|
def deconstruct(self):
|
|
124
126
|
name, path, args, kwargs = super().deconstruct()
|
|
125
|
-
kwargs[
|
|
127
|
+
kwargs["view_name"] = self.m_protected_view_name
|
|
126
128
|
return name, path, args, kwargs
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import mimetypes
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from urllib.parse import quote
|
|
4
|
-
from urllib.parse import urljoin
|
|
5
4
|
|
|
6
|
-
from django.conf import settings
|
|
7
5
|
from django.contrib.contenttypes.models import ContentType
|
|
8
6
|
from django.core.exceptions import PermissionDenied
|
|
9
7
|
from django.http import FileResponse
|
|
@@ -51,7 +49,10 @@ def x_accel_redirect_view(request, cid, field, pk, disp="inline"):
|
|
|
51
49
|
response["X-Accel-Redirect"] = redirect_url
|
|
52
50
|
return response
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
with open(file.path, "rb") as tmp_file:
|
|
53
|
+
response = FileResponse(
|
|
54
|
+
tmp_file,
|
|
55
|
+
as_attachment=disp == "attachment",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return response
|
|
@@ -42,8 +42,8 @@ def _dummyimage(job_chain: str) -> str:
|
|
|
42
42
|
height=size[1],
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
return "
|
|
46
|
-
# return "
|
|
45
|
+
return f"{settings.STATIC_URL}images/noise.png"
|
|
46
|
+
# return f"{settings.STATIC_URL}images/none.gif"
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def get_thumbnail(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["hatchling>=1.
|
|
2
|
+
requires = ["hatchling>=1.22.5"]
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
@@ -17,8 +17,6 @@ classifiers = [
|
|
|
17
17
|
"Environment :: Plugins",
|
|
18
18
|
"Environment :: Web Environment",
|
|
19
19
|
"Framework :: Django",
|
|
20
|
-
"Framework :: Django :: 1",
|
|
21
|
-
"Framework :: Django :: 1.11",
|
|
22
20
|
"Framework :: Django :: 2",
|
|
23
21
|
"Framework :: Django :: 2.0",
|
|
24
22
|
"Framework :: Django :: 2.1",
|
|
@@ -31,6 +29,7 @@ classifiers = [
|
|
|
31
29
|
"Framework :: Django :: 4.0",
|
|
32
30
|
"Framework :: Django :: 4.1",
|
|
33
31
|
"Framework :: Django :: 4.2",
|
|
32
|
+
"Framework :: Django :: 5.0",
|
|
34
33
|
"Intended Audience :: Developers",
|
|
35
34
|
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
|
36
35
|
"Natural Language :: English",
|
|
@@ -40,6 +39,7 @@ classifiers = [
|
|
|
40
39
|
"Programming Language :: Python :: 3",
|
|
41
40
|
"Programming Language :: Python :: 3.10",
|
|
42
41
|
"Programming Language :: Python :: 3.11",
|
|
42
|
+
"Programming Language :: Python :: 3.12",
|
|
43
43
|
"Programming Language :: Python :: 3 :: Only",
|
|
44
44
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
45
45
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
@@ -49,7 +49,7 @@ classifiers = [
|
|
|
49
49
|
"Topic :: Software Development :: Libraries",
|
|
50
50
|
]
|
|
51
51
|
dependencies = [
|
|
52
|
-
"Django>=
|
|
52
|
+
"Django>=2.0.0,<6",
|
|
53
53
|
]
|
|
54
54
|
dynamic = ["version"]
|
|
55
55
|
|
|
@@ -58,6 +58,7 @@ modeltranslation = ["django-modeltranslation>=0.17,<0.19"]
|
|
|
58
58
|
drf = ["djangorestframework>=3.13,<4"]
|
|
59
59
|
drf-spectacular = ["drf-spectacular>=0.26.3,<1"]
|
|
60
60
|
cryptodome = ["pycryptodome==3.20.0"]
|
|
61
|
+
django_hosts = ["django_hosts>=5.2,<7"]
|
|
61
62
|
|
|
62
63
|
[project.urls]
|
|
63
64
|
"Documentation" = "https://dd.github.io/Meringue"
|
|
@@ -85,15 +86,17 @@ exclude = [
|
|
|
85
86
|
description = "Dev environment"
|
|
86
87
|
python = "3.12"
|
|
87
88
|
dependencies = [
|
|
88
|
-
"pre-commit==3.
|
|
89
|
-
"ipython==8.
|
|
90
|
-
"django==
|
|
91
|
-
"pytz==
|
|
89
|
+
"pre-commit==3.7.0",
|
|
90
|
+
"ipython==8.23.0",
|
|
91
|
+
"django==5.0.4",
|
|
92
|
+
"pytz==2024.1",
|
|
92
93
|
"django-modeltranslation==0.18.11",
|
|
93
94
|
"pycryptodome==3.20.0",
|
|
94
|
-
"djangorestframework==3.
|
|
95
|
-
"
|
|
96
|
-
"
|
|
95
|
+
"djangorestframework==3.15.1",
|
|
96
|
+
"djangorestframework-simplejwt==5.3.1",
|
|
97
|
+
"drf-spectacular==0.27.2",
|
|
98
|
+
"Pillow==10.3.0",
|
|
99
|
+
"django_hosts==6.0",
|
|
97
100
|
]
|
|
98
101
|
[tool.hatch.envs.default.env-vars]
|
|
99
102
|
DJANGO_SETTINGS_MODULE = "test_project.settings"
|
|
@@ -121,43 +124,48 @@ remove = [
|
|
|
121
124
|
]
|
|
122
125
|
makemessages = "cd meringue/core && django-admin makemessages -l en -l ru --no-obsolete {args}"
|
|
123
126
|
compilemessages = "cd meringue && django-admin compilemessages -l en -l ru {args}"
|
|
127
|
+
changelog-update = [
|
|
128
|
+
"git fetch origin --tags",
|
|
129
|
+
"gitmoji-changelog update \"$(hatch version)\" --preset generic --group-similar-commits",
|
|
130
|
+
]
|
|
131
|
+
release-tag = "git tag -a \"v$(hatch version)\" -m \"v$(hatch version)\""
|
|
124
132
|
|
|
125
133
|
[tool.hatch.envs.lint]
|
|
126
134
|
description = "Lint environment"
|
|
127
135
|
detached = true
|
|
128
|
-
python = "3.
|
|
136
|
+
python = "3.12"
|
|
129
137
|
dependencies = [
|
|
130
|
-
"ruff==0.
|
|
131
|
-
"black==24.
|
|
138
|
+
"ruff==0.4.9",
|
|
139
|
+
"black==24.4.2",
|
|
132
140
|
]
|
|
133
141
|
[tool.hatch.envs.lint.scripts]
|
|
134
142
|
check = [
|
|
135
|
-
"ruff {args:.}",
|
|
143
|
+
"ruff check {args:.}",
|
|
136
144
|
"black --check --diff --exclude=\".*migrations\\/.*$\" {args:.}",
|
|
137
145
|
]
|
|
138
146
|
format = [
|
|
139
|
-
"ruff
|
|
147
|
+
"ruff format {args:.}",
|
|
140
148
|
"black --exclude=\".*migrations\\/.*$\" {args:.}",
|
|
141
149
|
]
|
|
142
150
|
|
|
143
151
|
[tool.hatch.envs.test]
|
|
144
152
|
description = "Tests environment"
|
|
145
153
|
detached = true
|
|
146
|
-
python = "3.
|
|
154
|
+
python = "3.12"
|
|
147
155
|
dependencies = [
|
|
148
|
-
"pytest==
|
|
149
|
-
"pytest-django==4.
|
|
150
|
-
"pytest-cov==
|
|
151
|
-
"Faker==
|
|
152
|
-
"
|
|
153
|
-
"pytz==2023.3.post1",
|
|
154
|
-
"django-modeltranslation==0.18.11",
|
|
156
|
+
"pytest==8.1.1",
|
|
157
|
+
"pytest-django==4.8.0",
|
|
158
|
+
"pytest-cov==5.0.0", # for ci tests with cover
|
|
159
|
+
"Faker==24.7.1",
|
|
160
|
+
"pytz==2024.1",
|
|
155
161
|
"pycryptodome==3.20.0",
|
|
156
|
-
"
|
|
157
|
-
"djangorestframework-simplejwt==5.3.1",
|
|
158
|
-
"drf-spectacular==0.26.4",
|
|
162
|
+
"drf-spectacular==0.27.2",
|
|
159
163
|
"pillow==10.3.0",
|
|
160
|
-
"
|
|
164
|
+
"django==5.0.4",
|
|
165
|
+
"django-modeltranslation==0.18.11",
|
|
166
|
+
"djangorestframework==3.15.1",
|
|
167
|
+
"djangorestframework-simplejwt==5.3.1",
|
|
168
|
+
"django_hosts==6.0",
|
|
161
169
|
]
|
|
162
170
|
[tool.hatch.envs.test.env-vars]
|
|
163
171
|
DJANGO_SETTINGS_MODULE = "test_project.settings"
|
|
@@ -170,15 +178,14 @@ makemigrations = "django-admin makemigrations {args}"
|
|
|
170
178
|
description = "Test matrix environment"
|
|
171
179
|
detached = true
|
|
172
180
|
dependencies = [
|
|
173
|
-
"pytest==
|
|
174
|
-
"pytest-django==4.
|
|
175
|
-
"pytest-cov==
|
|
176
|
-
"Faker==
|
|
177
|
-
"pytz==
|
|
181
|
+
"pytest==8.1.1",
|
|
182
|
+
"pytest-django==4.8.0",
|
|
183
|
+
"pytest-cov==5.0.0", # for ci tests with cover
|
|
184
|
+
"Faker==24.7.1",
|
|
185
|
+
"pytz==2024.1",
|
|
178
186
|
"pycryptodome==3.20.0",
|
|
179
|
-
"drf-spectacular==0.
|
|
187
|
+
"drf-spectacular==0.27.2",
|
|
180
188
|
"pillow==10.3.0",
|
|
181
|
-
"django_hosts==5.2",
|
|
182
189
|
]
|
|
183
190
|
[tool.hatch.envs.mtest.overrides]
|
|
184
191
|
matrix.django.dependencies = [
|
|
@@ -186,6 +193,7 @@ matrix.django.dependencies = [
|
|
|
186
193
|
{ value = "django-modeltranslation=={matrix:modeltranslation}" },
|
|
187
194
|
{ value = "djangorestframework=={matrix:djangorestframework}" },
|
|
188
195
|
{ value = "djangorestframework-simplejwt=={matrix:simplejwt}" },
|
|
196
|
+
{ value = "django_hosts=={matrix:django_hosts}" },
|
|
189
197
|
]
|
|
190
198
|
[tool.hatch.envs.mtest.env-vars]
|
|
191
199
|
DJANGO_SETTINGS_MODULE = "test_project.settings"
|
|
@@ -195,38 +203,55 @@ check = "pytest {args:-q}"
|
|
|
195
203
|
[[tool.hatch.envs.mtest.matrix]]
|
|
196
204
|
python = ["3.10", "3.11"]
|
|
197
205
|
django = ["2.0"]
|
|
198
|
-
modeltranslation = ["0.17.0"]
|
|
206
|
+
modeltranslation = ["0.17.0", "0.18.2"]
|
|
199
207
|
djangorestframework = ["3.13.0"]
|
|
200
208
|
simplejwt = ["5.2.0"]
|
|
209
|
+
django_hosts = ["5.2", "6.0"]
|
|
201
210
|
[[tool.hatch.envs.mtest.matrix]]
|
|
202
211
|
python = ["3.10", "3.11"]
|
|
203
212
|
django = ["3.0"]
|
|
204
|
-
modeltranslation = ["0.17.0"]
|
|
213
|
+
modeltranslation = ["0.17.0", "0.18.2"]
|
|
205
214
|
djangorestframework = ["3.13.0", "3.14.0", "3.15.0"]
|
|
206
215
|
simplejwt = ["5.2.0", "5.3.0"]
|
|
216
|
+
django_hosts = ["5.2", "6.0"]
|
|
207
217
|
[[tool.hatch.envs.mtest.matrix]]
|
|
208
218
|
python = ["3.10", "3.11"]
|
|
209
219
|
django = ["4.0"]
|
|
210
|
-
modeltranslation = ["0.17.0"]
|
|
211
|
-
djangorestframework = ["3.14.0"]
|
|
220
|
+
modeltranslation = ["0.17.0", "0.18.2"]
|
|
221
|
+
djangorestframework = ["3.14.0", "3.15.0"]
|
|
212
222
|
simplejwt = ["5.2.0", "5.3.0"]
|
|
223
|
+
django_hosts = ["5.2", "6.0"]
|
|
224
|
+
[[tool.hatch.envs.mtest.matrix]]
|
|
225
|
+
python = ["3.12"]
|
|
226
|
+
django = ["4.0"]
|
|
227
|
+
modeltranslation = ["0.17.0", "0.18.2"]
|
|
228
|
+
djangorestframework = ["3.14.0", "3.15.0"]
|
|
229
|
+
simplejwt = ["5.3.1"]
|
|
230
|
+
django_hosts = ["6.0"]
|
|
231
|
+
[[tool.hatch.envs.mtest.matrix]]
|
|
232
|
+
python = ["3.10", "3.11", "3.12"]
|
|
233
|
+
django = ["5.0"]
|
|
234
|
+
modeltranslation = ["0.17.0", "0.18.2"]
|
|
235
|
+
djangorestframework = ["3.15.0"]
|
|
236
|
+
simplejwt = ["5.3.1"]
|
|
237
|
+
django_hosts = ["6.0"]
|
|
213
238
|
|
|
214
239
|
[tool.hatch.envs.docs]
|
|
215
240
|
description = "Docs environment"
|
|
216
241
|
detached = true
|
|
217
|
-
python = "3.
|
|
242
|
+
python = "3.12"
|
|
218
243
|
dependencies = [
|
|
219
244
|
"mkdocs[i18n]==1.5.3",
|
|
220
245
|
"mkdocs-literate-nav==0.6.1",
|
|
221
|
-
"mkdocs-material==9.5.
|
|
222
|
-
"mkdocs-git-revision-date-localized-plugin==1.2.
|
|
223
|
-
"mkdocs-git-authors-plugin==0.
|
|
224
|
-
"mkdocstrings[python]==0.
|
|
225
|
-
"black==24.
|
|
246
|
+
"mkdocs-material==9.5.17",
|
|
247
|
+
"mkdocs-git-revision-date-localized-plugin==1.2.6",
|
|
248
|
+
"mkdocs-git-authors-plugin==0.9.0",
|
|
249
|
+
"mkdocstrings[python]==0.25.1",
|
|
250
|
+
"black==24.4.2",
|
|
226
251
|
"mkdocs-minify-plugin==0.8.0",
|
|
227
252
|
"mkdocs-gen-files==0.5.0",
|
|
228
|
-
"Pygments==2.
|
|
229
|
-
"mike==1.1
|
|
253
|
+
"Pygments==2.18.0",
|
|
254
|
+
"mike==2.1.1",
|
|
230
255
|
"linkchecker==10.4.0",
|
|
231
256
|
]
|
|
232
257
|
[tool.hatch.envs.docs.env-vars]
|
|
@@ -244,13 +269,14 @@ build-check = [
|
|
|
244
269
|
|
|
245
270
|
[tool.black]
|
|
246
271
|
line-length = 100
|
|
247
|
-
target-version = ["
|
|
272
|
+
target-version = ["py310"]
|
|
248
273
|
|
|
249
274
|
[tool.ruff]
|
|
250
|
-
target-version = "
|
|
275
|
+
target-version = "py310"
|
|
251
276
|
line-length = 100
|
|
252
277
|
show-fixes = true
|
|
253
278
|
# update-check = true
|
|
279
|
+
[tool.ruff.lint]
|
|
254
280
|
select = [
|
|
255
281
|
"A",
|
|
256
282
|
"B",
|
|
@@ -292,32 +318,34 @@ ignore = [
|
|
|
292
318
|
# "PLC1901", # empty string comparisons
|
|
293
319
|
# "PLW2901", # `for` loop variable overwritten
|
|
294
320
|
"SIM114", # Combine `if` branches using logical `or` operator
|
|
321
|
+
"ISC001", # Disabled as ruff recomendation from warning
|
|
295
322
|
]
|
|
296
323
|
# unfixable = [
|
|
297
324
|
# # Don't touch unused imports
|
|
298
325
|
# "F401",
|
|
299
326
|
# ]
|
|
300
|
-
[tool.ruff.
|
|
327
|
+
[tool.ruff.lint.per-file-ignores]
|
|
301
328
|
"__init__.py" = ["F401", "F403"]
|
|
302
329
|
"test_*.py" = ["S101", "PLR2004", "DTZ001", "RUF012"]
|
|
303
330
|
"*/migrations/*" = ["I", "E", "Q", "RUF"]
|
|
304
331
|
"test_project/*models.py" = ["RUF012"]
|
|
305
332
|
"test_project/*views.py" = ["RUF012"]
|
|
306
|
-
[tool.ruff.flake8-import-conventions]
|
|
307
|
-
[tool.ruff.flake8-import-conventions.extend-aliases]
|
|
333
|
+
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
|
|
308
334
|
"datetime" = "dt"
|
|
309
335
|
# [tool.ruff.flake8-quotes]
|
|
310
336
|
# inline-quotes = "single"
|
|
311
|
-
[tool.ruff.flake8-unused-arguments]
|
|
337
|
+
[tool.ruff.lint.flake8-unused-arguments]
|
|
312
338
|
ignore-variadic-names = true
|
|
313
|
-
[tool.ruff.isort]
|
|
339
|
+
[tool.ruff.lint.isort]
|
|
314
340
|
force-single-line = true
|
|
315
341
|
known-first-party = ["meringue"]
|
|
316
342
|
lines-after-imports = 2
|
|
317
343
|
no-lines-before = ["local-folder"]
|
|
318
344
|
section-order = ["future", "standard-library", "django", "third-party", "first-party", "local-folder"]
|
|
319
|
-
[tool.ruff.isort.sections]
|
|
345
|
+
[tool.ruff.lint.isort.sections]
|
|
320
346
|
django = ["django"]
|
|
347
|
+
[tool.ruff.format]
|
|
348
|
+
exclude = ["*/migrations/*"]
|
|
321
349
|
|
|
322
350
|
[tool.isort]
|
|
323
351
|
known_first_party = ["meringue"]
|
|
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
|