ramifice 0.8.10__py3-none-any.whl → 0.8.12__py3-none-any.whl
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.
- ramifice/__init__.py +16 -1
- ramifice/commons/__init__.py +2 -2
- ramifice/commons/general.py +11 -11
- ramifice/commons/indexes.py +8 -8
- ramifice/commons/many.py +10 -6
- ramifice/commons/one.py +13 -8
- ramifice/commons/tools.py +4 -4
- ramifice/commons/unit_manager.py +15 -5
- ramifice/fields/__init__.py +1 -1
- ramifice/fields/bool_field.py +26 -18
- ramifice/fields/choice_float_dyn_field.py +29 -21
- ramifice/fields/choice_float_field.py +41 -33
- ramifice/fields/choice_float_mult_dyn_field.py +29 -21
- ramifice/fields/choice_float_mult_field.py +48 -40
- ramifice/fields/choice_int_dyn_field.py +29 -21
- ramifice/fields/choice_int_field.py +41 -33
- ramifice/fields/choice_int_mult_dyn_field.py +29 -21
- ramifice/fields/choice_int_mult_field.py +48 -40
- ramifice/fields/choice_text_dyn_field.py +29 -21
- ramifice/fields/choice_text_field.py +47 -39
- ramifice/fields/choice_text_mult_dyn_field.py +29 -21
- ramifice/fields/choice_text_mult_field.py +48 -40
- ramifice/fields/color_field.py +40 -32
- ramifice/fields/date_field.py +49 -40
- ramifice/fields/date_time_field.py +49 -40
- ramifice/fields/email_field.py +42 -34
- ramifice/fields/file_field.py +45 -35
- ramifice/fields/float_field.py +56 -47
- ramifice/fields/general/__init__.py +1 -1
- ramifice/fields/general/choice_group.py +2 -2
- ramifice/fields/general/date_group.py +2 -2
- ramifice/fields/general/field.py +2 -2
- ramifice/fields/general/file_group.py +2 -2
- ramifice/fields/general/number_group.py +2 -2
- ramifice/fields/general/text_group.py +3 -3
- ramifice/fields/id_field.py +35 -28
- ramifice/fields/image_field.py +67 -57
- ramifice/fields/integer_field.py +56 -47
- ramifice/fields/ip_field.py +41 -34
- ramifice/fields/password_field.py +29 -22
- ramifice/fields/phone_field.py +44 -36
- ramifice/fields/slug_field.py +30 -22
- ramifice/fields/text_field.py +43 -35
- ramifice/fields/url_field.py +40 -33
- ramifice/models/__init__.py +1 -1
- ramifice/models/decorator.py +33 -11
- ramifice/models/model.py +16 -16
- ramifice/paladins/__init__.py +2 -2
- ramifice/paladins/check.py +58 -51
- ramifice/paladins/delete.py +9 -3
- ramifice/paladins/groups/__init__.py +1 -1
- ramifice/paladins/groups/bool_group.py +3 -3
- ramifice/paladins/groups/choice_group.py +3 -3
- ramifice/paladins/groups/date_group.py +3 -3
- ramifice/paladins/groups/file_group.py +3 -3
- ramifice/paladins/groups/id_group.py +3 -3
- ramifice/paladins/groups/img_group.py +36 -35
- ramifice/paladins/groups/num_group.py +3 -3
- ramifice/paladins/groups/pass_group.py +3 -3
- ramifice/paladins/groups/slug_group.py +8 -3
- ramifice/paladins/groups/text_group.py +3 -3
- ramifice/paladins/password.py +11 -4
- ramifice/paladins/refrash.py +7 -3
- ramifice/paladins/save.py +9 -3
- ramifice/paladins/tools.py +11 -6
- ramifice/paladins/validation.py +4 -4
- ramifice/utils/__init__.py +1 -1
- ramifice/utils/constants.py +1 -1
- ramifice/utils/errors.py +7 -7
- ramifice/utils/fixtures.py +7 -2
- ramifice/utils/migration.py +18 -9
- ramifice/utils/mixins/__init__.py +1 -1
- ramifice/utils/mixins/add_valid.py +3 -3
- ramifice/utils/mixins/hooks.py +8 -8
- ramifice/utils/mixins/indexing.py +3 -3
- ramifice/utils/mixins/json_converter.py +6 -6
- ramifice/utils/tools.py +12 -12
- ramifice/utils/translations.py +8 -4
- ramifice/utils/unit.py +8 -3
- {ramifice-0.8.10.dist-info → ramifice-0.8.12.dist-info}/METADATA +1 -1
- ramifice-0.8.12.dist-info/RECORD +84 -0
- ramifice-0.8.10.dist-info/RECORD +0 -84
- {ramifice-0.8.10.dist-info → ramifice-0.8.12.dist-info}/WHEEL +0 -0
- {ramifice-0.8.10.dist-info → ramifice-0.8.12.dist-info}/licenses/LICENSE +0 -0
ramifice/fields/url_field.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
"""Field of Model for enter URL address."""
|
1
|
+
"""Ramifice - Field of Model for enter URL address."""
|
2
2
|
|
3
3
|
__all__ = ("URLField",)
|
4
4
|
|
5
|
+
import logging
|
5
6
|
from urllib.parse import urlparse
|
6
7
|
|
7
8
|
from ramifice.fields.general.field import Field
|
@@ -9,9 +10,11 @@ from ramifice.fields.general.text_group import TextGroup
|
|
9
10
|
from ramifice.utils import constants
|
10
11
|
from ramifice.utils.mixins.json_converter import JsonMixin
|
11
12
|
|
13
|
+
logger = logging.getLogger(__name__)
|
14
|
+
|
12
15
|
|
13
16
|
class URLField(Field, TextGroup, JsonMixin):
|
14
|
-
"""Field of Model for enter URL address.
|
17
|
+
"""Ramifice - Field of Model for enter URL address.
|
15
18
|
|
16
19
|
Attributes:
|
17
20
|
label -- Text label for a web form field.
|
@@ -42,38 +45,42 @@ class URLField(Field, TextGroup, JsonMixin):
|
|
42
45
|
unique: bool = False,
|
43
46
|
):
|
44
47
|
if constants.DEBUG:
|
45
|
-
|
46
|
-
if not
|
48
|
+
try:
|
49
|
+
if default is not None:
|
50
|
+
if not isinstance(default, str):
|
51
|
+
raise AssertionError("Parameter `default` - Not а `str` type!")
|
52
|
+
if len(default) == 0:
|
53
|
+
raise AssertionError(
|
54
|
+
"The `default` parameter should not contain an empty string!"
|
55
|
+
)
|
56
|
+
result = urlparse(default)
|
57
|
+
if not result.scheme or not result.netloc:
|
58
|
+
raise AssertionError("Parameter `default` - Invalid URL address!")
|
59
|
+
if not isinstance(label, str):
|
47
60
|
raise AssertionError("Parameter `default` - Not а `str` type!")
|
48
|
-
if
|
49
|
-
raise AssertionError(
|
50
|
-
|
51
|
-
)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
raise
|
71
|
-
if not isinstance(required, bool):
|
72
|
-
raise AssertionError("Parameter `required` - Not а `bool` type!")
|
73
|
-
if not isinstance(readonly, bool):
|
74
|
-
raise AssertionError("Parameter `readonly` - Not а `bool` type!")
|
75
|
-
if not isinstance(unique, bool):
|
76
|
-
raise AssertionError("Parameter `unique` - Not а `bool` type!")
|
61
|
+
if not isinstance(disabled, bool):
|
62
|
+
raise AssertionError("Parameter `disabled` - Not а `bool` type!")
|
63
|
+
if not isinstance(hide, bool):
|
64
|
+
raise AssertionError("Parameter `hide` - Not а `bool` type!")
|
65
|
+
if not isinstance(ignored, bool):
|
66
|
+
raise AssertionError("Parameter `ignored` - Not а `bool` type!")
|
67
|
+
if not isinstance(ignored, bool):
|
68
|
+
raise AssertionError("Parameter `ignored` - Not а `bool` type!")
|
69
|
+
if not isinstance(hint, str):
|
70
|
+
raise AssertionError("Parameter `hint` - Not а `str` type!")
|
71
|
+
if warning is not None and not isinstance(warning, list):
|
72
|
+
raise AssertionError("Parameter `warning` - Not а `list` type!")
|
73
|
+
if not isinstance(placeholder, str):
|
74
|
+
raise AssertionError("Parameter `placeholder` - Not а `str` type!")
|
75
|
+
if not isinstance(required, bool):
|
76
|
+
raise AssertionError("Parameter `required` - Not а `bool` type!")
|
77
|
+
if not isinstance(readonly, bool):
|
78
|
+
raise AssertionError("Parameter `readonly` - Not а `bool` type!")
|
79
|
+
if not isinstance(unique, bool):
|
80
|
+
raise AssertionError("Parameter `unique` - Not а `bool` type!")
|
81
|
+
except AssertionError as err:
|
82
|
+
logger.error(str(err))
|
83
|
+
raise err
|
77
84
|
|
78
85
|
Field.__init__(
|
79
86
|
self,
|
ramifice/models/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"""Models."""
|
1
|
+
"""Ramifice - Models."""
|
ramifice/models/decorator.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
"""Decorator for converting Python classes into Ramifice models."""
|
1
|
+
"""Ramifice - Decorator for converting Python classes into Ramifice models."""
|
2
2
|
|
3
3
|
__all__ = ("model",)
|
4
4
|
|
5
|
+
import logging
|
5
6
|
import re
|
6
7
|
from os.path import exists
|
7
8
|
from typing import Any
|
@@ -16,6 +17,8 @@ from ramifice.utils.mixins.add_valid import AddValidMixin
|
|
16
17
|
from ramifice.utils.mixins.hooks import HooksMixin
|
17
18
|
from ramifice.utils.mixins.indexing import IndexMixin
|
18
19
|
|
20
|
+
logger = logging.getLogger(__name__)
|
21
|
+
|
19
22
|
|
20
23
|
def model(
|
21
24
|
service_name: str,
|
@@ -25,23 +28,38 @@ def model(
|
|
25
28
|
is_update_doc: bool = True,
|
26
29
|
is_delete_doc: bool = True,
|
27
30
|
) -> Any:
|
28
|
-
"""Decorator for converting Python Classe into Ramifice Model."""
|
31
|
+
"""Ramifice - Decorator for converting Python Classe into Ramifice Model."""
|
29
32
|
if not isinstance(service_name, str):
|
30
|
-
|
33
|
+
msg = "Parameter `service_name` - Must be `str` type!"
|
34
|
+
logger.error(msg)
|
35
|
+
raise AssertionError(msg)
|
31
36
|
if not isinstance(fixture_name, (str, type(None))):
|
32
|
-
|
37
|
+
msg = "Parameter `fixture_name` - Must be `str | None` type!"
|
38
|
+
logger.error(msg)
|
39
|
+
raise AssertionError(msg)
|
33
40
|
if not isinstance(db_query_docs_limit, int):
|
34
|
-
|
41
|
+
msg = "Parameter `db_query_docs_limit` - Must be `int` type!"
|
42
|
+
logger.error(msg)
|
43
|
+
raise AssertionError(msg)
|
35
44
|
if not isinstance(is_create_doc, bool):
|
36
|
-
|
45
|
+
msg = "Parameter `is_create_doc` - Must be `bool` type!"
|
46
|
+
logger.error(msg)
|
47
|
+
raise AssertionError(msg)
|
37
48
|
if not isinstance(is_update_doc, bool):
|
38
|
-
|
49
|
+
msg = "Parameter `is_update_doc` - Must be `bool` type!"
|
50
|
+
logger.error(msg)
|
51
|
+
raise AssertionError(msg)
|
39
52
|
if not isinstance(is_delete_doc, bool):
|
40
|
-
|
53
|
+
msg = "Parameter `is_delete_doc` - Must be `bool` type!"
|
54
|
+
logger.error(msg)
|
55
|
+
raise AssertionError(msg)
|
41
56
|
|
42
57
|
def decorator(cls: Any) -> Any:
|
43
58
|
if REGEX["service_name"].match(service_name) is None:
|
44
|
-
|
59
|
+
regex_str: str = "^[A-Z][a-zA-Z0-9]{0,24}$"
|
60
|
+
msg = f"Does not match the regular expression: {regex_str}"
|
61
|
+
logger.error(msg)
|
62
|
+
raise DoesNotMatchRegexError(regex_str)
|
45
63
|
if fixture_name is not None:
|
46
64
|
fixture_path = f"config/fixtures/{fixture_name}.yml"
|
47
65
|
|
@@ -51,6 +69,7 @@ def model(
|
|
51
69
|
+ f"META param: `fixture_name` => "
|
52
70
|
+ f"Fixture the `{fixture_path}` not exists!"
|
53
71
|
)
|
72
|
+
logger.error(msg)
|
54
73
|
raise PanicError(msg)
|
55
74
|
|
56
75
|
attrs = {key: val for key, val in cls.__dict__.items()}
|
@@ -85,11 +104,14 @@ def model(
|
|
85
104
|
|
86
105
|
|
87
106
|
def caching(cls: Any, service_name: str) -> dict[str, Any]:
|
88
|
-
"""Add additional metadata to `Model.META`."""
|
107
|
+
"""Ramifice - Add additional metadata to `Model.META`."""
|
89
108
|
metadata: dict[str, Any] = {}
|
90
109
|
model_name: str = cls.__name__
|
91
110
|
if REGEX["model_name"].match(model_name) is None:
|
92
|
-
|
111
|
+
regex_str: str = "^[A-Z][a-zA-Z0-9]{0,24}$"
|
112
|
+
msg = f"Does not match the regular expression: {regex_str}"
|
113
|
+
logger.error(msg)
|
114
|
+
raise DoesNotMatchRegexError(regex_str)
|
93
115
|
#
|
94
116
|
metadata["model_name"] = model_name
|
95
117
|
metadata["full_model_name"] = f"{cls.__module__}.{model_name}"
|
ramifice/models/model.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""
|
1
|
+
"""Ramifice - Converting Python classes into Ramifice Models."""
|
2
2
|
|
3
3
|
__all__ = ("Model",)
|
4
4
|
|
@@ -15,7 +15,7 @@ from ramifice.utils import translations
|
|
15
15
|
|
16
16
|
|
17
17
|
class Model(metaclass=ABCMeta):
|
18
|
-
"""Converting Python Class into Ramifice Model."""
|
18
|
+
"""Ramifice - Converting Python Class into Ramifice Model."""
|
19
19
|
|
20
20
|
META: dict[str, Any] = {}
|
21
21
|
|
@@ -49,25 +49,25 @@ class Model(metaclass=ABCMeta):
|
|
49
49
|
|
50
50
|
@property
|
51
51
|
def id(self) -> IDField:
|
52
|
-
"""Getter for the field `_id`."""
|
52
|
+
"""Ramifice - Getter for the field `_id`."""
|
53
53
|
return self._id
|
54
54
|
|
55
55
|
@abstractmethod
|
56
56
|
def fields(self) -> None:
|
57
|
-
"""
|
57
|
+
"""Ramifice - Adding fields."""
|
58
58
|
pass
|
59
59
|
|
60
60
|
def model_name(self) -> str:
|
61
|
-
"""Get Model name - Class name."""
|
61
|
+
"""Ramifice - Get Model name - Class name."""
|
62
62
|
return self.__class__.__name__
|
63
63
|
|
64
64
|
def full_model_name(self) -> str:
|
65
|
-
"""Get full Model name - module_name + . + ClassName."""
|
65
|
+
"""Ramifice - Get full Model name - module_name + . + ClassName."""
|
66
66
|
cls = self.__class__
|
67
67
|
return f"{cls.__module__}.{cls.__name__}"
|
68
68
|
|
69
69
|
def inject(self) -> None:
|
70
|
-
"""Injecting metadata from Model.META in params of fields."""
|
70
|
+
"""Ramifice - Injecting metadata from Model.META in params of fields."""
|
71
71
|
metadata = self.__class__.META
|
72
72
|
if bool(metadata):
|
73
73
|
lang = translations.CURRENT_LOCALE
|
@@ -91,7 +91,7 @@ class Model(metaclass=ABCMeta):
|
|
91
91
|
# Complect of methods for converting Model to JSON and back.
|
92
92
|
# --------------------------------------------------------------------------
|
93
93
|
def to_dict(self) -> dict[str, Any]:
|
94
|
-
"""Convert object instance to a dictionary."""
|
94
|
+
"""Ramifice - Convert object instance to a dictionary."""
|
95
95
|
json_dict: dict[str, Any] = {}
|
96
96
|
for name, data in self.__dict__.items():
|
97
97
|
if not callable(data):
|
@@ -99,12 +99,12 @@ class Model(metaclass=ABCMeta):
|
|
99
99
|
return json_dict
|
100
100
|
|
101
101
|
def to_json(self) -> str:
|
102
|
-
"""Convert object instance to a JSON string."""
|
102
|
+
"""Ramifice - Convert object instance to a JSON string."""
|
103
103
|
return orjson.dumps(self.to_dict()).decode("utf-8")
|
104
104
|
|
105
105
|
@classmethod
|
106
106
|
def from_dict(cls, json_dict: dict[str, Any]) -> Any:
|
107
|
-
"""Convert JSON string to a object instance."""
|
107
|
+
"""Ramifice - Convert JSON string to a object instance."""
|
108
108
|
obj = cls()
|
109
109
|
for name, data in json_dict.items():
|
110
110
|
obj.__dict__[name] = obj.__dict__[name].__class__.from_dict(data)
|
@@ -112,13 +112,13 @@ class Model(metaclass=ABCMeta):
|
|
112
112
|
|
113
113
|
@classmethod
|
114
114
|
def from_json(cls, json_str: str) -> Any:
|
115
|
-
"""Convert JSON string to a object instance."""
|
115
|
+
"""Ramifice - Convert JSON string to a object instance."""
|
116
116
|
json_dict = orjson.loads(json_str)
|
117
117
|
return cls.from_dict(json_dict)
|
118
118
|
|
119
119
|
# --------------------------------------------------------------------------
|
120
120
|
def to_dict_only_value(self) -> dict[str, Any]:
|
121
|
-
"""Convert model.field.value (only the `value` attribute) to a dictionary."""
|
121
|
+
"""Ramifice - Convert model.field.value (only the `value` attribute) to a dictionary."""
|
122
122
|
json_dict: dict[str, Any] = {}
|
123
123
|
current_locale = translations.CURRENT_LOCALE
|
124
124
|
for name, data in self.__dict__.items():
|
@@ -149,12 +149,12 @@ class Model(metaclass=ABCMeta):
|
|
149
149
|
return json_dict
|
150
150
|
|
151
151
|
def to_json_only_value(self) -> str:
|
152
|
-
"""Convert model.field.value (only the `value` attribute) to a JSON string."""
|
152
|
+
"""Ramifice - Convert model.field.value (only the `value` attribute) to a JSON string."""
|
153
153
|
return orjson.dumps(self.to_dict_only_value()).decode("utf-8")
|
154
154
|
|
155
155
|
@classmethod
|
156
156
|
def from_dict_only_value(cls, json_dict: dict[str, Any]) -> Any:
|
157
|
-
"""Convert JSON string to a object instance."""
|
157
|
+
"""Ramifice - Convert JSON string to a object instance."""
|
158
158
|
obj = cls()
|
159
159
|
for name, data in obj.__dict__.items():
|
160
160
|
if callable(data):
|
@@ -171,12 +171,12 @@ class Model(metaclass=ABCMeta):
|
|
171
171
|
|
172
172
|
@classmethod
|
173
173
|
def from_json_only_value(cls, json_str: str) -> Any:
|
174
|
-
"""Convert JSON string to a object instance."""
|
174
|
+
"""Ramifice - Convert JSON string to a object instance."""
|
175
175
|
json_dict = orjson.loads(json_str)
|
176
176
|
return cls.from_dict_only_value(json_dict)
|
177
177
|
|
178
178
|
def refrash_fields_only_value(self, only_value_dict: dict[str, Any]) -> None:
|
179
|
-
"""Partial or complete update a `value` of fields."""
|
179
|
+
"""Ramifice - Partial or complete update a `value` of fields."""
|
180
180
|
for name, data in self.__dict__.items():
|
181
181
|
if callable(data):
|
182
182
|
continue
|
ramifice/paladins/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Paladins - Model instance methods."""
|
1
|
+
"""Ramifice - Paladins - Model instance methods."""
|
2
2
|
|
3
3
|
__all__ = ("QPaladinsMixin",)
|
4
4
|
|
@@ -18,7 +18,7 @@ class QPaladinsMixin(
|
|
18
18
|
RefrashMixin,
|
19
19
|
ValidationMixin,
|
20
20
|
):
|
21
|
-
"""Paladins - Model instance methods."""
|
21
|
+
"""Ramifice - Paladins - Model instance methods."""
|
22
22
|
|
23
23
|
def __init__(self) -> None: # noqa: D107
|
24
24
|
super().__init__()
|
ramifice/paladins/check.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
"""Validation of Model data before saving to the database."""
|
1
|
+
"""Ramifice - Validation of Model data before saving to the database."""
|
2
2
|
|
3
3
|
__all__ = ("CheckMixin",)
|
4
4
|
|
5
|
+
import logging
|
5
6
|
from os import remove
|
6
7
|
from shutil import rmtree
|
7
|
-
from typing import Any
|
8
|
+
from typing import Any, assert_never
|
8
9
|
|
9
10
|
from anyio import to_thread
|
10
11
|
from bson.objectid import ObjectId
|
@@ -24,6 +25,8 @@ from ramifice.paladins.groups import (
|
|
24
25
|
)
|
25
26
|
from ramifice.utils import constants
|
26
27
|
|
28
|
+
logger = logging.getLogger(__name__)
|
29
|
+
|
27
30
|
|
28
31
|
class CheckMixin(
|
29
32
|
BoolGroupMixin,
|
@@ -37,7 +40,7 @@ class CheckMixin(
|
|
37
40
|
SlugGroupMixin,
|
38
41
|
TextGroupMixin,
|
39
42
|
):
|
40
|
-
"""Validation of Model data before saving to the database."""
|
43
|
+
"""Ramifice - Validation of Model data before saving to the database."""
|
41
44
|
|
42
45
|
async def check(
|
43
46
|
self,
|
@@ -45,7 +48,7 @@ class CheckMixin(
|
|
45
48
|
collection: AsyncCollection | None = None,
|
46
49
|
is_migration_process: bool = False,
|
47
50
|
) -> dict[str, Any]:
|
48
|
-
"""Validation of Model data before saving to the database.
|
51
|
+
"""Ramifice - Validation of Model data before saving to the database.
|
49
52
|
|
50
53
|
It is also used to verify Models that do not migrate to the database.
|
51
54
|
"""
|
@@ -96,28 +99,32 @@ class CheckMixin(
|
|
96
99
|
params["is_error_symptom"] = True
|
97
100
|
# Checking the fields by groups.
|
98
101
|
if not field_data.ignored:
|
99
|
-
group = field_data.group
|
100
102
|
params["field_data"] = field_data
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
103
|
+
match field_data.group:
|
104
|
+
case "text":
|
105
|
+
await self.text_group(params)
|
106
|
+
case "num":
|
107
|
+
await self.num_group(params)
|
108
|
+
case "date":
|
109
|
+
self.date_group(params)
|
110
|
+
case "img":
|
111
|
+
await self.img_group(params)
|
112
|
+
case "file":
|
113
|
+
await self.file_group(params)
|
114
|
+
case "choice":
|
115
|
+
self.choice_group(params)
|
116
|
+
case "bool":
|
117
|
+
self.bool_group(params)
|
118
|
+
case "id":
|
119
|
+
self.id_group(params)
|
120
|
+
case "slug":
|
121
|
+
await self.slug_group(params)
|
122
|
+
case "pass":
|
123
|
+
self.pass_group(params)
|
124
|
+
case _ as unreachable:
|
125
|
+
msg: str = f"Unacceptable group `{unreachable}`!"
|
126
|
+
logger.error(msg)
|
127
|
+
assert_never(unreachable)
|
121
128
|
|
122
129
|
# Actions in case of error.
|
123
130
|
if is_save:
|
@@ -130,36 +137,36 @@ class CheckMixin(
|
|
130
137
|
for field_name, field_data in self.__dict__.items():
|
131
138
|
if callable(field_data) or field_data.ignored:
|
132
139
|
continue
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
140
|
+
match field_data.group:
|
141
|
+
case "file":
|
142
|
+
file_data = result_map.get(field_name)
|
143
|
+
if file_data is not None:
|
144
|
+
if file_data["is_new_file"]:
|
145
|
+
await to_thread.run_sync(remove, file_data["path"])
|
146
|
+
field_data.value = None
|
147
|
+
if curr_doc is not None:
|
148
|
+
field_data.value = curr_doc[field_name]
|
149
|
+
case "img":
|
150
|
+
img_data = result_map.get(field_name)
|
151
|
+
if img_data is not None:
|
152
|
+
if img_data["is_new_img"]:
|
153
|
+
await to_thread.run_sync(rmtree, img_data["imgs_dir_path"])
|
154
|
+
field_data.value = None
|
155
|
+
if curr_doc is not None:
|
156
|
+
field_data.value = curr_doc[field_name]
|
150
157
|
else:
|
151
158
|
for field_name, field_data in self.__dict__.items():
|
152
159
|
if callable(field_data) or field_data.ignored:
|
153
160
|
continue
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
161
|
+
match field_data.group:
|
162
|
+
case "file":
|
163
|
+
file_data = result_map.get(field_name)
|
164
|
+
if file_data is not None:
|
165
|
+
file_data["is_new_file"] = False
|
166
|
+
case "img":
|
167
|
+
img_data = result_map.get(field_name)
|
168
|
+
if img_data is not None:
|
169
|
+
img_data["is_new_img"] = False
|
163
170
|
#
|
164
171
|
return dict(
|
165
172
|
data=result_map,
|
ramifice/paladins/delete.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
"""Delete document from database."""
|
1
|
+
"""Ramifice - Delete document from database."""
|
2
2
|
|
3
3
|
__all__ = ("DeleteMixin",)
|
4
4
|
|
5
|
+
import logging
|
5
6
|
from os import remove
|
6
7
|
from shutil import rmtree
|
7
8
|
from typing import Any
|
@@ -12,9 +13,11 @@ from pymongo.asynchronous.collection import AsyncCollection
|
|
12
13
|
from ramifice.utils import constants
|
13
14
|
from ramifice.utils.errors import PanicError
|
14
15
|
|
16
|
+
logger = logging.getLogger(__name__)
|
17
|
+
|
15
18
|
|
16
19
|
class DeleteMixin:
|
17
|
-
"""Delete document from database."""
|
20
|
+
"""Ramifice - Delete document from database."""
|
18
21
|
|
19
22
|
async def delete(
|
20
23
|
self,
|
@@ -27,7 +30,7 @@ class DeleteMixin:
|
|
27
30
|
comment: Any | None = None,
|
28
31
|
**kwargs: dict[str, Any],
|
29
32
|
) -> dict[str, Any]:
|
30
|
-
"""Delete document from database."""
|
33
|
+
"""Ramifice - Delete document from database."""
|
31
34
|
cls_model = self.__class__
|
32
35
|
# Raises a panic if the Model cannot be removed.
|
33
36
|
if not cls_model.META["is_delete_doc"]:
|
@@ -36,6 +39,7 @@ class DeleteMixin:
|
|
36
39
|
+ "META param: `is_delete_doc` (False) => "
|
37
40
|
+ "Documents of this Model cannot be removed from the database!"
|
38
41
|
)
|
42
|
+
logger.error(msg)
|
39
43
|
raise PanicError(msg)
|
40
44
|
# Get documet ID.
|
41
45
|
doc_id = self._id.value
|
@@ -45,6 +49,7 @@ class DeleteMixin:
|
|
45
49
|
+ "Field: `_id` > "
|
46
50
|
+ "Param: `value` => ID is missing."
|
47
51
|
)
|
52
|
+
logger.error(msg)
|
48
53
|
raise PanicError(msg)
|
49
54
|
# Run hook.
|
50
55
|
await self.pre_delete()
|
@@ -69,6 +74,7 @@ class DeleteMixin:
|
|
69
74
|
+ "Method: `delete` => "
|
70
75
|
+ "The document was not deleted, the document is absent in the database."
|
71
76
|
)
|
77
|
+
logger.error(msg)
|
72
78
|
raise PanicError(msg)
|
73
79
|
# Delete orphaned files and add None to field.value.
|
74
80
|
file_data: dict[str, Any] | None = None
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Groups - Model instance methods for specific processing of fields."""
|
1
|
+
"""Ramifice - Groups - Model instance methods for specific processing of fields."""
|
2
2
|
|
3
3
|
from ramifice.paladins.groups.bool_group import BoolGroupMixin
|
4
4
|
from ramifice.paladins.groups.choice_group import ChoiceGroupMixin
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Group for checking boolean fields.
|
1
|
+
"""Ramifice - Group for checking boolean fields.
|
2
2
|
|
3
3
|
Supported fields:
|
4
4
|
BooleanField
|
@@ -12,14 +12,14 @@ from ramifice.paladins.tools import panic_type_error
|
|
12
12
|
|
13
13
|
|
14
14
|
class BoolGroupMixin:
|
15
|
-
"""Group for checking boolean fields.
|
15
|
+
"""Ramifice - Group for checking boolean fields.
|
16
16
|
|
17
17
|
Supported fields:
|
18
18
|
BooleanField
|
19
19
|
"""
|
20
20
|
|
21
21
|
def bool_group(self, params: dict[str, Any]) -> None:
|
22
|
-
"""Checking boolean fields."""
|
22
|
+
"""Ramifice - Checking boolean fields."""
|
23
23
|
field = params["field_data"]
|
24
24
|
# Get current value.
|
25
25
|
value = field.value
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Group for checking choice fields.
|
1
|
+
"""Ramifice - Group for checking choice fields.
|
2
2
|
|
3
3
|
Supported fields:
|
4
4
|
ChoiceTextMultField | ChoiceTextMultDynField | ChoiceTextField
|
@@ -16,7 +16,7 @@ from ramifice.utils import translations
|
|
16
16
|
|
17
17
|
|
18
18
|
class ChoiceGroupMixin:
|
19
|
-
"""Group for checking choice fields.
|
19
|
+
"""Ramifice - Group for checking choice fields.
|
20
20
|
|
21
21
|
Supported fields:
|
22
22
|
ChoiceTextMultField | ChoiceTextMultDynField | ChoiceTextField
|
@@ -26,7 +26,7 @@ class ChoiceGroupMixin:
|
|
26
26
|
"""
|
27
27
|
|
28
28
|
def choice_group(self, params: dict[str, Any]) -> None:
|
29
|
-
"""Checking choice fields."""
|
29
|
+
"""Ramifice - Checking choice fields."""
|
30
30
|
field = params["field_data"]
|
31
31
|
is_migrate = params["is_migration_process"]
|
32
32
|
# Get current value.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Group for checking date fields.
|
1
|
+
"""Ramifice - Group for checking date fields.
|
2
2
|
|
3
3
|
Supported fields:
|
4
4
|
DateTimeField | DateField
|
@@ -19,14 +19,14 @@ from ramifice.utils import translations
|
|
19
19
|
|
20
20
|
|
21
21
|
class DateGroupMixin:
|
22
|
-
"""Group for checking date fields.
|
22
|
+
"""Ramifice - Group for checking date fields.
|
23
23
|
|
24
24
|
Supported fields:
|
25
25
|
DateTimeField | DateField
|
26
26
|
"""
|
27
27
|
|
28
28
|
def date_group(self, params: dict[str, Any]) -> None:
|
29
|
-
"""Checking date fields."""
|
29
|
+
"""Ramifice - Checking date fields."""
|
30
30
|
field = params["field_data"]
|
31
31
|
# Get current value.
|
32
32
|
value = field.value or field.default or None
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Group for checking file fields.
|
1
|
+
"""Ramifice - Group for checking file fields.
|
2
2
|
|
3
3
|
Supported fields: FileField
|
4
4
|
"""
|
@@ -16,13 +16,13 @@ from ramifice.utils.tools import to_human_size
|
|
16
16
|
|
17
17
|
|
18
18
|
class FileGroupMixin:
|
19
|
-
"""Group for checking file fields.
|
19
|
+
"""Ramifice - Group for checking file fields.
|
20
20
|
|
21
21
|
Supported fields: FileField
|
22
22
|
"""
|
23
23
|
|
24
24
|
async def file_group(self, params: dict[str, Any]) -> None:
|
25
|
-
"""Checking file fields."""
|
25
|
+
"""Ramifice - Checking file fields."""
|
26
26
|
field = params["field_data"]
|
27
27
|
value = field.value or None
|
28
28
|
|