django-camomilla-cms 6.0.0b15__py2.py3-none-any.whl → 6.0.0b17__py2.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.
Files changed (72) hide show
  1. camomilla/__init__.py +1 -1
  2. camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
  3. camomilla/dynamic_pages_urls.py +6 -2
  4. camomilla/managers/pages.py +93 -8
  5. camomilla/model_api.py +14 -7
  6. camomilla/models/media.py +1 -1
  7. camomilla/models/menu.py +10 -4
  8. camomilla/models/page.py +189 -127
  9. camomilla/openapi/schema.py +17 -8
  10. camomilla/redirects.py +10 -0
  11. camomilla/serializers/base/__init__.py +6 -4
  12. camomilla/serializers/fields/__init__.py +5 -17
  13. camomilla/serializers/fields/related.py +10 -4
  14. camomilla/serializers/mixins/__init__.py +23 -195
  15. camomilla/serializers/mixins/fields.py +20 -0
  16. camomilla/serializers/mixins/filter_fields.py +57 -0
  17. camomilla/serializers/mixins/json.py +34 -0
  18. camomilla/serializers/mixins/language.py +32 -0
  19. camomilla/serializers/mixins/nesting.py +35 -0
  20. camomilla/serializers/mixins/optimize.py +91 -0
  21. camomilla/serializers/mixins/ordering.py +34 -0
  22. camomilla/serializers/mixins/page.py +58 -0
  23. camomilla/{contrib/rest_framework/serializer.py → serializers/mixins/translation.py} +16 -56
  24. camomilla/serializers/utils.py +5 -3
  25. camomilla/serializers/validators.py +6 -2
  26. camomilla/settings.py +10 -2
  27. camomilla/storages/default.py +12 -0
  28. camomilla/storages/optimize.py +2 -2
  29. camomilla/storages/overwrite.py +2 -2
  30. camomilla/templates/defaults/parts/menu.html +1 -1
  31. camomilla/templatetags/menus.py +3 -0
  32. camomilla/theme/__init__.py +1 -1
  33. camomilla/theme/{admin.py → admin/__init__.py} +22 -20
  34. camomilla/theme/admin/pages.py +46 -0
  35. camomilla/theme/admin/translations.py +13 -0
  36. camomilla/theme/apps.py +1 -5
  37. camomilla/translation.py +7 -1
  38. camomilla/urls.py +2 -5
  39. camomilla/utils/query_parser.py +167 -0
  40. camomilla/utils/translation.py +47 -5
  41. camomilla/views/base/__init__.py +35 -5
  42. camomilla/views/medias.py +1 -1
  43. camomilla/views/menus.py +0 -2
  44. camomilla/views/mixins/__init__.py +17 -69
  45. camomilla/views/mixins/bulk_actions.py +22 -0
  46. camomilla/views/mixins/language.py +33 -0
  47. camomilla/views/mixins/optimize.py +18 -0
  48. camomilla/views/mixins/pagination.py +12 -18
  49. camomilla/views/mixins/permissions.py +6 -0
  50. camomilla/views/pages.py +12 -2
  51. {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA +23 -16
  52. django_camomilla_cms-6.0.0b17.dist-info/RECORD +132 -0
  53. {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/WHEEL +1 -1
  54. tests/fixtures/__init__.py +17 -0
  55. tests/test_api.py +2 -11
  56. tests/test_camomilla_filters.py +7 -13
  57. tests/test_media.py +113 -0
  58. tests/test_menu.py +97 -0
  59. tests/test_model_api.py +68 -0
  60. tests/test_model_api_permissions.py +39 -0
  61. tests/test_model_api_register.py +393 -0
  62. tests/test_pages.py +343 -0
  63. tests/test_query_parser.py +58 -0
  64. tests/test_templates_context.py +111 -0
  65. tests/test_utils.py +64 -64
  66. tests/utils/api.py +28 -0
  67. tests/utils/media.py +9 -0
  68. camomilla/serializers/fields/json.py +0 -49
  69. django_camomilla_cms-6.0.0b15.dist-info/RECORD +0 -105
  70. {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info/licenses}/LICENSE +0 -0
  71. {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/top_level.txt +0 -0
  72. {camomilla/contrib/rest_framework → tests/utils}/__init__.py +0 -0
tests/utils/api.py ADDED
@@ -0,0 +1,28 @@
1
+ from django.contrib.auth.models import User
2
+ from rest_framework.test import APIClient
3
+
4
+ client = APIClient()
5
+
6
+
7
+ def login_superuser():
8
+ User.objects.create_superuser("admin", "admin@test.com", "adminadmin")
9
+ response = client.post(
10
+ "/api/camomilla/token-auth/", {"username": "admin", "password": "adminadmin"}
11
+ )
12
+ return response.json()["token"]
13
+
14
+
15
+ def login_user():
16
+ User.objects.create_user("user", "user@test.com", "useruser")
17
+ response = client.post(
18
+ "/api/camomilla/token-auth/", {"username": "user", "password": "useruser"}
19
+ )
20
+ return response.json()["token"]
21
+
22
+
23
+ def login_staff():
24
+ User.objects.create_user("staff", "staff@test.com", "staffstaff", is_staff=True)
25
+ response = client.post(
26
+ "/api/camomilla/token-auth/", {"username": "staff", "password": "staffstaff"}
27
+ )
28
+ return response.json()["token"]
tests/utils/media.py ADDED
@@ -0,0 +1,9 @@
1
+ import os
2
+ from tests.fixtures import load_asset
3
+ from django.conf import settings
4
+
5
+ def load_asset_and_remove_media(filename):
6
+ asset = load_asset(filename)
7
+ if os.path.exists(f"{settings.MEDIA_ROOT}/{filename}"):
8
+ os.remove(f"{settings.MEDIA_ROOT}/{filename}")
9
+ return asset
@@ -1,49 +0,0 @@
1
- from pydantic import TypeAdapter, ValidationError
2
- from rest_framework import serializers
3
- from rest_framework.utils import model_meta
4
- from typing import TYPE_CHECKING, Any, Union, Dict, List
5
-
6
- from camomilla.utils.setters import pointed_setter
7
-
8
- if TYPE_CHECKING:
9
- from structured.pydantic.models import BaseModel
10
-
11
-
12
-
13
- class StructuredJSONField(serializers.JSONField):
14
- """
15
- This field allows to serialize and deserialize structured data.
16
- """
17
-
18
- schema: Union["BaseModel", TypeAdapter] = None
19
-
20
- def __init__(self, **kwargs):
21
- self.schema = kwargs.pop("schema", None)
22
- super().__init__(**kwargs)
23
-
24
- def bind(self, field_name, parent):
25
- if self.schema is None and isinstance(parent, serializers.ModelSerializer):
26
- info = model_meta.get_field_info(parent.Meta.model)
27
- field = info.fields[field_name]
28
- self.schema = field.schema
29
- self.many = field.many
30
- self.json_schema = field.schema.json_schema()
31
- super().bind(field_name, parent)
32
-
33
- def to_representation(self, instance: Union["BaseModel", List["BaseModel"]]):
34
- if isinstance(instance, list) and self.many:
35
- return super().to_representation(
36
- self.schema.dump_python(instance, exclude_unset=True)
37
- )
38
- return super().to_representation(instance.model_dump(exclude_unset=True))
39
-
40
- def to_internal_value(self, data: Union[list, dict]):
41
- try:
42
- return self.schema.validate_python(super().to_internal_value(data))
43
- except ValidationError as e:
44
- drf_error: Union[list, Dict[str, Any]] = [] if self.many else {}
45
- for error in e.errors():
46
- pointed_setter(
47
- drf_error, ".".join([str(x) for x in error["loc"]]), [error["msg"]]
48
- )
49
- raise serializers.ValidationError(drf_error)
@@ -1,105 +0,0 @@
1
- camomilla/__init__.py,sha256=NkhtGSnemCX19_YBz80aKvqoqwSnTGEtwPHHnB-JjcI,251
2
- camomilla/apps.py,sha256=eUwb9ynyiRAc5OXgt7ZsAdhsCOnPCpNdIFYMheNeN-o,532
3
- camomilla/authentication.py,sha256=jz6tQT4PPEu-_JLox1LZrOy7EiWBb9MWaObK63MJGus,855
4
- camomilla/context_processors.py,sha256=cGowjDZ-oDGYn1j2Pj5QDGCqnzXAOdOwp5dmzin_FTc,165
5
- camomilla/defaults.py,sha256=VNQ_sbxu09AyFGNpUUYypIAyhlBhEORD36BBNj7e73I,1220
6
- camomilla/dynamic_pages_urls.py,sha256=14H47KlSxmINoJyrsul0KR7Qvk6-1uoXrD1ReV_W4h8,1056
7
- camomilla/exceptions.py,sha256=gLniAsK_pmsNNKGMv5Z384LXVbM8oeHcOwz4F91u1LY,111
8
- camomilla/model_api.py,sha256=VC3tNQucS3-KVtdZNWkkbkJn8vtl_cBKYTcC3QU6PpU,2253
9
- camomilla/parsers.py,sha256=fL8XGCGPxJIZNZkPdGtnPSbDP-6-yzGOCVMuLPjkx9Y,1975
10
- camomilla/permissions.py,sha256=9NlBO4JMmg36vXCUjPNyq6uZxhkdrnXyIbJVLtWhGWE,1813
11
- camomilla/settings.py,sha256=GDJXDcEmyobGrP4MmEH3MAt1KBK74gXmmRR8kFuJzp0,3306
12
- camomilla/sitemap.py,sha256=U2t5TwhB_-sEscmQZ69PZ5st3bIap8NRxzWEvCgB130,786
13
- camomilla/translation.py,sha256=-Y0Toy1D__wxMovipWVIuNx3TrfhDGffrduWYFUmYA4,1269
14
- camomilla/urls.py,sha256=YFUYcPuvnNSTnfJa_JByRWAPLgc4_R4LgqCMrmkbFpE,2217
15
- camomilla/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- camomilla/contrib/modeltranslation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- camomilla/contrib/modeltranslation/hvad_migration.py,sha256=UanLVSlYYd_ykMC4STtYkkUMJqlFQQYhbWkoV47alM0,5403
18
- camomilla/contrib/rest_framework/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- camomilla/contrib/rest_framework/serializer.py,sha256=G6SKes-8RkJKDupCNN0B2B1BQuYqS0y820oGYotxPcY,5924
20
- camomilla/fields/__init__.py,sha256=gKrJwHvUA3q_wu-OVV0hrRZmFkT4znMHrmZtpriDumw,323
21
- camomilla/fields/json.py,sha256=tWEDn6kwTP6pNB53djxuVPu2d57m9cIDc4ccCEfUbDQ,1938
22
- camomilla/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- camomilla/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- camomilla/management/commands/regenerate_thumbnails.py,sha256=pKToASR8p8TJezGpFfuylsAHtriNueJ7xqJJxq55adY,496
25
- camomilla/managers/__init__.py,sha256=Zwp28E1RKafIl0FqcUi1YNHxF19IsMIvhlhS-Njg9Mw,60
26
- camomilla/managers/pages.py,sha256=8SXd0iUt2UA59lEn9DzJC41SkeU7Vc_tFe9sJhvfyww,1144
27
- camomilla/models/__init__.py,sha256=y7Q34AGhQ1weJUKWb6XjiyUbwRnJeylOBGMErU0wqYg,147
28
- camomilla/models/article.py,sha256=LgkZgRsubtDV6NwBz8E2bIgKD6H3I-1QLAxEan5TYYs,1139
29
- camomilla/models/content.py,sha256=mIgtifb_WMIt58we5u6qWZemHvuDN1zZaBeCyzHL78A,956
30
- camomilla/models/media.py,sha256=7TD_0nhNoi8P-Gmsr0Kag4eGaxMXuTfQOFl53Mb03cQ,6854
31
- camomilla/models/menu.py,sha256=1eUOjBTZQklPgHXrQTpPsRKjT4QNFSoQ8diUVNRymfc,3589
32
- camomilla/models/page.py,sha256=O4EGWjzk4cHGzmtkJr2nSWG51qLAlqt5B9fkoyEatrs,17287
33
- camomilla/models/mixins/__init__.py,sha256=c2NixqvrIX4E9WGRqQbylXlqBWDXEqN9mzs_dpB0hFQ,1248
34
- camomilla/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- camomilla/openapi/schema.py,sha256=kYNtIKnLx4SIj893umIE6u-q3HH9hYH9O4zdZCSOe7U,2100
36
- camomilla/serializers/__init__.py,sha256=8v1GsJ_YZ6T72VnKBb5l-8K93oaLf4PIsMt-yFtK-Gk,176
37
- camomilla/serializers/article.py,sha256=pYVcS0KztzjzSqgruElQMMEZcqTzmQUqXrdv_Sx5Az4,401
38
- camomilla/serializers/content_type.py,sha256=qB2wkmkvQI6LHxfSI6auEh6M9cJRFBaHnpmkBCCzeYo,557
39
- camomilla/serializers/media.py,sha256=H4JVpRVxXVmn_BiqrjihKXpfLm9fLmHDFIICRDGJU4s,1940
40
- camomilla/serializers/menu.py,sha256=TdoyXs40PqxNevnRbBbYOOX9rUv9zQGiHFNduspaZnw,552
41
- camomilla/serializers/page.py,sha256=NNjEypVYu_9iKqdHV_-61ea37gxiHlDP5gsloV_i6yg,1834
42
- camomilla/serializers/user.py,sha256=CzrHiVRvYYWNE4eNpCNKtJB7DjVqHHwIcP4NUBXMHSo,3706
43
- camomilla/serializers/utils.py,sha256=sE6Fe8vgGuEWYTox7_ATC6zwcUZ7t2EqkemuP5tWp00,1001
44
- camomilla/serializers/validators.py,sha256=EX-EFg6afFr8viPKq-LHeEtRAKPVtO4kIlEymY1j2HA,2043
45
- camomilla/serializers/base/__init__.py,sha256=HSDBPXQ3ldX0pixDbNLna5LSUQ_TfFZ4JWKRm6OpWcU,793
46
- camomilla/serializers/fields/__init__.py,sha256=T_ONowldBTPfgbwFmoefY1r3TQiB2sbWQPpFvBSnzqE,681
47
- camomilla/serializers/fields/file.py,sha256=yjKMho2ti9TIAzo6nwyLnNPJ6GVUumL2wxhegvYqI2o,800
48
- camomilla/serializers/fields/json.py,sha256=LzSVjVXjRR5mbZ94tVq-wdX3_B5yzv0h7pPEFZVOL1s,1874
49
- camomilla/serializers/fields/related.py,sha256=Lofgk582KAb0EIK20jtds538O_y-yRHo644ND_VlXrM,4747
50
- camomilla/serializers/mixins/__init__.py,sha256=prhA91hMrLezm-mIYc3yHJXefM346okZQ8OS8IxxqhI,7114
51
- camomilla/storages/__init__.py,sha256=ytGgX59Ar8vFfYz7eV8z-j5yO_5FqxdZM25iyLnJuSA,131
52
- camomilla/storages/optimize.py,sha256=YKbhSbTaWNbTFIRTRWdilD3w8b_LjMLOmE6yk2lrbo4,2745
53
- camomilla/storages/overwrite.py,sha256=CO_zSZxr321eohYFuzPjDMK7WMFnvvwlIigIPabU_eE,343
54
- camomilla/templates/admin/camomilla/page/change_form.html,sha256=ig7rRUtylDZMINBQuVPpZLmeB4sOTV_VtqnTgzAyxEo,251
55
- camomilla/templates/defaults/base.html,sha256=pklt7Pif3g9d7gwgRxCQj7gniJaHD14ZqZID_xIlC0A,6638
56
- camomilla/templates/defaults/articles/default.html,sha256=1f89jBvNtTa1mPAbC91yy8CzeAjTWO3hhQsTuQW5OKg,239
57
- camomilla/templates/defaults/pages/default.html,sha256=bP81Qb6M56I-fBJMywWwEu_cnERtWIX28UkGrUSRU6M,144
58
- camomilla/templates/defaults/parts/langswitch.html,sha256=AkaQzb2KNjRYCMLUn_jE31V36rwBIwp4MneirWPiBcI,3424
59
- camomilla/templates/defaults/parts/menu.html,sha256=KBgXv23dCWW0XM16R5fT0_g-w_qudVfcF-CYSdwl83s,338
60
- camomilla/templates/defaults/widgets/media_select_multiple.html,sha256=k2XYou8KkPuFLnPMkPJAFJ-zGJj2Xvu6R3ZmiKa3g7Q,3727
61
- camomilla/templates_context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
- camomilla/templates_context/autodiscover.py,sha256=td7SCsqg3iNPnv1HDEDEpwWgWLjy5Zmc8Nbze1_J46I,1907
63
- camomilla/templates_context/rendering.py,sha256=GfTR45_gC7WT7zTKPVXkBDwe22uF63A-DfZUW31woAU,3194
64
- camomilla/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
- camomilla/templatetags/camomilla_filters.py,sha256=35x0-cWrRHeLhqypSLlJzEFY_fQDcRHiwZQpFgIsspE,692
66
- camomilla/templatetags/menus.py,sha256=pLFeJ1UAm3flsU9TNo2iQk4otSwZuJPr86Nf408dZ-8,862
67
- camomilla/theme/__init__.py,sha256=0q-mhm8VNgYidC6IDdFUN4eArRIb2Wf1Wf1vymdu_Fg,30
68
- camomilla/theme/admin.py,sha256=7TgNXOfIy4awtV-KkGEKsmai94qhBiykB0uJWwTZy8U,2461
69
- camomilla/theme/apps.py,sha256=ecqG8ntWdOighYOEHQOMVQpa5g_1WEzzpaaGjnOi9uA,1195
70
- camomilla/theme/static/admin/css/responsive.css,sha256=yGq6qXrr8xEVsXTnprIBgkX-sMGZrNf0Kkh-xDxf6yE,157
71
- camomilla/theme/static/admin/img/favicon.ico,sha256=qpKv_2MaGILvyihnD1Vq9Yk-ZXGkxWTW26ciMeBFMYU,15406
72
- camomilla/theme/static/admin/img/logo.svg,sha256=WBAORIV_LzEOdcpq7iU6d0Nu3omgk2gn05f6LnPjfWg,3238
73
- camomilla/theme/templates/admin/base.html,sha256=veKZ6KlnUYILeY4I2MYI18BbZMDec9MgzVzUqCHnjDc,254
74
- camomilla/theme/templates/rosetta/base.html,sha256=s9Ijf1nZx8um30R5Gk3g-w-RwFGv2QGViHufyLLiiDY,16731
75
- camomilla/utils/__init__.py,sha256=Ui7nzSh45UMMFtCGF1xFHKyJMNWflG_Nx72HAJHJHFM,100
76
- camomilla/utils/getters.py,sha256=6j18grFAZ8BC70SriycFDTQFxTnudGn0uKGA83_Rclk,798
77
- camomilla/utils/normalization.py,sha256=RDCZtjwpEEwjvfUjQl2bEWFKw7NxTzkXco72VeO2M9w,255
78
- camomilla/utils/seo.py,sha256=8p_a_TGgohenpJb094tT4mMxbn2xzW0qDILuTnjNocM,3324
79
- camomilla/utils/setters.py,sha256=LV57SM65rL1_ZQkVzk9al_Q13lndVywXLkqgfIvgS0Y,915
80
- camomilla/utils/templates.py,sha256=Lv4-5019cnM30HmdZnYWiU5gxry-eFZVAhwOofGQRDs,598
81
- camomilla/utils/translation.py,sha256=HG70ki9MTBVTdAYgi6lqqFQtNm30VTvGSYepXpyb3_Y,2477
82
- camomilla/views/__init__.py,sha256=94QuOnnbfMMb17mruO2ydUt286-8zBmDxEPWrJv5Wog,178
83
- camomilla/views/articles.py,sha256=qGxebOA5iTbGGe9PfbH40YBoDPKktH8FJongg6rh2R8,571
84
- camomilla/views/contents.py,sha256=JxvnmgeK8JEmCMLzVG8pVq2DwvmjXtgnIdsDnn74tA4,1205
85
- camomilla/views/decorators.py,sha256=hR--nTGQn2mMKDrWn-0Ildzbsvp11OfoWAtedKEzmiA,982
86
- camomilla/views/languages.py,sha256=Rt_X7s3dbDBv4dxsQ9fnav_u0TAzzo8fGKBBx3esDsg,441
87
- camomilla/views/medias.py,sha256=S4Ak4JI6XCSu3BCZx8KOotX7TBfrIU82GPXgyP3KcZA,3001
88
- camomilla/views/menus.py,sha256=o2W6oQNiB__jHw5rbGaitEENxuRk1_mRoLCKyb30qPk,3352
89
- camomilla/views/pages.py,sha256=KrBsKT0Z-rkBha8K3P6fVDt4vArQBxsc9rZ28j8XW9w,994
90
- camomilla/views/tags.py,sha256=XcYRlcBFSPPY32lt7POb6fWPJL_8HsTo5JcHcAOiOKw,479
91
- camomilla/views/users.py,sha256=_fvsKOEtep4SJLvMva2_q-HdLQT_1KlFNt4wcl3xCJk,3130
92
- camomilla/views/base/__init__.py,sha256=S7KGhVzHM7f0j8XD7cbBY5__66zvKYkphRD9cfl0O1E,222
93
- camomilla/views/mixins/__init__.py,sha256=GeRoznX3wTm6XydOltAIbx_WU7hVS70R-7jyAck0UpE,2438
94
- camomilla/views/mixins/ordering.py,sha256=mh7fqPyVCVJh84Nl2pYFQouzGxa-ANF3Wqv0pCb7OVU,4779
95
- camomilla/views/mixins/pagination.py,sha256=vUkfhqhTabeDdoiMwjeVpO6gl534EI0JMrr4TlZ8MRA,5956
96
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
- tests/test_api.py,sha256=DTXtvNNRwvZvxGKi6LyCzhpyU1OzPWGSbBUfRL3-Nck,2101
98
- tests/test_camomilla_filters.py,sha256=_W9CcwsEyewMBvnNYKk4CVqrkXxRYejle3mjiBS7hqk,1848
99
- tests/test_models.py,sha256=WJs8lxWZWn1l7X3a_QFVc8fF5LHTsI8bc3uhQe6-o-Q,684
100
- tests/test_utils.py,sha256=0tdEDBaBkyjAXpbqP0SpFcfgO56MV2TWZmk9xpjR7J0,3613
101
- django_camomilla_cms-6.0.0b15.dist-info/LICENSE,sha256=kVS7zDrNkav2hLLXbOJwVdonY2ToApTK3khyJagGQoQ,1063
102
- django_camomilla_cms-6.0.0b15.dist-info/METADATA,sha256=_k6mnVPePkm5V8-NNr4LKbft-k1_vte_CM6lEgTB32U,2390
103
- django_camomilla_cms-6.0.0b15.dist-info/WHEEL,sha256=TJ49d73sNs10F0aze1W_bTW2P_X7-F4YXOlBqoqA-jY,109
104
- django_camomilla_cms-6.0.0b15.dist-info/top_level.txt,sha256=G9VIGBmMMqC7JEckoTgXKmC6T2BR75QRkqRnngw1_lo,16
105
- django_camomilla_cms-6.0.0b15.dist-info/RECORD,,