ramifice 0.8.26__py3-none-any.whl → 0.8.27__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/commons/tools.py CHANGED
@@ -21,11 +21,7 @@ def correct_mongo_filter(cls_model: Any, filter: Any) -> Any:
21
21
  """
22
22
  lang: str = translations.CURRENT_LOCALE
23
23
  filter_json: str = json_util.dumps(filter)
24
- filter_json = (
25
- cls_model.META["regex_mongo_filter"]
26
- .sub(rf'\g<field>.{lang}":', filter_json)
27
- .replace('":.', ".")
28
- )
24
+ filter_json = cls_model.META["regex_mongo_filter"].sub(rf'\g<field>.{lang}":', filter_json).replace('":.', ".")
29
25
  return json_util.loads(filter_json)
30
26
 
31
27
 
@@ -57,7 +57,7 @@ class EmailField(Field, TextGroup, JsonMixin):
57
57
  try:
58
58
  validate_email(default, check_deliverability=True)
59
59
  except EmailNotValidError:
60
- raise AssertionError("Parameter `default` - Invalid Email address!")
60
+ raise AssertionError("Parameter `default` - Invalid Email address!") # noqa: B904
61
61
  if not isinstance(label, str):
62
62
  raise AssertionError("Parameter `default` - Not а `str` type!")
63
63
  if not isinstance(disabled, bool):
@@ -5,7 +5,7 @@ __all__ = ("FileField",)
5
5
  import logging
6
6
  import uuid
7
7
  from base64 import b64decode
8
- from datetime import date
8
+ from datetime import datetime
9
9
  from os import makedirs
10
10
  from os.path import basename, exists, getsize
11
11
  from shutil import copyfile
@@ -62,9 +62,7 @@ class FileField(Field, FileGroup, JsonMixin):
62
62
  if not isinstance(default, str):
63
63
  raise AssertionError("Parameter `default` - Not а `str` type!")
64
64
  if len(default) == 0:
65
- raise AssertionError(
66
- "The `default` parameter should not contain an empty string!"
67
- )
65
+ raise AssertionError("The `default` parameter should not contain an empty string!")
68
66
  if not isinstance(label, str):
69
67
  raise AssertionError("Parameter `default` - Not а `str` type!")
70
68
  if not isinstance(disabled, bool):
@@ -149,7 +147,7 @@ class FileField(Field, FileGroup, JsonMixin):
149
147
  # Create new (uuid) file name.
150
148
  f_uuid_name = f"{uuid.uuid4()}{extension}"
151
149
  # Create the current date for the directory name.
152
- date_str: str = str(date.today())
150
+ date_str: str = str(datetime.now().date()) # noqa: DTZ005
153
151
  # Create path to target directory.
154
152
  dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
155
153
  # Create target directory if it does not exist.
@@ -195,7 +193,7 @@ class FileField(Field, FileGroup, JsonMixin):
195
193
  # Create new (uuid) file name.
196
194
  f_uuid_name = f"{uuid.uuid4()}{extension}"
197
195
  # Create the current date for the directory name.
198
- date_str: str = str(date.today())
196
+ date_str: str = str(datetime.now().date()) # noqa: DTZ005
199
197
  # Create path to target directory.
200
198
  dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
201
199
  # Create target directory if it does not exist.
@@ -2,10 +2,8 @@
2
2
 
3
3
  __all__ = ("ChoiceGroup",)
4
4
 
5
- from abc import ABCMeta
6
5
 
7
-
8
- class ChoiceGroup(metaclass=ABCMeta):
6
+ class ChoiceGroup: # noqa: B903
9
7
  """General additional parameters for choice fields.
10
8
 
11
9
  Args:
@@ -2,11 +2,10 @@
2
2
 
3
3
  __all__ = ("DateGroup",)
4
4
 
5
- from abc import ABCMeta
6
5
  from datetime import datetime
7
6
 
8
7
 
9
- class DateGroup(metaclass=ABCMeta):
8
+ class DateGroup:
10
9
  """General additional parameters for date|datetime fields.
11
10
 
12
11
  Args:
@@ -2,10 +2,8 @@
2
2
 
3
3
  __all__ = ("Field",)
4
4
 
5
- from abc import ABCMeta
6
5
 
7
-
8
- class Field(metaclass=ABCMeta):
6
+ class Field:
9
7
  """General parameters for all types fields of Model.
10
8
 
11
9
  Args:
@@ -28,7 +26,7 @@ class Field(metaclass=ABCMeta):
28
26
  ignored: bool = False,
29
27
  hint: str = "",
30
28
  warning: list[str] | None = None,
31
- errors: list[str] = [],
29
+ errors: list[str] = [], # noqa: B006
32
30
  field_type: str = "",
33
31
  group: str = "",
34
32
  ) -> None:
@@ -2,10 +2,8 @@
2
2
 
3
3
  __all__ = ("FileGroup",)
4
4
 
5
- from abc import ABCMeta
6
5
 
7
-
8
- class FileGroup(metaclass=ABCMeta):
6
+ class FileGroup:
9
7
  """General additional parameters for file fields.
10
8
 
11
9
  Args:
@@ -2,10 +2,8 @@
2
2
 
3
3
  __all__ = ("NumberGroup",)
4
4
 
5
- from abc import ABCMeta
6
5
 
7
-
8
- class NumberGroup(metaclass=ABCMeta):
6
+ class NumberGroup: # noqa: B903
9
7
  """General additional parameters for number fields.
10
8
 
11
9
  Args:
@@ -2,10 +2,8 @@
2
2
 
3
3
  __all__ = ("TextGroup",)
4
4
 
5
- from abc import ABCMeta
6
5
 
7
-
8
- class TextGroup(metaclass=ABCMeta):
6
+ class TextGroup:
9
7
  """General additional parameters for text fields.
10
8
 
11
9
  Args:
@@ -5,7 +5,7 @@ __all__ = ("ImageField",)
5
5
  import logging
6
6
  import uuid
7
7
  from base64 import b64decode
8
- from datetime import date
8
+ from datetime import datetime
9
9
  from os import makedirs
10
10
  from os.path import basename, exists, getsize
11
11
  from shutil import copyfile
@@ -57,7 +57,6 @@ class ImageField(Field, FileGroup, JsonMixin):
57
57
  target_dir: str = "images",
58
58
  accept: str = "image/png,image/jpeg,image/webp",
59
59
  # Available 4 sizes from lg to xs or None.
60
- # Example: {"lg": 1200, "md": 600, "sm": 300, "xs": 150 }
61
60
  thumbnails: dict[str, int] | None = None,
62
61
  ) -> None:
63
62
  if constants.DEBUG:
@@ -66,16 +65,12 @@ class ImageField(Field, FileGroup, JsonMixin):
66
65
  if not isinstance(default, str):
67
66
  raise AssertionError("Parameter `default` - Not а `str` type!")
68
67
  if len(default) == 0:
69
- raise AssertionError(
70
- "The `default` parameter should not contain an empty string!"
71
- )
68
+ raise AssertionError("The `default` parameter should not contain an empty string!")
72
69
  if thumbnails is not None:
73
70
  if not isinstance(thumbnails, dict):
74
71
  raise AssertionError("Parameter `thumbnails` - Not а `dict` type!")
75
72
  if len(thumbnails) == 0:
76
- raise AssertionError(
77
- "The `thumbnails` parameter should not contain an empty dictionary!"
78
- )
73
+ raise AssertionError("The `thumbnails` parameter should not contain an empty dictionary!")
79
74
  size_name_list = ["lg", "md", "sm", "xs"]
80
75
  curr_size_thumb: int = 0
81
76
  for size_name in thumbnails.keys():
@@ -146,7 +141,6 @@ class ImageField(Field, FileGroup, JsonMixin):
146
141
 
147
142
  self.value: dict[str, str | int | bool] | None = None
148
143
  # Available 4 sizes from lg to xs or None.
149
- # Example: {"lg": 1200, "md": 600, "sm": 300, "xs": 150 }
150
144
  self.thumbnails = thumbnails
151
145
 
152
146
  async def from_base64(
@@ -179,7 +173,7 @@ class ImageField(Field, FileGroup, JsonMixin):
179
173
  if item[0] == 40:
180
174
  break
181
175
  # Create the current date for the directory name.
182
- date_str: str = str(date.today())
176
+ date_str: str = str(datetime.now().date()) # noqa: DTZ005
183
177
  # Directory name for the original image and its thumbnails.
184
178
  general_dir = uuid.uuid4()
185
179
  # Create path to target directory with images.
@@ -238,7 +232,7 @@ class ImageField(Field, FileGroup, JsonMixin):
238
232
  logger.error(msg)
239
233
  raise FileHasNoExtensionError(msg)
240
234
  # Create the current date for the directory name.
241
- date_str: str = str(date.today())
235
+ date_str: str = str(datetime.now().date()) # noqa: DTZ005
242
236
  # Directory name for the original image and its thumbnails.
243
237
  general_dir = uuid.uuid4()
244
238
  # Create path to target directory with images.
@@ -56,7 +56,7 @@ class IPField(Field, TextGroup, JsonMixin):
56
56
  try:
57
57
  ipaddress.ip_address(default)
58
58
  except ValueError:
59
- raise AssertionError("Parameter `default` - Invalid IP address!")
59
+ raise AssertionError("Parameter `default` - Invalid IP address!") # noqa: B904
60
60
  if not isinstance(label, str):
61
61
  raise AssertionError("Parameter `default` - Not а `str` type!")
62
62
  if not isinstance(disabled, bool):
@@ -62,7 +62,7 @@ class PhoneField(Field, TextGroup, JsonMixin):
62
62
  if not phonenumbers.is_valid_number(phone_default):
63
63
  raise AssertionError()
64
64
  except phonenumbers.phonenumberutil.NumberParseException:
65
- raise AssertionError("Parameter `default` - Invalid Phone number!")
65
+ raise AssertionError("Parameter `default` - Invalid Phone number!") # noqa: B904
66
66
  if not isinstance(label, str):
67
67
  raise AssertionError("Parameter `default` - Not а `str` type!")
68
68
  if not isinstance(disabled, bool):
@@ -39,7 +39,7 @@ class SlugField(Field, TextGroup, JsonMixin):
39
39
  hint: str = "",
40
40
  warning: list[str] | None = None,
41
41
  readonly: bool = False,
42
- slug_sources: list[str] = ["_id"],
42
+ slug_sources: list[str] = ["_id"], # noqa: B006
43
43
  ) -> None:
44
44
  if constants.DEBUG:
45
45
  try:
@@ -61,13 +61,13 @@ def model(
61
61
  if not exists(fixture_path):
62
62
  msg = (
63
63
  f"Model: `{cls.__module__}.{cls.__name__}` > "
64
- + f"META param: `fixture_name` => "
64
+ + "META param: `fixture_name` => "
65
65
  + f"Fixture the `{fixture_path}` not exists!"
66
66
  )
67
67
  logger.critical(msg)
68
68
  raise PanicError(msg)
69
69
 
70
- attrs = {key: val for key, val in cls.__dict__.items()}
70
+ attrs = dict(cls.__dict__)
71
71
  attrs["__dict__"] = Model.__dict__["__dict__"]
72
72
  metadata = {
73
73
  "service_name": service_name,
ramifice/models/model.py CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  __all__ = ("Model",)
4
4
 
5
- from abc import ABCMeta, abstractmethod
6
- from typing import Any
5
+ from abc import abstractmethod
6
+ from typing import Any, ClassVar
7
7
 
8
8
  import orjson
9
9
  from babel.dates import format_date, format_datetime
@@ -15,10 +15,10 @@ from ramifice.fields import DateTimeField, IDField
15
15
  from ramifice.utils import translations
16
16
 
17
17
 
18
- class Model(metaclass=ABCMeta):
18
+ class Model:
19
19
  """Converting Python Class into Ramifice Model."""
20
20
 
21
- META: dict[str, Any] = {}
21
+ META: ClassVar[dict[str, Any]] = {}
22
22
 
23
23
  def __init__(self) -> None: # noqa: D107
24
24
  _ = translations._
@@ -81,9 +81,7 @@ class Model(metaclass=ABCMeta):
81
81
  if "Dyn" in f_type.field_type:
82
82
  dyn_data = data_dynamic_fields[f_name]
83
83
  if dyn_data is not None:
84
- f_type.choices = [
85
- [item["value"], item["title"][lang]] for item in dyn_data
86
- ]
84
+ f_type.choices = [[item["value"], item["title"][lang]] for item in dyn_data]
87
85
  else:
88
86
  # This is necessary for
89
87
  # `paladins > refrash > RefrashMixin > refrash_from_db`.
@@ -2,14 +2,15 @@
2
2
 
3
3
  __all__ = ("AddValidMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
  from xloft import NamedTuple
8
8
 
9
9
 
10
- class AddValidMixin(metaclass=ABCMeta):
10
+ class AddValidMixin:
11
11
  """Contains an abstract method for additional validation of fields."""
12
12
 
13
+ @abstractmethod
13
14
  async def add_validation(self) -> NamedTuple:
14
15
  """Additional validation of fields."""
15
16
  return NamedTuple()
@@ -168,8 +168,8 @@ class CheckMixin(
168
168
  if img_data is not None:
169
169
  img_data["is_new_img"] = False
170
170
  #
171
- return dict(
172
- data=result_map,
173
- is_valid=not params["is_error_symptom"],
174
- is_update=is_update,
175
- )
171
+ return {
172
+ "data": result_map,
173
+ "is_valid": not params["is_error_symptom"],
174
+ "is_update": is_update,
175
+ }
@@ -66,7 +66,7 @@ class SlugGroupMixin:
66
66
  err_msg = (
67
67
  f"Model: `{params['full_model_name']}` > "
68
68
  + f"Field: `{field_name}` > "
69
- + f"Parameter: `slug_sources` => "
69
+ + "Parameter: `slug_sources` => "
70
70
  + "At least one field should be unique!"
71
71
  )
72
72
  logger.critical(err_msg)
@@ -102,11 +102,11 @@ class TextGroupMixin:
102
102
  # Insert result.
103
103
  if params["is_save"]:
104
104
  if is_multi_language:
105
- mult_lang_text: dict[str, str] = (
105
+ mult_lang_text = (
106
106
  params["curr_doc"][field_name]
107
107
  if params["is_update"]
108
108
  else (
109
- {lang: value for lang in translations.LANGUAGES}
109
+ dict.fromkeys(translations.LANGUAGES)
110
110
  if isinstance(value, str)
111
111
  else {lang: value.get(lang, "- -") for lang in translations.LANGUAGES}
112
112
  )
@@ -2,26 +2,32 @@
2
2
 
3
3
  __all__ = ("HooksMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
 
8
- class HooksMixin(metaclass=ABCMeta):
8
+ class HooksMixin:
9
9
  """A set of abstract methods for creating hooks."""
10
10
 
11
+ @abstractmethod
11
12
  async def pre_create(self) -> None:
12
13
  """Called before a new document is created in the database."""
13
14
 
15
+ @abstractmethod
14
16
  async def post_create(self) -> None:
15
17
  """Called after a new document has been created in the database."""
16
18
 
19
+ @abstractmethod
17
20
  async def pre_update(self) -> None:
18
21
  """Called before updating an existing document in the database."""
19
22
 
23
+ @abstractmethod
20
24
  async def post_update(self) -> None:
21
25
  """Called after an existing document in the database is updated."""
22
26
 
27
+ @abstractmethod
23
28
  async def pre_delete(self) -> None:
24
29
  """Called before deleting an existing document in the database."""
25
30
 
31
+ @abstractmethod
26
32
  async def post_delete(self) -> None:
27
33
  """Called after an existing document in the database has been deleted."""
@@ -2,12 +2,13 @@
2
2
 
3
3
  __all__ = ("IndexMixin",)
4
4
 
5
- from abc import ABCMeta
5
+ from abc import abstractmethod
6
6
 
7
7
 
8
- class IndexMixin(metaclass=ABCMeta):
8
+ class IndexMixin:
9
9
  """Contains the method for indexing the model in the database."""
10
10
 
11
11
  @classmethod
12
+ @abstractmethod
12
13
  async def indexing(cls) -> None:
13
14
  """Set up and start indexing."""
ramifice/paladins/save.py CHANGED
@@ -46,7 +46,7 @@ class SaveMixin:
46
46
  # Create or update a document in database.
47
47
  if result_check["is_update"]:
48
48
  # Update date and time.
49
- checked_data["updated_at"] = datetime.now()
49
+ checked_data["updated_at"] = datetime.now() # noqa: DTZ005
50
50
  # Run hook.
51
51
  await self.pre_update()
52
52
  # Update doc.
@@ -68,7 +68,7 @@ class SaveMixin:
68
68
  refresh_from_mongo_doc(self, mongo_doc)
69
69
  else:
70
70
  # Add date and time.
71
- today = datetime.now()
71
+ today = datetime.now() # noqa: DTZ005
72
72
  checked_data["created_at"] = today
73
73
  checked_data["updated_at"] = today
74
74
  # Run hook.
@@ -31,19 +31,19 @@ class ValidationMixin:
31
31
  if len(field_data.errors) > 0:
32
32
  # title
33
33
  if not is_err:
34
- print(colored("\nERRORS:", "red", attrs=["bold"]))
35
- print(colored("Model: ", "blue", attrs=["bold"]), end="")
36
- print(colored(f"`{self.full_model_name()}`", "blue"))
34
+ print(colored("\nERRORS:", "red", attrs=["bold"])) # noqa: T201
35
+ print(colored("Model: ", "blue", attrs=["bold"]), end="") # noqa: T201
36
+ print(colored(f"`{self.full_model_name()}`", "blue")) # noqa: T201
37
37
  is_err = True
38
38
  # field name
39
- print(colored("Field: ", "green", attrs=["bold"]), end="")
40
- print(colored(f"`{field_name}`:", "green"))
39
+ print(colored("Field: ", "green", attrs=["bold"]), end="") # noqa: T201
40
+ print(colored(f"`{field_name}`:", "green")) # noqa: T201
41
41
  # error messages
42
- print(colored("\n".join(field_data.errors), "red"))
42
+ print(colored("\n".join(field_data.errors), "red")) # noqa: T201
43
43
  if len(self._id.alerts) > 0:
44
44
  # title
45
- print(colored("AlERTS:", "yellow", attrs=["bold"]))
45
+ print(colored("AlERTS:", "yellow", attrs=["bold"])) # noqa: T201
46
46
  # messages
47
- print(colored("\n".join(self._id.alerts), "yellow"), end="\n\n")
47
+ print(colored("\n".join(self._id.alerts), "yellow"), end="\n\n") # noqa: T201
48
48
  else:
49
- print(end="\n\n")
49
+ print(end="\n\n") # noqa: T201
@@ -64,7 +64,7 @@ REGEX: dict[str, re.Pattern] = {
64
64
  "model_name": re.compile(r"^[A-Z][a-zA-Z0-9]{0,24}$"),
65
65
  "color_code": re.compile(
66
66
  r"^(?:#|0x)(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|hsl)a?\([^\)]*\)$",
67
- re.I,
67
+ re.I, # noqa: FURB167
68
68
  ),
69
69
  "password": re.compile(r'^[-._!"`\'#%&,:;<>=@{}~\$\(\)\*\+\/\\\?\[\]\^\|a-zA-Z0-9]{8,256}$'),
70
70
  }
@@ -71,8 +71,8 @@ async def apply_fixture(
71
71
  # If the check fails.
72
72
  if not result_check["is_valid"]:
73
73
  await collection.database.drop_collection(collection.name)
74
- print(colored("\nFIXTURE:", "red", attrs=["bold"]))
75
- print(colored(fixture_path, "blue", attrs=["bold"]))
74
+ print(colored("\nFIXTURE:", "red", attrs=["bold"])) # noqa: T201
75
+ print(colored(fixture_path, "blue", attrs=["bold"])) # noqa: T201
76
76
  inst_model.print_err()
77
77
  msg = f"Fixture `{fixture_name}` failed."
78
78
  logger.critical(msg)
@@ -80,7 +80,7 @@ async def apply_fixture(
80
80
  # Get data for document.
81
81
  checked_data: dict[str, Any] = result_check["data"]
82
82
  # Add date and time.
83
- today = datetime.now()
83
+ today = datetime.now() # noqa: DTZ005
84
84
  checked_data["created_at"] = today
85
85
  checked_data["updated_at"] = today
86
86
  # Run hook.
@@ -172,7 +172,7 @@ class Migration:
172
172
  is_migration_process=True,
173
173
  )
174
174
  if not result_check["is_valid"]:
175
- print(colored("\n!!!>>MIGRATION<<!!!", "red", attrs=["bold"]))
175
+ print(colored("\n!!!>>MIGRATION<<!!!", "red", attrs=["bold"])) # noqa: T201
176
176
  inst_model.print_err()
177
177
  msg: str = "Migration failed."
178
178
  logger.critical(msg)
@@ -188,7 +188,7 @@ class Migration:
188
188
  ):
189
189
  checked_data[field_name] = mongo_doc[field_name]
190
190
  # Update date and time.
191
- checked_data["updated_at"] = datetime.now()
191
+ checked_data["updated_at"] = datetime.now() # noqa: DTZ005
192
192
  # Update the document in the database.
193
193
  await model_collection.replace_one(
194
194
  filter={"_id": checked_data["_id"]},
@@ -197,7 +197,7 @@ class Migration:
197
197
  #
198
198
  # Refresh the dynamic fields data for the current model.
199
199
  for field_name, field_data in metadata["data_dynamic_fields"].items():
200
- if model_state["data_dynamic_fields"].get(field_name, False) == False:
200
+ if model_state["data_dynamic_fields"].get(field_name, False) == False: # noqa: E712
201
201
  model_state["data_dynamic_fields"][field_name] = field_data
202
202
  else:
203
203
  metadata["data_dynamic_fields"][field_name] = model_state[
ramifice/utils/tools.py CHANGED
@@ -37,7 +37,7 @@ def is_password(password: str | None) -> bool:
37
37
 
38
38
  def to_human_size(size: int) -> str:
39
39
  """Convert number of bytes to readable format."""
40
- idx = int(math.floor(math.log(size) / math.log(1024)))
40
+ idx = int(math.floor(math.log(size) / math.log(1024))) # noqa: RUF046
41
41
  size = size if size < 1024 else abs(round(size / pow(1024, idx), 2))
42
42
  order = ["bytes", "KB", "MB", "GB", "TB"][idx]
43
43
  return f"{size} {order}"
@@ -57,7 +57,7 @@ def add_languages(
57
57
  ) -> None:
58
58
  """Add languages."""
59
59
  global DEFAULT_LOCALE, LANGUAGES
60
- if not default_locale in languages:
60
+ if default_locale not in languages:
61
61
  msg = "DEFAULT_LOCALE is not included in the LANGUAGES!"
62
62
  logger.critical(msg)
63
63
  raise PanicError(msg)
ramifice/utils/unit.py CHANGED
@@ -38,10 +38,10 @@ class Unit(JsonMixin):
38
38
  )
39
39
  raise PanicError(msg)
40
40
  if not isinstance(value, (float, int, str)):
41
- msg = "Class: `Unit` > Field: `value` => Not а `float | int | str` type!"
41
+ msg = "Class: `Unit` > Field: `value` => Not a `float | int | str` type!"
42
42
  raise PanicError(msg)
43
43
  if not isinstance(is_delete, bool):
44
- msg = "Class: `Unit` > Field: `is_delete` => Not а `bool` type!"
44
+ msg = "Class: `Unit` > Field: `is_delete` => Not a `bool` type!"
45
45
  raise PanicError(msg)
46
46
 
47
47
  JsonMixin.__init__(self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.8.26
3
+ Version: 0.8.27
4
4
  Summary: ORM-pseudo-like API MongoDB for Python language.
5
5
  Project-URL: Homepage, https://github.com/kebasyaty/ramifice
6
6
  Project-URL: Documentation, https://kebasyaty.github.io/ramifice/
@@ -5,7 +5,7 @@ ramifice/commons/general.py,sha256=ZryiRH-qf_cH9HCul7EP11UU-k4YO_rp_kku2FWAwj4,5
5
5
  ramifice/commons/indexes.py,sha256=dBPVYeJGbEyENLEzGjQmQ2XYOr3qqzjonj6zyH4rl54,3696
6
6
  ramifice/commons/many.py,sha256=D4sRNe9zrG_BD43vcEbnv81YthnzctZznbih6lBCnqM,9424
7
7
  ramifice/commons/one.py,sha256=htcrIjwKTegwvLoA9KHVChCLzdwVJW0LZXUGLBMFE64,6979
8
- ramifice/commons/tools.py,sha256=wBnJFibq3jW09vXywnP3MFGWCb2iLxWeDfwWBKf2b7g,2461
8
+ ramifice/commons/tools.py,sha256=o0o-0W7VDAMPiEOWF9Du7W7py94fCLFx8KJc7LM6HP4,2423
9
9
  ramifice/commons/unit_manager.py,sha256=hDHmn3u0NDeIXxh0iCvaxN_stxtCAJVie-cWAZ6TK88,4968
10
10
  ramifice/fields/__init__.py,sha256=hjqCZG_kKsHdHtSd05vHn9SiFpk-YSvKEsVFaXim5Sw,2360
11
11
  ramifice/fields/bool_field.py,sha256=d3sKQWMAfEycgtBIhIIov2XVoqLbN8th8i3H7YLrNdg,2769
@@ -24,39 +24,39 @@ ramifice/fields/choice_text_mult_field.py,sha256=gw5vWxooWBp0-RbFNTs74_n7Ib_nS2h
24
24
  ramifice/fields/color_field.py,sha256=-ju_cJBzKSmcXsFQweePqNmF8VeIyaRJLwvl_ypOuVk,4505
25
25
  ramifice/fields/date_field.py,sha256=pmn627RGLojnprr3KAEYWvaF8IZm3YsWFZHBR8CCuYQ,6315
26
26
  ramifice/fields/date_time_field.py,sha256=AVtxkvs6MP6GnSQ5chImWETnJ57LEHJinTj05Xg1xiE,6372
27
- ramifice/fields/email_field.py,sha256=zW908yFZH7mY98GrvsBvE1gwvRL_yP44yh_WJE9pKWU,4431
28
- ramifice/fields/file_field.py,sha256=Hjv1R3DYO-BaBJIBcwZVLvGsdCsBHydy3rd1bljFxcA,9478
27
+ ramifice/fields/email_field.py,sha256=Z1FNIVy6NFcgxYXxsioUfU_kipbMp6iXdxS97woBooU,4445
28
+ ramifice/fields/file_field.py,sha256=dAsOYXPjMNwC_t8jCyoNEwlRAsGEd9V_tiuix0qTukU,9476
29
29
  ramifice/fields/float_field.py,sha256=ePOO0GBjDFlWjieRItpVKkUbKeuAagBCeDNvvFCVEJs,5859
30
30
  ramifice/fields/id_field.py,sha256=36VroZIgCH6uKuYjjWTXIycZ06ZGy4reLX6FhMUphCI,4757
31
- ramifice/fields/image_field.py,sha256=wfBi4M0J6JAU4dTSmtOR0L3LUyf5L6QiDY8XK1TuOUg,13046
31
+ ramifice/fields/image_field.py,sha256=jeHzsQtPJObDkKWUfyGagXn3_vKBaG4YXuJyqRYD1Mc,12854
32
32
  ramifice/fields/integer_field.py,sha256=p6dkzuTDjuBdi4K43m9-qRQGOXz4zNIz0x2fD1tm-Mk,5833
33
- ramifice/fields/ip_field.py,sha256=ICf5hwGEnq5RiRiPKZZXm6WtdzEw4_TDLB7_1BYG-Vs,4335
33
+ ramifice/fields/ip_field.py,sha256=7s-pWIXVol2wWP6q8bEJiK_VyIzGZO17ZROK_GGbOrY,4349
34
34
  ramifice/fields/password_field.py,sha256=lKELnyIjlAIJWeCR_3BCa0ZL5R0L73cf9zimigIgN3g,3902
35
- ramifice/fields/phone_field.py,sha256=XIiJJGXXeOSjoB9n2qMmTH6vIB7pAgvh-CJakL_mX8A,4622
36
- ramifice/fields/slug_field.py,sha256=Vvuug6TYOxmOaoDeqaFgu6MlMmaSgpXkS60juuGNvIE,3538
35
+ ramifice/fields/phone_field.py,sha256=9KwTd4lUHYsP2-XzWDnC0ri5reU7imCf51Qqjv_TIqQ,4636
36
+ ramifice/fields/slug_field.py,sha256=wJtyf5LWP5pxw6G91_sYSs02QY7kvLYyB1_99_6gz5o,3552
37
37
  ramifice/fields/text_field.py,sha256=fBVxBzHwj7R0TiSXnidqA5XHJdEz16WShT6TGjC-B6g,5299
38
38
  ramifice/fields/url_field.py,sha256=O0IG1NKljTCN8AXll0vAQgPE5dXHJPbxrkytI6zG3i0,4348
39
39
  ramifice/fields/general/__init__.py,sha256=JzgIDseNQLB_IDwY9-JSiT_bONxvhJmbKl5PhQzTnpE,40
40
- ramifice/fields/general/choice_group.py,sha256=RkYEuEl6wSazqhq2aDhUoKzKTEd54BgItpRy69rH93o,928
41
- ramifice/fields/general/date_group.py,sha256=9fgLgyKhfVEwlCcQ87uRInmvWhwMoyfB5dT3Tq3wCPM,1229
42
- ramifice/fields/general/field.py,sha256=tBU-9l_w1LW1EVRvu0qJn1ySk5y3BzzaUSeStIbMEg4,1392
43
- ramifice/fields/general/file_group.py,sha256=97JqyUCKYGtvQfNOuUjOa5SIMuQ4V6I-rpmM5UDmS1E,1032
44
- ramifice/fields/general/number_group.py,sha256=6Canht6VXXzp2lF-6R7uoWXbPufrjceYP74btOyzmzA,785
45
- ramifice/fields/general/text_group.py,sha256=ofWj1d-9pKkbxARpXa2xQ6ANY3fiLtJUaFPp0vsDiT4,1123
40
+ ramifice/fields/general/choice_group.py,sha256=fdxfUEKavnW3SahtmyXNDsIJ1O67wCqZb0g-qnNc9cc,896
41
+ ramifice/fields/general/date_group.py,sha256=0Y4njV6AboQKCpSpjNRWiO8iJF4EdnVWOvmRz_M_7MY,1185
42
+ ramifice/fields/general/field.py,sha256=8P_k66rSGpY9qfiyRvRcH4VcqmzCy6fphr_BLrf-2N0,1360
43
+ ramifice/fields/general/file_group.py,sha256=HjCww3B6eS9gUmr6AGZTXhHVhS_VBvn0XpbrViWA8a8,986
44
+ ramifice/fields/general/number_group.py,sha256=QvJnnpvWvU5J-99mWk7h-00hW7busClv1eSR_DPll4A,753
45
+ ramifice/fields/general/text_group.py,sha256=y5j_7I-TzOpr6vJpbEFHN1JRc6s0wa6BVSqnHMMmX-4,1077
46
46
  ramifice/models/__init__.py,sha256=I4p5Y_oHG9ZLZ3vR44PpCGGvB-C2W7fSQPb5qJsm-VQ,178
47
- ramifice/models/decorator.py,sha256=uIjJ3uww0Ac7ufFn4VMqlA_8eP1I6oIhz5gRnDnH2w8,6396
48
- ramifice/models/model.py,sha256=qH21L7sDmJxbMz5UygHPCJhWgL52snFV_BRN-GchV00,7711
47
+ ramifice/models/decorator.py,sha256=2asTgb2rG4lfTciJhrfOI11kk-2wiScLBIbMy9Er3B4,6366
48
+ ramifice/models/model.py,sha256=kexnWtfmQaiGZU2qKeAhuHLxmuIFFe-xHwCULzLs9bc,7639
49
49
  ramifice/paladins/__init__.py,sha256=bFr12UzadCCpuIkGSd6reeIeQ5td8W7LfckduP84WXc,1517
50
- ramifice/paladins/add_valid.py,sha256=NbRDEjetY0Pp3qoLzM5QUYI8ydkiXav_iOnqJUIwcRw,430
51
- ramifice/paladins/check.py,sha256=UHGlyZqZVq200Iv7BpRphf8LfREzV3X5EkdoqSuDqsg,6935
50
+ ramifice/paladins/add_valid.py,sha256=c-vIkbbIBC94T4czxkQC40uwNEe6w8wQgNVgu4cjeoY,439
51
+ ramifice/paladins/check.py,sha256=Gdfqb6pvcRwbcJNPXlG15aIZfpWNZJlpA4Yomf8at1c,6940
52
52
  ramifice/paladins/delete.py,sha256=k3N2qlaHZLWtFUTqWvtkYaqW9h3uK7ecpLjKr5gfoGE,3690
53
- ramifice/paladins/hooks.py,sha256=oZXO2v9zsEzpf2w3L04YjigGKyk6c8PzCWBneqGi2CQ,943
54
- ramifice/paladins/indexing.py,sha256=pQGKZFmYougPJwZRVqDINvcEQEcYsTCjAsNMMhmwrsU,354
53
+ ramifice/paladins/hooks.py,sha256=jTOcz5eb3WUpIy21h-CcnsISDDsTgDCWjitszcFxZFE,1057
54
+ ramifice/paladins/indexing.py,sha256=ep6iSUhnH70eaNASr0Kx3yeuRE_i9BEdVUUiJBo4hZE,363
55
55
  ramifice/paladins/password.py,sha256=7lZmsl-bBely5zlVz0aCYlC5yf8nHp1YswoFF4CZWBI,3297
56
56
  ramifice/paladins/refrash.py,sha256=oS-N1QVwQGwt5lSxS01bpM6ETGuMLV_RFt1u5v2uEds,1221
57
- ramifice/paladins/save.py,sha256=Ylmf20iZU9IwR0kE9zNlJVUXxjb9BckP9ifwRqCTJAg,3715
57
+ ramifice/paladins/save.py,sha256=f91g24hDaifTtZVDCaixWYTAdUj0MTGv10hqT8FNUaE,3747
58
58
  ramifice/paladins/tools.py,sha256=8rkWPGrVMJiYN97EZuX52nVFVfB6qa08avYT4v8ohLA,2918
59
- ramifice/paladins/validation.py,sha256=3x8WUR0bTDkzJj41mEZyKc6brEmNukKpy0fc0NsniwQ,1764
59
+ ramifice/paladins/validation.py,sha256=vJ55g4al-V_aGxFSrnXDwAxjJXWv00Z8ZGexFipRD1c,1890
60
60
  ramifice/paladins/groups/__init__.py,sha256=GdIBJaMKz7L8pBKMAA__a4m-p0g0_RlzCcvDLDMMiec,958
61
61
  ramifice/paladins/groups/bool_group.py,sha256=X8P4YDh02gNzxTo9rgeCnmnV88jApUPqPLYIkpf5vGg,841
62
62
  ramifice/paladins/groups/choice_group.py,sha256=NkD2sKqBkdUMHY36pFdvL4uQ-81LXByRHF_lhCEAI6Y,1848
@@ -66,18 +66,18 @@ ramifice/paladins/groups/id_group.py,sha256=9iurBTOuhG1_8Wmxc5piTMcUNxAW3H0ZavA1
66
66
  ramifice/paladins/groups/img_group.py,sha256=yH1cNAZbRnc5l67HCsjLNf2cR0L4LGasuBMOhCOP4GA,6171
67
67
  ramifice/paladins/groups/num_group.py,sha256=UtpmYELsNyooiOEIAhSaRuTxYr_FrNpqq9KqAflX2aU,2349
68
68
  ramifice/paladins/groups/pass_group.py,sha256=54kvAyoUCEjujTw0Dh6oUrtv3RU80sWEem_b-3Ytv0k,1920
69
- ramifice/paladins/groups/slug_group.py,sha256=aakQpNoAcEFppRczlZgnP4-u9_7-Mb0RAWKhSGmo0Ig,2506
70
- ramifice/paladins/groups/text_group.py,sha256=PzFuRaHQzfsboGOOGKsxuqazN6We5u9TudB0-k1v0Ow,4505
69
+ ramifice/paladins/groups/slug_group.py,sha256=sf-9CebDLoCDsaxyPVJKMhi6D_tWFeg3ET8Qk5E8pU8,2505
70
+ ramifice/paladins/groups/text_group.py,sha256=TWvUxFctwDtXSJQL_E4TvHX1Yh-cDx5MJLGLAJyC6Xc,4478
71
71
  ramifice/utils/__init__.py,sha256=lAD90nw2VfGSuf0SLjOkeFScBPmc48XFvecueAfq73w,468
72
- ramifice/utils/constants.py,sha256=Wu_MyXvPpNonBbdgCmETLvMsZavyNXQ1IW9RXS9CMTA,2613
72
+ ramifice/utils/constants.py,sha256=zDVG2D8u0UMNl1Ik90PhZCdxjmK81uwqxosorersbXE,2630
73
73
  ramifice/utils/errors.py,sha256=eEV7-aVR0U19vKqTd9JRHFJXcOv6N1HtXSzqeQpdciE,2796
74
- ramifice/utils/fixtures.py,sha256=n_EZ53uf4wKU1Erk9u58v0C1o5oqtBtnVe7JOJtH_VA,3335
75
- ramifice/utils/migration.py,sha256=Oo0Zjvje8YOR1szTUL5dn6trnb5oU41u6aveDNmpIvI,11460
74
+ ramifice/utils/fixtures.py,sha256=8DqsTyX1yLIk04bYrKJHGojTc7974sEhQnsc6XVXe9M,3379
75
+ ramifice/utils/migration.py,sha256=0XMdHl1K0Akt5RxsRB_aUzN4VvN2t2yu3O-jSpFh79A,11504
76
76
  ramifice/utils/mixins.py,sha256=XSkxJllqsMxN7xcP_9kn3-GRS4a1l_QQpFOlD3e-tIM,1123
77
- ramifice/utils/tools.py,sha256=EPFINdgAJgewwQ9OErLEX8_z-_soQckyX7FsA7eRvyQ,3147
78
- ramifice/utils/translations.py,sha256=XlMcTRnDDxABxkBbFQY6Lg96IDuYoJUVSvPPWdeZNe8,4646
79
- ramifice/utils/unit.py,sha256=7alJuqY6vmYVZtumND6yMSJQDgarqMdRHXTyC6ULh4M,2550
80
- ramifice-0.8.26.dist-info/METADATA,sha256=O1WjnKMIkWsj1rch2lKpUIcfgnLnF_MoBafyW2-4Yq8,21081
81
- ramifice-0.8.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
82
- ramifice-0.8.26.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
83
- ramifice-0.8.26.dist-info/RECORD,,
77
+ ramifice/utils/tools.py,sha256=EKNJAV9Ch17IrmghLcu7-I69gDNkDSqPepG9GKU7WkA,3163
78
+ ramifice/utils/translations.py,sha256=EWITTDd4uXukRubOchqGwNjmZWt5HxoxRgq_kKeGsR8,4646
79
+ ramifice/utils/unit.py,sha256=Z32YjftbhNiuZTAQaM9-2ILxkfYcNz4nQ-1MFr8Jjek,2548
80
+ ramifice-0.8.27.dist-info/METADATA,sha256=ZVCIlIENRsAwjiVxjKUarX6apkD2gmTATwXy8h64A2c,21081
81
+ ramifice-0.8.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
82
+ ramifice-0.8.27.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
83
+ ramifice-0.8.27.dist-info/RECORD,,