ramifice 0.3.24__py3-none-any.whl → 0.3.25__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/fields/color_field.py +0 -7
- ramifice/fields/email_field.py +0 -9
- ramifice/fields/ip_field.py +0 -9
- ramifice/fields/password_field.py +0 -7
- ramifice/fields/phone_field.py +0 -11
- ramifice/fields/url_field.py +0 -8
- ramifice/paladins/groups/pass_group.py +2 -1
- ramifice/paladins/groups/text_group.py +5 -4
- ramifice/utilities.py +17 -10
- {ramifice-0.3.24.dist-info → ramifice-0.3.25.dist-info}/METADATA +51 -2
- {ramifice-0.3.24.dist-info → ramifice-0.3.25.dist-info}/RECORD +13 -13
- {ramifice-0.3.24.dist-info → ramifice-0.3.25.dist-info}/WHEEL +0 -0
- {ramifice-0.3.24.dist-info → ramifice-0.3.25.dist-info}/licenses/LICENSE +0 -0
ramifice/fields/color_field.py
CHANGED
@@ -86,10 +86,3 @@ class ColorField(Field, TextGroup, JsonMixin):
|
|
86
86
|
JsonMixin.__init__(self)
|
87
87
|
|
88
88
|
self.default = default
|
89
|
-
|
90
|
-
def is_valid(self, value: str | None = None) -> bool:
|
91
|
-
"""Validate Color code."""
|
92
|
-
color_code = str(value or self.value or self.default)
|
93
|
-
if store.REGEX["color_code"].match(color_code) is None:
|
94
|
-
return False
|
95
|
-
return True
|
ramifice/fields/email_field.py
CHANGED
@@ -82,12 +82,3 @@ class EmailField(Field, TextGroup, JsonMixin):
|
|
82
82
|
JsonMixin.__init__(self)
|
83
83
|
|
84
84
|
self.default = default
|
85
|
-
|
86
|
-
def is_valid(self, value: str | None = None) -> bool:
|
87
|
-
"""Validate Email address."""
|
88
|
-
email = str(value or self.value or self.default)
|
89
|
-
try:
|
90
|
-
validate_email(email, check_deliverability=True)
|
91
|
-
except EmailNotValidError:
|
92
|
-
return False
|
93
|
-
return True
|
ramifice/fields/ip_field.py
CHANGED
@@ -82,12 +82,3 @@ class IPField(Field, TextGroup, JsonMixin):
|
|
82
82
|
JsonMixin.__init__(self)
|
83
83
|
|
84
84
|
self.default = default
|
85
|
-
|
86
|
-
def is_valid(self, value: str | None = None) -> bool:
|
87
|
-
"""Validate IP address."""
|
88
|
-
address = str(value or self.value or self.default)
|
89
|
-
try:
|
90
|
-
ipaddress.ip_address(address)
|
91
|
-
except ValueError:
|
92
|
-
return False
|
93
|
-
return True
|
@@ -61,13 +61,6 @@ class PasswordField(Field):
|
|
61
61
|
self.placeholder = placeholder
|
62
62
|
self.required = required
|
63
63
|
|
64
|
-
def is_valid(self, value: str | None = None) -> bool:
|
65
|
-
"""Validate Password."""
|
66
|
-
password = str(value or self.value)
|
67
|
-
if not store.REGEX["password"].match(password):
|
68
|
-
return False
|
69
|
-
return True
|
70
|
-
|
71
64
|
def to_dict(self) -> dict[str, Any]:
|
72
65
|
"""Convert object instance to a dictionary."""
|
73
66
|
json_dict: dict[str, Any] = {}
|
ramifice/fields/phone_field.py
CHANGED
@@ -87,14 +87,3 @@ class PhoneField(Field, TextGroup, JsonMixin):
|
|
87
87
|
JsonMixin.__init__(self)
|
88
88
|
|
89
89
|
self.default = default
|
90
|
-
|
91
|
-
def is_valid(self, value: str | None = None) -> bool:
|
92
|
-
"""Validate Phone number."""
|
93
|
-
number = str(value or self.value or self.default)
|
94
|
-
try:
|
95
|
-
phone = phonenumbers.parse(number)
|
96
|
-
if not phonenumbers.is_valid_number(phone):
|
97
|
-
return False
|
98
|
-
except phonenumbers.phonenumberutil.NumberParseException:
|
99
|
-
return False
|
100
|
-
return True
|
ramifice/fields/url_field.py
CHANGED
@@ -95,11 +95,3 @@ class URLField(Field, TextGroup, JsonMixin):
|
|
95
95
|
JsonMixin.__init__(self)
|
96
96
|
|
97
97
|
self.default = default
|
98
|
-
|
99
|
-
def is_valid(self, value: str | None = None) -> bool:
|
100
|
-
"""Validate URL address."""
|
101
|
-
url = str(value or self.value or self.default)
|
102
|
-
result = urlparse(url)
|
103
|
-
if not result.scheme or not result.netloc:
|
104
|
-
return False
|
105
|
-
return True
|
@@ -8,6 +8,7 @@ from typing import Any
|
|
8
8
|
from argon2 import PasswordHasher
|
9
9
|
|
10
10
|
from ... import translations
|
11
|
+
from ...utilities import is_password
|
11
12
|
from ..tools import accumulate_error, panic_type_error
|
12
13
|
|
13
14
|
|
@@ -38,7 +39,7 @@ class PassGroupMixin:
|
|
38
39
|
params["result_map"][field.name] = None
|
39
40
|
return
|
40
41
|
# Validation Passwor.
|
41
|
-
if not
|
42
|
+
if not is_password(value):
|
42
43
|
err_msg = translations._("Invalid Password !")
|
43
44
|
accumulate_error(err_msg, params)
|
44
45
|
chars = "a-z A-Z 0-9 - . _ ! \" ` ' # % & , : ; < > = @ { } ~ $ ( ) * + / \\ ? [ ] ^ |"
|
@@ -10,6 +10,7 @@ from typing import Any
|
|
10
10
|
from email_validator import EmailNotValidError, validate_email
|
11
11
|
|
12
12
|
from ... import translations
|
13
|
+
from ...utilities import is_color, is_ip, is_phone, is_url
|
13
14
|
from ..tools import accumulate_error, check_uniqueness, panic_type_error
|
14
15
|
|
15
16
|
|
@@ -59,16 +60,16 @@ class TextGroupMixin:
|
|
59
60
|
except EmailNotValidError:
|
60
61
|
err_msg = translations._("Invalid Email address !")
|
61
62
|
accumulate_error(err_msg, params)
|
62
|
-
elif "URL" in field_type and not
|
63
|
+
elif "URL" in field_type and not is_url(value):
|
63
64
|
err_msg = translations._("Invalid URL address !")
|
64
65
|
accumulate_error(err_msg, params)
|
65
|
-
elif "IP" in field_type and not
|
66
|
+
elif "IP" in field_type and not is_ip(value):
|
66
67
|
err_msg = translations._("Invalid IP address !")
|
67
68
|
accumulate_error(err_msg, params)
|
68
|
-
elif "Color" in field_type and not
|
69
|
+
elif "Color" in field_type and not is_color(value):
|
69
70
|
err_msg = translations._("Invalid Color code !")
|
70
71
|
accumulate_error(err_msg, params)
|
71
|
-
elif "Phone" in field_type and not
|
72
|
+
elif "Phone" in field_type and not is_phone(value):
|
72
73
|
err_msg = translations._("Invalid Phone number !")
|
73
74
|
accumulate_error(err_msg, params)
|
74
75
|
# Insert result.
|
ramifice/utilities.py
CHANGED
@@ -13,6 +13,13 @@ from email_validator import EmailNotValidError, validate_email
|
|
13
13
|
from .store import REGEX
|
14
14
|
|
15
15
|
|
16
|
+
def is_password(password: str | None) -> bool:
|
17
|
+
"""Validate Password."""
|
18
|
+
if not REGEX["password"].match(str(password)):
|
19
|
+
return False
|
20
|
+
return True
|
21
|
+
|
22
|
+
|
16
23
|
def to_human_size(size: int) -> str:
|
17
24
|
"""Convert number of bytes to readable format."""
|
18
25
|
idx = int(math.floor(math.log(size) / math.log(1024)))
|
@@ -21,13 +28,13 @@ def to_human_size(size: int) -> str:
|
|
21
28
|
return f"{size} {order}"
|
22
29
|
|
23
30
|
|
24
|
-
def get_file_size(path: str) ->
|
31
|
+
def get_file_size(path: str) -> int:
|
25
32
|
"""Get human readable version of file size."""
|
26
|
-
size = os.path.getsize(path)
|
27
|
-
return
|
33
|
+
size: int = os.path.getsize(path)
|
34
|
+
return size
|
28
35
|
|
29
36
|
|
30
|
-
def normal_email(email: str) -> str | None:
|
37
|
+
def normal_email(email: str | None) -> str | None:
|
31
38
|
"""Normalizing email address."""
|
32
39
|
normal: str | None = None
|
33
40
|
try:
|
@@ -38,7 +45,7 @@ def normal_email(email: str) -> str | None:
|
|
38
45
|
return normal
|
39
46
|
|
40
47
|
|
41
|
-
def is_email(email: str) -> bool:
|
48
|
+
def is_email(email: str | None) -> bool:
|
42
49
|
"""Validate Email address."""
|
43
50
|
try:
|
44
51
|
validate_email(str(email), check_deliverability=True)
|
@@ -47,7 +54,7 @@ def is_email(email: str) -> bool:
|
|
47
54
|
return True
|
48
55
|
|
49
56
|
|
50
|
-
def is_url(url: str) -> bool:
|
57
|
+
def is_url(url: str | None) -> bool:
|
51
58
|
"""Validate URL address."""
|
52
59
|
result = urlparse(str(url))
|
53
60
|
if not result.scheme or not result.netloc:
|
@@ -55,7 +62,7 @@ def is_url(url: str) -> bool:
|
|
55
62
|
return True
|
56
63
|
|
57
64
|
|
58
|
-
def is_ip(address: str | int) -> bool:
|
65
|
+
def is_ip(address: str | int | None) -> bool:
|
59
66
|
"""Validate IP address."""
|
60
67
|
try:
|
61
68
|
ipaddress.ip_address(str(address))
|
@@ -64,14 +71,14 @@ def is_ip(address: str | int) -> bool:
|
|
64
71
|
return True
|
65
72
|
|
66
73
|
|
67
|
-
def is_color(color_code: str) -> bool:
|
74
|
+
def is_color(color_code: str | None) -> bool:
|
68
75
|
"""Validate Color code."""
|
69
76
|
if REGEX["color_code"].match(str(color_code)) is None:
|
70
77
|
return False
|
71
78
|
return True
|
72
79
|
|
73
80
|
|
74
|
-
def is_phone(number: str) -> bool:
|
81
|
+
def is_phone(number: str | None) -> bool:
|
75
82
|
"""Validate Phone number."""
|
76
83
|
try:
|
77
84
|
phone = phonenumbers.parse(str(number))
|
@@ -87,6 +94,6 @@ def is_mongo_id(oid: Any) -> bool:
|
|
87
94
|
return ObjectId.is_valid(oid)
|
88
95
|
|
89
96
|
|
90
|
-
def hash_to_obj_id(hash: str) -> ObjectId | None:
|
97
|
+
def hash_to_obj_id(hash: str | None) -> ObjectId | None:
|
91
98
|
"""Get ObjectId from hash string."""
|
92
99
|
return ObjectId(hash) if bool(hash) else None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ramifice
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.25
|
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/
|
@@ -144,7 +144,7 @@ class User:
|
|
144
144
|
def fields(self):
|
145
145
|
# For custom translations.
|
146
146
|
gettext = translations.gettext
|
147
|
-
|
147
|
+
ngettext = translations.ngettext
|
148
148
|
self.avatar = ImageField(
|
149
149
|
label=gettext("Avatar"),
|
150
150
|
default="public/media/default/no-photo.png",
|
@@ -519,6 +519,55 @@ await user.update_password( # uses verify_password
|
|
519
519
|
)
|
520
520
|
```
|
521
521
|
|
522
|
+
## General auxiliary methods
|
523
|
+
|
524
|
+
```python
|
525
|
+
from ramifice.utilities import (
|
526
|
+
get_file_size,
|
527
|
+
hash_to_obj_id,
|
528
|
+
is_color,
|
529
|
+
is_email,
|
530
|
+
is_ip,
|
531
|
+
is_mongo_id,
|
532
|
+
is_password,
|
533
|
+
is_phone,
|
534
|
+
is_url,
|
535
|
+
normal_email,
|
536
|
+
to_human_size,
|
537
|
+
)
|
538
|
+
|
539
|
+
if is_password("12345678"):
|
540
|
+
...
|
541
|
+
|
542
|
+
if is_email("kebasyaty@gmail.com"):
|
543
|
+
...
|
544
|
+
|
545
|
+
email = normal_email("kebasyaty@gmail.com") # + validate_email
|
546
|
+
|
547
|
+
if is_url("https://www.google.com"):
|
548
|
+
...
|
549
|
+
|
550
|
+
if is_ip("127.0.0.1"):
|
551
|
+
...
|
552
|
+
|
553
|
+
if is_color("#000"):
|
554
|
+
...
|
555
|
+
|
556
|
+
if is_phone("+447986123456"):
|
557
|
+
...
|
558
|
+
|
559
|
+
if is_mongo_id("666f6f2d6261722d71757578"):
|
560
|
+
...
|
561
|
+
|
562
|
+
from bson.objectid import ObjectId
|
563
|
+
_id: ObjectId | None = hash_to_obj_id("666f6f2d6261722d71757578")
|
564
|
+
|
565
|
+
size: str = to_human_size(2097152) # => 2.0 MB
|
566
|
+
|
567
|
+
path = "public/media/default/no_doc.odt"
|
568
|
+
size: int = get_file_size(path) # => 9843
|
569
|
+
```
|
570
|
+
|
522
571
|
## Contributing
|
523
572
|
|
524
573
|
1. Fork it (<https://github.com/kebasyaty/ramifice/fork>)
|
@@ -13,7 +13,7 @@ ramifice/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
ramifice/store.py,sha256=MpDEPvUvbs11FXjakNtHPm9MekIv5p1U3as2Y80lTyc,1860
|
14
14
|
ramifice/translations.py,sha256=GNGE0ULAA0aOY5pTxUd3MQW-nVaKvp6BeXWEcsR0s0o,4048
|
15
15
|
ramifice/types.py,sha256=ljo6VscUGWEJ4Km4JYo8GEfxd1YK1CUbS8CfHp_MlEA,2390
|
16
|
-
ramifice/utilities.py,sha256=
|
16
|
+
ramifice/utilities.py,sha256=2qfdSvqlL3rhT8-7MW83IoMjKQ0CZz0e24UTxMcOq90,2654
|
17
17
|
ramifice/commons/__init__.py,sha256=LHCsdpl4z8W-xUvAlOr1ad0ras9hspvCpuce4SAdfP0,472
|
18
18
|
ramifice/commons/general.py,sha256=fTnIRA3IGbi0lMKBCgeqkI7BGJWTbZVu0nOJYoNRSRU,4571
|
19
19
|
ramifice/commons/indexes.py,sha256=ABNRXeWZSreAE4_EDlsTN9aS8QiZbzhsatUJFn2EuOo,3849
|
@@ -35,21 +35,21 @@ ramifice/fields/choice_text_dyn_field.py,sha256=FyXeaTOfg3YfpgZ5TjXGGvFe2LasmbsM
|
|
35
35
|
ramifice/fields/choice_text_field.py,sha256=oy_yB_0cuWNM2CWZAC9ZMzkMtkyb7ViCvB3YcWJG41Y,3812
|
36
36
|
ramifice/fields/choice_text_mult_dyn_field.py,sha256=L-pmeIMa8Vh8O6G7f1TnmEI26dlyHbSOc2fPKN6tJoU,3043
|
37
37
|
ramifice/fields/choice_text_mult_field.py,sha256=1R1z7hzmdhhlEBoltxL67KwrId6WEapEuCxMI-O46_Q,4166
|
38
|
-
ramifice/fields/color_field.py,sha256=
|
38
|
+
ramifice/fields/color_field.py,sha256=zoqNw7o8VNE7qogd-7yV2Kh3SDb-u76FskpE2RTKHuQ,3494
|
39
39
|
ramifice/fields/date_field.py,sha256=Vlaxgp3WeDNMwbnQcTGu8kyQ7gc7M-7sFBPfzu-4MVw,5205
|
40
40
|
ramifice/fields/date_time_field.py,sha256=VpLeYJHs0df45fz4gnprtn7aipVFKGY4n02eRep7in0,5240
|
41
|
-
ramifice/fields/email_field.py,sha256=
|
41
|
+
ramifice/fields/email_field.py,sha256=NrP87ZpYsEFbI2jd4MiiLHi6MpE3uRr5XVm1GRwcWpM,3403
|
42
42
|
ramifice/fields/file_field.py,sha256=NMM9k-kVes7VarxvTQmsl2f2nvRKp-upjPHMDjNIrwY,7892
|
43
43
|
ramifice/fields/float_field.py,sha256=4l7gzg46qQ7ZbXS6Z8GUhiUBR26rXChvO_uFx-lbUds,4555
|
44
44
|
ramifice/fields/id_field.py,sha256=5wlY2j051TB2GPsw0iQkFiQBV_Y_o1W_QnCtBlaDuYQ,4126
|
45
45
|
ramifice/fields/image_field.py,sha256=u4YJ3vFtGj5uhVLjgrvV9gNLwLXT4jfVPUN2mlPKHfg,12269
|
46
46
|
ramifice/fields/integer_field.py,sha256=Gnm5IBSvWtCLGbg5pOSAdKa5xLzqXgiigVbzw8zcjas,4531
|
47
|
-
ramifice/fields/ip_field.py,sha256=
|
48
|
-
ramifice/fields/password_field.py,sha256=
|
49
|
-
ramifice/fields/phone_field.py,sha256=
|
47
|
+
ramifice/fields/ip_field.py,sha256=inImogNq0ldYZ8ceOG9vMj_cqbykmgnsTcsRzV_vWWg,3312
|
48
|
+
ramifice/fields/password_field.py,sha256=_O2VGcKAfrMkFSWFIE7foVB5r3K4EoO8TIQNNNooQxo,3207
|
49
|
+
ramifice/fields/phone_field.py,sha256=dPpEdiiaZtf1eYV7AgzrM_-ZfkGPQVaGZmMsnwXECto,3585
|
50
50
|
ramifice/fields/slug_field.py,sha256=t-9ckQ6ki7lNis7U05t4MDd0cE_cdm29es8zfRlHfSs,2655
|
51
51
|
ramifice/fields/text_field.py,sha256=AFkXCEI_4QjBdyYtp1DClwaCLkwjKurmLcrDtxhSGxc,3971
|
52
|
-
ramifice/fields/url_field.py,sha256=
|
52
|
+
ramifice/fields/url_field.py,sha256=FPfpJGeRSdiVVQ1Wf8USZ7BxOm25v3Kp2FLmd-mxvMw,3963
|
53
53
|
ramifice/fields/general/__init__.py,sha256=5OE0TwPQjvpB3lBPuEwKrhjR_1ehOWxB98OJP_n32MA,20
|
54
54
|
ramifice/fields/general/choice_group.py,sha256=TBJblwH8mB71wd1z2jcSs28H-zx3JZVBfkk4YCE1-pI,916
|
55
55
|
ramifice/fields/general/date_group.py,sha256=RKockc_X1bYAbpzxTzXdc0kxgx51MK0bjko_j34ixWU,1169
|
@@ -73,10 +73,10 @@ ramifice/paladins/groups/file_group.py,sha256=AtGu2sQ9A64dPo2Kpt4milp5HWPdULdPdQ
|
|
73
73
|
ramifice/paladins/groups/id_group.py,sha256=zAlJrDTOdRY9e7eFYSXPjjsD05A4EsgSE6ibN3KKOMU,1263
|
74
74
|
ramifice/paladins/groups/img_group.py,sha256=o0bMI1WIA6t1QrhLaR2bBAAJUKCgHg7SiIFQsGTr2Cg,5535
|
75
75
|
ramifice/paladins/groups/num_group.py,sha256=lpyFG9a6WGOzu9f_9jwYVWZNFHxG0B0AVWvvbv_2mV0,2224
|
76
|
-
ramifice/paladins/groups/pass_group.py,sha256=
|
76
|
+
ramifice/paladins/groups/pass_group.py,sha256=tjBSovPSCKATF46FazT0a1EQ2YiztRqOjBq0uu2nTU8,1852
|
77
77
|
ramifice/paladins/groups/slug_group.py,sha256=SVYxHcSSgCA51C18LVGxMQYuUw-6ryQlTi6B9T8Dzsw,2185
|
78
|
-
ramifice/paladins/groups/text_group.py,sha256=
|
79
|
-
ramifice-0.3.
|
80
|
-
ramifice-0.3.
|
81
|
-
ramifice-0.3.
|
82
|
-
ramifice-0.3.
|
78
|
+
ramifice/paladins/groups/text_group.py,sha256=o5DnlptN93vsHtb36qO-noEnPv7CSAiqVj1j603zKw0,3159
|
79
|
+
ramifice-0.3.25.dist-info/METADATA,sha256=RCix9UrN67JO5bCxjhQ4lgWYtiX-RlQJHzm7erzuuN8,20303
|
80
|
+
ramifice-0.3.25.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
81
|
+
ramifice-0.3.25.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
|
82
|
+
ramifice-0.3.25.dist-info/RECORD,,
|
File without changes
|
File without changes
|