ramifice 0.5.2__py3-none-any.whl → 0.5.4__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.
@@ -34,59 +34,64 @@ class UnitMixin:
34
34
  # Check the presence of a Model state.
35
35
  if model_state is None:
36
36
  raise PanicError("Error: Model State - Not found!")
37
- # Get dynamic field data.
38
- choices: list | None = model_state["data_dynamic_fields"][unit.field]
39
- # Get Title.
37
+ # Get clean fields of Unit.
38
+ unit_field: str = unit.field
40
39
  title = unit.title
41
40
  title = {lang: title.get(lang, "- -") for lang in translations.LANGUAGES}
42
- main_lang = translations.DEFAULT_LOCALE
43
- main_title = title[main_lang]
41
+ target_value = unit.value
42
+ # Get dynamic field data.
43
+ choices: list | None = model_state["data_dynamic_fields"][unit_field]
44
+ # Determine the presence of unit.
45
+ is_unit_exists: bool = False
46
+ if choices is not None:
47
+ for item in choices:
48
+ if item["value"] == target_value:
49
+ is_unit_exists = True
50
+ break
44
51
  # Add Unit to Model State.
45
52
  if not unit.is_delete:
46
53
  if choices is not None:
47
- choices.append({"title": title, "value": unit.value})
54
+ if is_unit_exists:
55
+ main_lang = translations.DEFAULT_LOCALE
56
+ msg = (
57
+ "Error: It is impossible to add unit - "
58
+ + f"Unit `{title[main_lang]}: {target_value}` is exists!"
59
+ )
60
+ raise PanicError(msg)
61
+ choices.append({"title": title, "value": target_value})
48
62
  else:
49
- choices = [{"title": title, "value": unit.value}]
50
- model_state["data_dynamic_fields"][unit.field] = choices
63
+ choices = [{"title": title, "value": target_value}]
64
+ model_state["data_dynamic_fields"][unit_field] = choices
51
65
  else:
52
66
  # Delete Unit from Model State.
53
67
  if choices is None:
54
- msg = (
55
- "Error: It is not possible to delete Unit."
56
- + f"Title `{main_title}` not exists!"
57
- )
68
+ msg = "Error: It is not possible to delete Unit - Units is not exists!"
58
69
  raise PanicError(msg)
59
- is_key_exists: bool = False
60
- for item in choices:
61
- if main_title == item["title"][main_lang]:
62
- is_key_exists = True
63
- break
64
- if not is_key_exists:
70
+ if not is_unit_exists:
71
+ main_lang = translations.DEFAULT_LOCALE
65
72
  msg = (
66
73
  "Error: It is not possible to delete Unit."
67
- + f"Title `{main_title}` not exists!"
74
+ + f"Unit `{title[main_lang]}: {target_value}` is not exists!"
68
75
  )
69
76
  raise PanicError(msg)
70
- choices = [item for item in choices if item["title"][main_lang] != main_title]
71
- model_state["data_dynamic_fields"][unit.field] = choices or None
77
+ choices = [item for item in choices if item["value"] != target_value]
78
+ model_state["data_dynamic_fields"][unit_field] = choices or None
72
79
  # Update state of current Model in super collection.
73
80
  await super_collection.replace_one(
74
81
  filter={"collection_name": model_state["collection_name"]},
75
82
  replacement=model_state,
76
83
  )
77
84
  # Update metadata of current Model.
78
- cls.META["data_dynamic_fields"][unit.field] = choices or None
85
+ cls.META["data_dynamic_fields"][unit_field] = choices or None
79
86
  # Update documents in the collection of the current Model.
80
87
  if unit.is_delete:
81
- unit_field: str = unit.field
82
- unit_value: float | int | str | None = unit.value
83
88
  collection: AsyncCollection = globals.MONGO_DATABASE[cls.META["collection_name"]]
84
89
  async for mongo_doc in collection.find():
85
90
  field_value = mongo_doc[unit_field]
86
91
  if field_value is not None:
87
- if isinstance(unit_value, list):
92
+ if isinstance(field_value, list):
88
93
  value_list = mongo_doc[unit_field]
89
- value_list.remove(unit_value)
94
+ value_list.remove(target_value)
90
95
  mongo_doc[unit_field] = value_list or None
91
96
  else:
92
97
  mongo_doc[unit_field] = None
@@ -189,7 +189,7 @@ class Monitor:
189
189
  "data_dynamic_fields"
190
190
  ][field_name]
191
191
  # Refresh state of current Model.
192
- model_state["data_dynamic_field"] = metadata["data_dynamic_fields"]
192
+ model_state["data_dynamic_fields"] = metadata["data_dynamic_fields"]
193
193
  model_state["field_name_and_type"] = metadata["field_name_and_type"]
194
194
  await super_collection.replace_one(
195
195
  filter={"collection_name": model_state["collection_name"]},
ramifice/utils/unit.py CHANGED
@@ -20,7 +20,7 @@ class Unit(JsonMixin):
20
20
  self,
21
21
  field: str,
22
22
  title: dict[str, str], # Example: {"en": "Title", "ru": "Заголовок"}
23
- value: float | int | str | None = None, # None for is_delete=True
23
+ value: float | int | str,
24
24
  is_delete: bool = False,
25
25
  ):
26
26
  # Check the match of types.
@@ -33,8 +33,8 @@ class Unit(JsonMixin):
33
33
  + 'Example: {"en": "Title", "ru": "Заголовок"}'
34
34
  )
35
35
  raise PanicError(msg)
36
- if not isinstance(value, (float, int, str, type(None))):
37
- msg = "Class: `Unit` > Field: `value` => Not а `float | int | str | None` type!"
36
+ if not isinstance(value, (float, int, str)):
37
+ msg = "Class: `Unit` > Field: `value` => Not а `float | int | str` type!"
38
38
  raise PanicError(msg)
39
39
  if not isinstance(is_delete, bool):
40
40
  msg = "Class: `Unit` > Field: `is_delete` => Not а `bool` type!"
@@ -47,10 +47,10 @@ class Unit(JsonMixin):
47
47
  self.value = value
48
48
  self.is_delete = is_delete
49
49
 
50
- self.check_value_arguments()
50
+ self.check_empty_arguments()
51
51
 
52
- def check_value_arguments(self) -> None:
53
- """Check if the values correspond to the arguments.
52
+ def check_empty_arguments(self) -> None:
53
+ """Check the arguments for empty values.
54
54
 
55
55
  Returns:
56
56
  `None` or raised exception `PanicError`.
@@ -61,14 +61,6 @@ class Unit(JsonMixin):
61
61
  field_name = "field"
62
62
  elif len(self.title) == 0:
63
63
  field_name = "title"
64
- elif self.value is None and self.is_delete == False:
65
- msg = (
66
- "Method: `unit_manager` > "
67
- + "Argument: `unit` > "
68
- + f"Field: `{field_name}` => "
69
- + "For `value` = None, `is_delete` should be True!"
70
- )
71
- raise PanicError(msg)
72
64
  elif isinstance(self.value, str) and len(self.value) == 0:
73
65
  field_name = "value"
74
66
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.5.2
3
+ Version: 0.5.4
4
4
  Summary: ORM-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/
@@ -175,7 +175,7 @@ class User:
175
175
  # Hint: By default = 2 MB
176
176
  max_size=524288, # 512 KB = 0.5 MB = 524288 Bytes (in binary)
177
177
  warning=[
178
- gettext("Maximum size: %s" % to_human_size(524288)),
178
+ gettext("Maximum size: %s") % to_human_size(524288),
179
179
  ],
180
180
  )
181
181
  self.username = TextField(
@@ -185,7 +185,7 @@ class User:
185
185
  required=True,
186
186
  unique=True,
187
187
  warning=[
188
- gettext("Allowed chars: %s" % "a-z A-Z 0-9 _"),
188
+ gettext("Allowed chars: %s") % "a-z A-Z 0-9 _",
189
189
  ],
190
190
  )
191
191
  self.first_name = TextField(
@@ -272,7 +272,7 @@ class User:
272
272
  сonfirm_password = self.сonfirm_password.value
273
273
 
274
274
  if re.match(r"^[a-zA-Z0-9_]+$", username) is None: # type: ignore[arg-type]
275
- error_map["username"] = gettext("Allowed chars: %s" % "a-z A-Z 0-9 _")
275
+ error_map["username"] = gettext("Allowed chars: %s") % "a-z A-Z 0-9 _"
276
276
 
277
277
  if id is None and (password != сonfirm_password):
278
278
  error_map["password"] = gettext("Passwords do not match!")
@@ -342,60 +342,9 @@ if __name__ == "__main__":
342
342
  asyncio.run(main())
343
343
  ```
344
344
 
345
- ### How to create custom translations ?
345
+ ### How to add localization?
346
346
 
347
- ```python
348
- from ramifice import translations
349
-
350
- translations.DEFAULT_LOCALE = "en" # For Ramifice by default = "en"
351
- translations.LANGUAGES = ["en", "ru"] # For Ramifice by default = ["en", "ru"]
352
- ```
353
-
354
- ```shell
355
- cd project_name
356
- # Add your custom translations:
357
- uv run pybabel extract -o config/translations/custom.pot src
358
- uv run pybabel init -i config/translations/custom.pot -d config/translations/custom -l en
359
- uv run pybabel init -i config/translations/custom.pot -d config/translations/custom -l ru
360
- ...
361
-
362
- # Hint: Do not forget to add translations for new languages.
363
- uv run pybabel compile -d config/translations/custom
364
-
365
- # Update your custom translations:
366
- uv run pybabel extract -o config/translations/custom.pot src
367
- uv run pybabel update -i config/translations/custom.pot -d config/translations/custom
368
- # Hint: Do not forget to check the translations for existing languages.
369
- uv run pybabel compile -d config/translations/custom
370
- ```
371
-
372
- ### How to add new languages ​​to Ramifice ?
373
-
374
- ```python
375
- from ramifice import translations
376
-
377
- translations.DEFAULT_LOCALE = "en" # For Ramifice by default = "en"
378
- translations.LANGUAGES = ["en", "ru", "de", "de_ch"] # For Ramifice by default = ["en", "ru"]
379
- ```
380
-
381
- ```shell
382
- cd project_name
383
- # Example:
384
- uv run pybabel init -i config/translations/ramifice.pot -d config/translations/ramifice -l de
385
- uv run pybabel init -i config/translations/ramifice.pot -d config/translations/ramifice -l de_ch
386
- ...
387
-
388
- # Hint: Do not forget to add translations for new languages.
389
- uv run pybabel compile -d config/translations/ramifice
390
-
391
- # Update translations to Ramifice:
392
- uv run pybabel extract -o config/translations/ramifice.pot ramifice
393
- uv run pybabel update -i config/translations/ramifice.pot -d config/translations/ramifice
394
- # Hint: Do not forget to check the translations for existing languages.
395
- uv run pybabel compile -d config/translations/ramifice
396
- ```
397
-
398
- ### [See more examples here.](https://github.com/kebasyaty/ramifice/tree/v0/examples "See more examples here.")
347
+ [See in the examples.](https://github.com/kebasyaty/ramifice/tree/v0/examples "See in the examples.")
399
348
 
400
349
  ## Model Parameters
401
350
 
@@ -6,7 +6,7 @@ ramifice/commons/indexes.py,sha256=hAcWKZ9MMgLbRtoQ6Af0b8r-PY0dbEYmMBl8z_d1DRo,3
6
6
  ramifice/commons/many.py,sha256=jkah1kO1CXWPB0xW0dbMelCFBSirRYkX9a333EcPE_M,9202
7
7
  ramifice/commons/one.py,sha256=uZsgwg_GgA1VMZDPqhRFMmCdtvcv6xsL4DWbCOwGV3w,6730
8
8
  ramifice/commons/tools.py,sha256=ectaILVYCSwNbB0VAys6nIhdsJbwuxAupNvcQfweC88,2366
9
- ramifice/commons/unit_manager.py,sha256=o8Ux2y95nddo762hf1YDyp07QwvQyotR5iVoG5FZaZI,4001
9
+ ramifice/commons/unit_manager.py,sha256=sMoeANBW9OZUDijn3zg5wxt9TN9lF0qYgiHzljr9xyw,4303
10
10
  ramifice/fields/__init__.py,sha256=yRfX7Tvpuh27Ggcx5u9e1RRYK7Wu59EVJYxxetmuP1w,1290
11
11
  ramifice/fields/bool_field.py,sha256=WWubSwsFJZu8b3MviDd2zXnNYOQaYw8toklFNSTVFLA,2072
12
12
  ramifice/fields/choice_float_dyn_field.py,sha256=Yrd9cNKLm0mhU-P3IojwFRLSbuxdp7f2NMGJhrRWsf8,3093
@@ -70,16 +70,16 @@ ramifice/utils/__init__.py,sha256=xixHoOX4ja5jIUZemem1qn4k4aonv3G3Q76azQK_pkU,43
70
70
  ramifice/utils/errors.py,sha256=iuhq7fzpUmsOyeXeg2fJjta8yAuqlXLKsZVMpfUhtHE,1901
71
71
  ramifice/utils/fixtures.py,sha256=qsv9cg06lc82XaRlhI1j5vftmOQTTwOcDXCg_lnpK04,3159
72
72
  ramifice/utils/globals.py,sha256=uR20um3Qg_1SG1t7WyWbpq8kQD-9Mslyr_c1yh5Hw9w,1751
73
- ramifice/utils/migration.py,sha256=ol8ysNGBr0wuOwo00ZbbN0U8YKiiYVgyRYja0axdiHM,11059
73
+ ramifice/utils/migration.py,sha256=kx1JX0xSgebtNtoTm_161_MqBw5kpsqCfIsc8wXYc34,11060
74
74
  ramifice/utils/tools.py,sha256=sOKzwnvf6vdTNf9r6PKAdw6aB4undat2Z8tzS3M1GnQ,2733
75
75
  ramifice/utils/translations.py,sha256=GNGE0ULAA0aOY5pTxUd3MQW-nVaKvp6BeXWEcsR0s0o,4048
76
- ramifice/utils/unit.py,sha256=cFnhXt8sO0X-wiuiSU7_YzmRkpdNFcf2qxfR8YPsuiE,2861
76
+ ramifice/utils/unit.py,sha256=R34gxriT67vI6PmjMIRftNsSP036jwbnsYjxt1Wma48,2454
77
77
  ramifice/utils/mixins/__init__.py,sha256=-UxYokZSlEaqoIs0aPVGtzK2CgN88mTzyhryHEtt0Yo,181
78
78
  ramifice/utils/mixins/add_valid.py,sha256=TLOObedzXNA9eCylfAVbVCqIKE5sV-P5AdIN7avj-GA,407
79
79
  ramifice/utils/mixins/hooks.py,sha256=33jvJRhfnJeL2Hd_YFXk3M_7wjqHaByU2wRjKyboL6s,914
80
80
  ramifice/utils/mixins/indexing.py,sha256=Z0427HoaVRyNmSNN8Fx0mSICgAKV-gDdu3iR5qYUEbs,329
81
81
  ramifice/utils/mixins/json_converter.py,sha256=WhigXyDAV-FfILaZuwvRFRIk0D90Rv3dG5t-mv5fVyc,1107
82
- ramifice-0.5.2.dist-info/METADATA,sha256=8tjSGncIGRewQNVNLb6exe9yl52r92U5UFgXyl7wq1I,24388
83
- ramifice-0.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
- ramifice-0.5.2.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
- ramifice-0.5.2.dist-info/RECORD,,
82
+ ramifice-0.5.4.dist-info/METADATA,sha256=G7x9T9_WihchEvWZhdsdn7wsAoPaSXxNazI1ZoZASec,22500
83
+ ramifice-0.5.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
+ ramifice-0.5.4.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
+ ramifice-0.5.4.dist-info/RECORD,,