ramifice 0.8.2__py3-none-any.whl → 0.8.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.
- ramifice/fields/file_field.py +16 -14
- ramifice/fields/general/file_group.py +0 -2
- ramifice/fields/image_field.py +16 -14
- ramifice/models/decorator.py +1 -0
- ramifice/paladins/check.py +2 -2
- ramifice/paladins/delete.py +2 -2
- ramifice/utils/constants.py +16 -2
- ramifice/utils/tools.py +3 -3
- ramifice/utils/translations.py +2 -2
- {ramifice-0.8.2.dist-info → ramifice-0.8.4.dist-info}/METADATA +1 -1
- {ramifice-0.8.2.dist-info → ramifice-0.8.4.dist-info}/RECORD +13 -13
- {ramifice-0.8.2.dist-info → ramifice-0.8.4.dist-info}/WHEEL +0 -0
- {ramifice-0.8.2.dist-info → ramifice-0.8.4.dist-info}/licenses/LICENSE +0 -0
ramifice/fields/file_field.py
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
"""Field of Model for upload file."""
|
2
2
|
|
3
|
-
import os
|
4
3
|
import uuid
|
5
4
|
from base64 import b64decode
|
6
5
|
from datetime import date
|
6
|
+
from os.path import basename
|
7
7
|
from pathlib import Path
|
8
8
|
|
9
|
-
import
|
9
|
+
from aiofiles import open as async_open
|
10
|
+
from aiofiles import os as async_os
|
10
11
|
from aioshutil import copyfile
|
11
12
|
|
12
13
|
from ramifice.fields.general.field import Field
|
13
14
|
from ramifice.fields.general.file_group import FileGroup
|
14
15
|
from ramifice.utils import constants
|
16
|
+
from ramifice.utils.constants import MEDIA_ROOT, MEDIA_URL
|
15
17
|
from ramifice.utils.errors import FileHasNoExtensionError
|
16
18
|
from ramifice.utils.mixins.json_converter import JsonMixin
|
17
19
|
|
@@ -124,25 +126,25 @@ class FileField(Field, FileGroup, JsonMixin):
|
|
124
126
|
# Create the current date for the directory name.
|
125
127
|
date_str: str = str(date.today())
|
126
128
|
# Create path to target directory.
|
127
|
-
dir_target_path = f"{
|
129
|
+
dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
|
128
130
|
# Create target directory if it does not exist.
|
129
|
-
if not await
|
130
|
-
await
|
131
|
+
if not await async_os.path.exists(dir_target_path):
|
132
|
+
await async_os.makedirs(dir_target_path)
|
131
133
|
# Create path to target file.
|
132
134
|
f_target_path = f"{dir_target_path}/{f_uuid_name}"
|
133
135
|
# Save file in target directory.
|
134
|
-
async with
|
136
|
+
async with async_open(f_target_path, mode="wb") as open_f:
|
135
137
|
f_content = b64decode(base64_str)
|
136
138
|
await open_f.write(f_content)
|
137
139
|
# Add paths to target file.
|
138
140
|
file_info["path"] = f_target_path
|
139
|
-
file_info["url"] = f"{
|
141
|
+
file_info["url"] = f"{MEDIA_URL}/uploads/{self.target_dir}/{date_str}/{f_uuid_name}"
|
140
142
|
# Add original file name.
|
141
143
|
file_info["name"] = filename
|
142
144
|
# Add file extension.
|
143
145
|
file_info["extension"] = extension
|
144
146
|
# Add file size (in bytes).
|
145
|
-
file_info["size"] = await
|
147
|
+
file_info["size"] = await async_os.path.getsize(f_target_path)
|
146
148
|
#
|
147
149
|
# to value.
|
148
150
|
self.value = file_info
|
@@ -169,23 +171,23 @@ class FileField(Field, FileGroup, JsonMixin):
|
|
169
171
|
# Create the current date for the directory name.
|
170
172
|
date_str: str = str(date.today())
|
171
173
|
# Create path to target directory.
|
172
|
-
dir_target_path = f"{
|
174
|
+
dir_target_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}"
|
173
175
|
# Create target directory if it does not exist.
|
174
|
-
if not await
|
175
|
-
await
|
176
|
+
if not await async_os.path.exists(dir_target_path):
|
177
|
+
await async_os.makedirs(dir_target_path)
|
176
178
|
# Create path to target file.
|
177
179
|
f_target_path = f"{dir_target_path}/{f_uuid_name}"
|
178
180
|
# Save file in target directory.
|
179
181
|
await copyfile(src_path, f_target_path)
|
180
182
|
# Add paths to target file.
|
181
183
|
file_info["path"] = f_target_path
|
182
|
-
file_info["url"] = f"{
|
184
|
+
file_info["url"] = f"{MEDIA_URL}/uploads/{self.target_dir}/{date_str}/{f_uuid_name}"
|
183
185
|
# Add original file name.
|
184
|
-
file_info["name"] =
|
186
|
+
file_info["name"] = basename(src_path)
|
185
187
|
# Add file extension.
|
186
188
|
file_info["extension"] = extension
|
187
189
|
# Add file size (in bytes).
|
188
|
-
file_info["size"] = await
|
190
|
+
file_info["size"] = await async_os.path.getsize(f_target_path)
|
189
191
|
#
|
190
192
|
# to value.
|
191
193
|
self.value = file_info
|
ramifice/fields/image_field.py
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
"""Field of Model for upload image."""
|
2
2
|
|
3
|
-
import os
|
4
3
|
import uuid
|
5
4
|
from base64 import b64decode
|
6
5
|
from datetime import date
|
6
|
+
from os.path import basename
|
7
7
|
from pathlib import Path
|
8
8
|
|
9
|
-
import
|
9
|
+
from aiofiles import open as async_open
|
10
|
+
from aiofiles import os as async_os
|
10
11
|
from aioshutil import copyfile
|
11
12
|
|
12
13
|
from ramifice.fields.general.field import Field
|
13
14
|
from ramifice.fields.general.file_group import FileGroup
|
14
15
|
from ramifice.utils import constants
|
16
|
+
from ramifice.utils.constants import MEDIA_ROOT, MEDIA_URL
|
15
17
|
from ramifice.utils.errors import FileHasNoExtensionError
|
16
18
|
from ramifice.utils.mixins.json_converter import JsonMixin
|
17
19
|
|
@@ -155,18 +157,18 @@ class ImageField(Field, FileGroup, JsonMixin):
|
|
155
157
|
# Directory name for the original image and its thumbnails.
|
156
158
|
general_dir = uuid.uuid4()
|
157
159
|
# Create path to target directory with images.
|
158
|
-
imgs_dir_path = f"{
|
160
|
+
imgs_dir_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}/{general_dir}"
|
159
161
|
# Create url path to target directory with images.
|
160
|
-
imgs_dir_url = f"{
|
162
|
+
imgs_dir_url = f"{MEDIA_URL}/uploads/{self.target_dir}/{date_str}/{general_dir}"
|
161
163
|
# Create a new name for the original image.
|
162
164
|
new_original_name = f"original{extension}"
|
163
165
|
# Create path to main image.
|
164
166
|
main_img_path = f"{imgs_dir_path}/{new_original_name}"
|
165
167
|
# Create target directory if it does not exist.
|
166
|
-
if not await
|
167
|
-
await
|
168
|
+
if not await async_os.path.exists(imgs_dir_path):
|
169
|
+
await async_os.makedirs(imgs_dir_path)
|
168
170
|
# Save main image in target directory.
|
169
|
-
async with
|
171
|
+
async with async_open(main_img_path, mode="wb") as open_f:
|
170
172
|
f_content = b64decode(base64_str)
|
171
173
|
await open_f.write(f_content)
|
172
174
|
# Add paths for main image.
|
@@ -186,7 +188,7 @@ class ImageField(Field, FileGroup, JsonMixin):
|
|
186
188
|
# Add url path to target directory with images.
|
187
189
|
img_info["imgs_dir_url"] = imgs_dir_url
|
188
190
|
# Add size of main image (in bytes).
|
189
|
-
img_info["size"] = await
|
191
|
+
img_info["size"] = await async_os.path.getsize(main_img_path)
|
190
192
|
#
|
191
193
|
# to value.
|
192
194
|
self.value = img_info
|
@@ -213,23 +215,23 @@ class ImageField(Field, FileGroup, JsonMixin):
|
|
213
215
|
# Directory name for the original image and its thumbnails.
|
214
216
|
general_dir = uuid.uuid4()
|
215
217
|
# Create path to target directory with images.
|
216
|
-
imgs_dir_path = f"{
|
218
|
+
imgs_dir_path = f"{MEDIA_ROOT}/uploads/{self.target_dir}/{date_str}/{general_dir}"
|
217
219
|
# Create url path to target directory with images.
|
218
|
-
imgs_dir_url = f"{
|
220
|
+
imgs_dir_url = f"{MEDIA_URL}/uploads/{self.target_dir}/{date_str}/{general_dir}"
|
219
221
|
# Create a new name for the original image.
|
220
222
|
new_original_name = f"original{extension}"
|
221
223
|
# Create path to main image.
|
222
224
|
main_img_path = f"{imgs_dir_path}/{new_original_name}"
|
223
225
|
# Create target directory if it does not exist.
|
224
|
-
if not await
|
225
|
-
await
|
226
|
+
if not await async_os.path.exists(imgs_dir_path):
|
227
|
+
await async_os.makedirs(imgs_dir_path)
|
226
228
|
# Save main image in target directory.
|
227
229
|
await copyfile(src_path, main_img_path)
|
228
230
|
# Add paths for main image.
|
229
231
|
img_info["path"] = main_img_path
|
230
232
|
img_info["url"] = f"{imgs_dir_url}/{new_original_name}"
|
231
233
|
# Add original image name.
|
232
|
-
img_info["name"] =
|
234
|
+
img_info["name"] = basename(src_path)
|
233
235
|
# Add image extension.
|
234
236
|
img_info["extension"] = extension
|
235
237
|
# Transform extension to the upper register and delete the point.
|
@@ -242,7 +244,7 @@ class ImageField(Field, FileGroup, JsonMixin):
|
|
242
244
|
# Add url path to target directory with images.
|
243
245
|
img_info["imgs_dir_url"] = imgs_dir_url
|
244
246
|
# Add size of main image (in bytes).
|
245
|
-
img_info["size"] = await
|
247
|
+
img_info["size"] = await async_os.path.getsize(main_img_path)
|
246
248
|
#
|
247
249
|
# to value.
|
248
250
|
self.value = img_info
|
ramifice/models/decorator.py
CHANGED
@@ -42,6 +42,7 @@ def model(
|
|
42
42
|
raise DoesNotMatchRegexError("^[A-Z][a-zA-Z0-9]{0,24}$")
|
43
43
|
if fixture_name is not None:
|
44
44
|
fixture_path = f"config/fixtures/{fixture_name}.yml"
|
45
|
+
|
45
46
|
if not os.path.exists(fixture_path):
|
46
47
|
msg = (
|
47
48
|
f"Model: `{cls.__module__}.{cls.__name__}` > "
|
ramifice/paladins/check.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
from typing import Any
|
4
4
|
|
5
|
-
from aiofiles import os
|
5
|
+
from aiofiles import os as async_os
|
6
6
|
from aioshutil import rmtree
|
7
7
|
from bson.objectid import ObjectId
|
8
8
|
from pymongo.asynchronous.collection import AsyncCollection
|
@@ -133,7 +133,7 @@ class CheckMixin(
|
|
133
133
|
file_data = result_map.get(field_name)
|
134
134
|
if file_data is not None:
|
135
135
|
if file_data["is_new_file"]:
|
136
|
-
await
|
136
|
+
await async_os.remove(file_data["path"])
|
137
137
|
field_data.value = None
|
138
138
|
if curr_doc is not None:
|
139
139
|
field_data.value = curr_doc[field_name]
|
ramifice/paladins/delete.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
from typing import Any
|
4
4
|
|
5
|
-
from aiofiles import os
|
5
|
+
from aiofiles import os as async_os
|
6
6
|
from aioshutil import rmtree
|
7
7
|
from pymongo.asynchronous.collection import AsyncCollection
|
8
8
|
|
@@ -77,7 +77,7 @@ class DeleteMixin:
|
|
77
77
|
if group == "file":
|
78
78
|
file_data = mongo_doc[field_name]
|
79
79
|
if file_data is not None and len(file_data["path"]) > 0:
|
80
|
-
await
|
80
|
+
await async_os.remove(file_data["path"])
|
81
81
|
file_data = None
|
82
82
|
elif group == "img":
|
83
83
|
file_data = mongo_doc[field_name]
|
ramifice/utils/constants.py
CHANGED
@@ -7,9 +7,11 @@ List of variables:
|
|
7
7
|
- `MONGO_DATABASE` - Caching a Mongo database.
|
8
8
|
- `DATABASE_NAME` - Caching a database name.
|
9
9
|
- `SUPER_COLLECTION_NAME` - Caching a super collection name.
|
10
|
+
- `MEDIA_ROOT` - Absolute filesystem path to the directory that will hold user-uploaded files.
|
11
|
+
- `MEDIA_URL` - URL that handles the media served from MEDIA_ROOT, used for managing stored files.
|
12
|
+
- `STATIC_ROOT` - The absolute path to the directory where static files are located.
|
13
|
+
- `STATIC_URL` - URL to use when referring to static files located in STATIC_ROOT.
|
10
14
|
- `REGEX` - Caching a patterns of regular expression.
|
11
|
-
- `FILE_INFO_DICT` - Caching a dictionary to transmit information about the file.
|
12
|
-
- `IMG_INFO_DICT` - Caching a dictionary to transmit information about the image.
|
13
15
|
"""
|
14
16
|
|
15
17
|
import re
|
@@ -30,6 +32,18 @@ DATABASE_NAME: str | None = None
|
|
30
32
|
# Store technical data for Models migration into a database.
|
31
33
|
# Store dynamic field data for simulate relationship Many-to-One and Many-to-Manyю.
|
32
34
|
SUPER_COLLECTION_NAME: str = "SUPER_COLLECTION"
|
35
|
+
# Absolute filesystem path to the
|
36
|
+
# directory that will hold user-uploaded files.
|
37
|
+
MEDIA_ROOT: str = "public/media"
|
38
|
+
# URL that handles the media served from MEDIA_ROOT,
|
39
|
+
# used for managing stored files.
|
40
|
+
MEDIA_URL: str = "/media"
|
41
|
+
# The absolute path to the
|
42
|
+
# directory where static files are located.
|
43
|
+
STATIC_ROOT: str = "public/static"
|
44
|
+
# URL to use when referring to
|
45
|
+
# static files located in STATIC_ROOT.
|
46
|
+
STATIC_URL: str = "/static"
|
33
47
|
# Caching a patterns of regular expression.
|
34
48
|
REGEX: dict[str, re.Pattern] = {
|
35
49
|
"database_name": re.compile(r"^[a-zA-Z][-_a-zA-Z0-9]{0,59}$"),
|
ramifice/utils/tools.py
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
import asyncio
|
4
4
|
import ipaddress
|
5
5
|
import math
|
6
|
-
import os
|
7
6
|
from typing import Any
|
8
7
|
from urllib.parse import urlparse
|
9
8
|
|
10
9
|
import phonenumbers
|
10
|
+
from aiofiles import ospath
|
11
11
|
from bson.objectid import ObjectId
|
12
12
|
from email_validator import EmailNotValidError, validate_email
|
13
13
|
|
@@ -29,9 +29,9 @@ def to_human_size(size: int) -> str:
|
|
29
29
|
return f"{size} {order}"
|
30
30
|
|
31
31
|
|
32
|
-
def get_file_size(path: str) -> int:
|
32
|
+
async def get_file_size(path: str) -> int:
|
33
33
|
"""Get file size in bytes."""
|
34
|
-
size: int =
|
34
|
+
size: int = await ospath.getsize(path)
|
35
35
|
return size
|
36
36
|
|
37
37
|
|
ramifice/utils/translations.py
CHANGED
@@ -30,11 +30,11 @@ from typing import Any
|
|
30
30
|
|
31
31
|
from ramifice.utils.errors import PanicError
|
32
32
|
|
33
|
-
# Language
|
33
|
+
# Language by default.
|
34
34
|
DEFAULT_LOCALE: str = "en"
|
35
35
|
# Code of current language.
|
36
36
|
CURRENT_LOCALE: str = copy.deepcopy(DEFAULT_LOCALE)
|
37
|
-
# List of
|
37
|
+
# List of supported languages.
|
38
38
|
LANGUAGES: frozenset[str] = frozenset(("en", "ru"))
|
39
39
|
|
40
40
|
if not DEFAULT_LOCALE in LANGUAGES:
|
@@ -25,10 +25,10 @@ ramifice/fields/color_field.py,sha256=K-lYp8f08HTZt6WU0kY3CQWaAmx6I3-uyKHBq7xAeS
|
|
25
25
|
ramifice/fields/date_field.py,sha256=-M_dD8tVUXcDCQD5Hy5Ns9Z2QGlRya0qbvoWgA4qpmg,5277
|
26
26
|
ramifice/fields/date_time_field.py,sha256=ahjX-cD5Qj-V7JUi5QAZ8qgv9UePhYYYzJghiasKdqE,5312
|
27
27
|
ramifice/fields/email_field.py,sha256=4Kxy1K6CXJUJ8Db0CQuopjodiY4ybe7V0GT756t7Nks,3481
|
28
|
-
ramifice/fields/file_field.py,sha256=
|
28
|
+
ramifice/fields/file_field.py,sha256=CSCHSExyXUsvLGGCj3WmBHM0YUUcK9QZZb3kB8r8HQs,8253
|
29
29
|
ramifice/fields/float_field.py,sha256=JeVwoIi6j-dovXarZ3NgmSQI7f3qZzydlRs_yqp3Faw,4637
|
30
30
|
ramifice/fields/id_field.py,sha256=YO5oIwXtqgURjjd2oYe2ouXxdpaiJp5ZhUgUA2pkNeo,4183
|
31
|
-
ramifice/fields/image_field.py,sha256=
|
31
|
+
ramifice/fields/image_field.py,sha256=ZBbraEI0P5qWK1_xDnZ42YXhqgK4LdcL28vg9zgPBiw,11672
|
32
32
|
ramifice/fields/integer_field.py,sha256=xPwpdhYNz4MyHgOypqa29oGNdKZic05yyUYHg5CDD3E,4609
|
33
33
|
ramifice/fields/ip_field.py,sha256=tBFGFMC_zwAyLGtVRNNfiu4vQoxXPcgVHhX_aoHrvns,3390
|
34
34
|
ramifice/fields/password_field.py,sha256=USD4Y8MTI89QZVT6zqLGBmb5kqOKrXqh73-z99cOvtk,3266
|
@@ -40,15 +40,15 @@ ramifice/fields/general/__init__.py,sha256=JzgIDseNQLB_IDwY9-JSiT_bONxvhJmbKl5Ph
|
|
40
40
|
ramifice/fields/general/choice_group.py,sha256=aNO8LnsafGOOQ7d2lAppI9YtzVHbWUZ6t1znEEIbAv8,962
|
41
41
|
ramifice/fields/general/date_group.py,sha256=C5VgR0CBEGgG7nIYEeI82hVXttngSJAGFvEdXC_OpGY,1213
|
42
42
|
ramifice/fields/general/field.py,sha256=qm7N-U5H1V6BK_6quJeGGpTmb9IqA-vxZlNHwoABye0,1384
|
43
|
-
ramifice/fields/general/file_group.py,sha256=
|
43
|
+
ramifice/fields/general/file_group.py,sha256=pC9bGUpDeu7FLJVD6NMCzq18aPETotipknSly2GH7Q0,1014
|
44
44
|
ramifice/fields/general/number_group.py,sha256=LOPHbKAnIuqW4DEh2fH78w6qOQjp0OhkuP7MoikhlkA,761
|
45
45
|
ramifice/fields/general/text_group.py,sha256=m9EnlYGwqlck-JIYOCUd0hUYAVr8jH4YCnTmm9QlCkQ,1103
|
46
46
|
ramifice/models/__init__.py,sha256=h_QQ5rSJNZ-7kmx7wIFd8E8RmUS94b_x4jdwMbq8zm4,15
|
47
|
-
ramifice/models/decorator.py,sha256=
|
47
|
+
ramifice/models/decorator.py,sha256=dzwC489KBjamQxrWNy8lrdXVLb3e8OKPWbPGJZqxaFA,5958
|
48
48
|
ramifice/models/model.py,sha256=e5UWHKIHwm7saxQ4bbamsTkz1VVBIqTRlAmJCOg5uRE,7160
|
49
49
|
ramifice/paladins/__init__.py,sha256=EJ6EEKXUcMG5P1bDmlEa4W3fsxSz5u6mzDG_oU1efMQ,618
|
50
|
-
ramifice/paladins/check.py,sha256=
|
51
|
-
ramifice/paladins/delete.py,sha256=
|
50
|
+
ramifice/paladins/check.py,sha256=c-7jbFV5qzE9nF8Cl6VSPA8DtziADOuV6j1rldnZBKI,6602
|
51
|
+
ramifice/paladins/delete.py,sha256=teUyj-sosObatoaFpMC3wodC4GvWbzgJCCxsI_Z9vyk,3448
|
52
52
|
ramifice/paladins/password.py,sha256=G-tMz2dIiOYEhOeSHYgAmc2e4tG_TJ2gt5tzPwBapkw,3047
|
53
53
|
ramifice/paladins/refrash.py,sha256=hIZQEBGtoIhuGGg2KQYGApCaMb8WhK_QZlzi1_-zzU0,1100
|
54
54
|
ramifice/paladins/save.py,sha256=mFau65uWYy4dSVyTVdZGR3VUnP-I_NPdMvq7F5n1sFo,3899
|
@@ -66,19 +66,19 @@ ramifice/paladins/groups/pass_group.py,sha256=uuIIqMBXsYG7vTHc_AhdgWuNCivxTgQMjk
|
|
66
66
|
ramifice/paladins/groups/slug_group.py,sha256=ztiA2v7e5lQYRZtlLw8WGOhSWaYQfOdZ6wkKbx3ZbTM,2329
|
67
67
|
ramifice/paladins/groups/text_group.py,sha256=cdwUZoomw61A7CmDIbds_oOaia2tD-J5LLuj5b8E8O4,4472
|
68
68
|
ramifice/utils/__init__.py,sha256=xixHoOX4ja5jIUZemem1qn4k4aonv3G3Q76azQK_pkU,43
|
69
|
-
ramifice/utils/constants.py,sha256=
|
69
|
+
ramifice/utils/constants.py,sha256=dTSk07FVc6hgXwG1IF0_klPnbfxlFHiaRmym5zWgzIM,2395
|
70
70
|
ramifice/utils/errors.py,sha256=iuhq7fzpUmsOyeXeg2fJjta8yAuqlXLKsZVMpfUhtHE,1901
|
71
71
|
ramifice/utils/fixtures.py,sha256=PMRl1Ud0Ek0eX5F7BPiL7az_H7YKtIVKB8MJ17CeBdw,3179
|
72
72
|
ramifice/utils/migration.py,sha256=5VYYB7DFMzLCRYWdlwtqGRSUPFdXp5SMxuMWraofVCw,11106
|
73
|
-
ramifice/utils/tools.py,sha256=
|
74
|
-
ramifice/utils/translations.py,sha256=
|
73
|
+
ramifice/utils/tools.py,sha256=DSSR__sHgfDlYF4vhtR8vmeFtgquonkM5W_3V3SX6Y0,2872
|
74
|
+
ramifice/utils/translations.py,sha256=Ibx6HqPcnsNxuBfXDs9mCLEA7xu4mkl3q39vqFaK-GI,4233
|
75
75
|
ramifice/utils/unit.py,sha256=PPNKWYFJ8cz0nwbBPaTdL58_Nr7N0fIHFJBpKG2ZLKI,2482
|
76
76
|
ramifice/utils/mixins/__init__.py,sha256=GrxJDsw73bEkitIh0-0BCxNnUK-N5uRXMCRlaPoaz1o,265
|
77
77
|
ramifice/utils/mixins/add_valid.py,sha256=TLOObedzXNA9eCylfAVbVCqIKE5sV-P5AdIN7avj-GA,407
|
78
78
|
ramifice/utils/mixins/hooks.py,sha256=33jvJRhfnJeL2Hd_YFXk3M_7wjqHaByU2wRjKyboL6s,914
|
79
79
|
ramifice/utils/mixins/indexing.py,sha256=Z0427HoaVRyNmSNN8Fx0mSICgAKV-gDdu3iR5qYUEbs,329
|
80
80
|
ramifice/utils/mixins/json_converter.py,sha256=2K_PZ34AzpesusgyyQFOLXFPcjXez3TWn-m9CHIKwRo,1131
|
81
|
-
ramifice-0.8.
|
82
|
-
ramifice-0.8.
|
83
|
-
ramifice-0.8.
|
84
|
-
ramifice-0.8.
|
81
|
+
ramifice-0.8.4.dist-info/METADATA,sha256=D7LCsTfcUITuLa2XzN_DS5sSgED6Scv9JfaXcu5b84k,21016
|
82
|
+
ramifice-0.8.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
83
|
+
ramifice-0.8.4.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
|
84
|
+
ramifice-0.8.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|