imio.smartweb.common 1.2.26__py3-none-any.whl → 1.2.28__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.
@@ -1,7 +1,12 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ from imio.smartweb.common.utils import get_image_format
3
4
  from plone.namedfile.interfaces import IAvailableSizes
5
+ from plone.namedfile.interfaces import INamedImageField
6
+ from plone.namedfile.field import InvalidImageFile
7
+ from zope.component import adapter
4
8
  from zope.component import getUtility
9
+ from zope.interface import Interface
5
10
 
6
11
 
7
12
  class BaseCroppingProvider(object):
@@ -17,3 +22,25 @@ class BaseCroppingProvider(object):
17
22
  scales = list(allowed_sizes.keys())
18
23
  scales.remove("banner")
19
24
  return scales
25
+
26
+
27
+ @adapter(INamedImageField, Interface)
28
+ class ImageContenttypeValidator:
29
+ def __init__(self, field, value):
30
+ self.field = field
31
+ self.value = value
32
+
33
+ def __call__(self):
34
+ if self.value is None:
35
+ return
36
+ mimetype = get_image_format(self.value)
37
+
38
+ valid_mimetypes = [
39
+ "image/gif",
40
+ "image/jpeg",
41
+ "image/png",
42
+ "image/svg+xml",
43
+ "image/webp",
44
+ ]
45
+ if mimetype not in valid_mimetypes:
46
+ raise InvalidImageFile(mimetype, self.field.__name__)
@@ -7,4 +7,10 @@
7
7
  factory=".adapters.BaseCroppingProvider"
8
8
  />
9
9
 
10
+ <adapter
11
+ factory=".adapters.ImageContenttypeValidator"
12
+ provides="plone.namedfile.field.IPluggableImageFieldValidation"
13
+ name="smartweb_image_contenttype"
14
+ />
15
+
10
16
  </configure>
@@ -2,11 +2,8 @@
2
2
 
3
3
  from collective.taxonomy.interfaces import ITaxonomy
4
4
  from collective.taxonomy.jsonimpl import EditTaxonomyData as baseEditTaxonomyData
5
- from imio.smartweb.locales import SmartwebMessageFactory as _
6
5
  from plone import api
7
6
  from zope.component import queryUtility
8
- from zope.component import queryUtility
9
- from plone import api
10
7
  from Products.Five import BrowserView
11
8
 
12
9
 
@@ -51,11 +51,10 @@ class SmartwebCroppingImageScalingFactory(CroppingImageScalingFactory):
51
51
  ):
52
52
  storage = Storage(self.context)
53
53
  self.box = storage.read(fieldname, scale)
54
- if scale is not None:
55
- if "portrait" in scale or "paysage" in scale or "carre" in scale:
56
- orientation = scale.split("_")[0]
57
- # take cropping box from "affiche" scale
58
- self.box = storage.read(fieldname, f"{orientation}_affiche")
54
+ if scale and ("portrait" in scale or "paysage" in scale or "carre" in scale):
55
+ orientation = scale.split("_")[0]
56
+ # take cropping box from "affiche" scale
57
+ self.box = storage.read(fieldname, f"{orientation}_affiche")
59
58
  if self.box:
60
59
  mode = "contain"
61
60
  else:
@@ -1,6 +1,7 @@
1
1
  <configure
2
2
  xmlns="http://namespaces.zope.org/zope">
3
3
 
4
+ <include package="z3c.unconfigure" file="meta.zcml" />
4
5
  <include package="collective.taxonomy" />
5
6
  <include package="eea.facetednavigation" />
6
7
  <include package="eea.facetednavigation" file="meta.zcml" />
@@ -2,9 +2,11 @@
2
2
 
3
3
  from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING
4
4
  from imio.smartweb.common.widgets.select import TranslatedAjaxSelectWidget
5
+ from importlib.metadata import version
5
6
  from plone.api import portal as portal_api
6
7
  from zope.publisher.browser import TestRequest
7
8
 
9
+
8
10
  import mock
9
11
  import unittest
10
12
 
@@ -20,42 +22,99 @@ class TestVocabulary(unittest.TestCase):
20
22
  portal_api.get_current_language = mock.Mock(return_value="fr")
21
23
  widget = TranslatedAjaxSelectWidget(self.request)
22
24
  widget.update()
23
- self.assertEqual(
24
- {
25
- "name": None,
26
- "value": "",
27
- "pattern": "select2",
28
- "pattern_options": {"separator": ";"},
29
- },
30
- widget._base_args(),
31
- )
32
-
33
- widget.vocabulary = "imio.smartweb.vocabulary.Topics"
34
- self.assertEqual(
35
- widget._base_args(),
36
- {
37
- "name": None,
38
- "value": "",
39
- "pattern": "select2",
40
- "pattern_options": {
41
- "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
42
- "separator": ";",
43
- },
44
- },
45
- )
46
- widget.value = "entertainment"
47
- self.assertEqual(
48
- widget._base_args(),
49
- {
50
- "name": None,
51
- "value": "entertainment",
52
- "pattern": "select2",
53
- "pattern_options": {
54
- "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
55
- "initialValues": {
56
- "entertainment": "Activités et divertissement",
25
+ # __import__("pdb").set_trace()
26
+ if version("plone.app.z3cform") < "4.4.0":
27
+ self.assertEqual(
28
+ {
29
+ "name": None,
30
+ "value": "",
31
+ "pattern": "select2",
32
+ "pattern_options": {"separator": ";"},
33
+ },
34
+ widget._base_args(),
35
+ )
36
+ widget.vocabulary = "imio.smartweb.vocabulary.Topics"
37
+ self.assertEqual(
38
+ widget._base_args(),
39
+ {
40
+ "name": None,
41
+ "value": "",
42
+ "pattern": "select2",
43
+ "pattern_options": {
44
+ "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
45
+ "separator": ";",
57
46
  },
58
- "separator": ";",
59
47
  },
60
- },
61
- )
48
+ )
49
+ widget.value = "entertainment"
50
+ self.assertEqual(
51
+ widget._base_args(),
52
+ {
53
+ "name": None,
54
+ "value": "entertainment",
55
+ "pattern": "select2",
56
+ "pattern_options": {
57
+ "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
58
+ "initialValues": {
59
+ "entertainment": "Activités et divertissement",
60
+ },
61
+ "separator": ";",
62
+ },
63
+ },
64
+ )
65
+ else:
66
+ # _base.args has been removed
67
+ # see https://github.com/plone/plone.app.z3cform/commit/5de30e9b117885859680dfe3861f134a667cea9c
68
+ self.assertEqual(
69
+ {
70
+ "name": None,
71
+ "value": None,
72
+ "pattern": "select2",
73
+ "pattern_options": {"separator": ";"},
74
+ },
75
+ {
76
+ "name": widget.name,
77
+ "value": widget.value,
78
+ "pattern": widget.pattern,
79
+ "pattern_options": widget.get_pattern_options(),
80
+ },
81
+ )
82
+ widget.vocabulary = "imio.smartweb.vocabulary.Topics"
83
+ self.assertEqual(
84
+ {
85
+ "name": None,
86
+ "value": None,
87
+ "pattern": "select2",
88
+ "pattern_options": {
89
+ "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
90
+ "separator": ";",
91
+ },
92
+ },
93
+ {
94
+ "name": widget.name,
95
+ "value": widget.value,
96
+ "pattern": widget.pattern,
97
+ "pattern_options": widget.get_pattern_options(),
98
+ },
99
+ )
100
+ widget.value = "entertainment"
101
+ self.assertEqual(
102
+ {
103
+ "name": None,
104
+ "value": "entertainment",
105
+ "pattern": "select2",
106
+ "pattern_options": {
107
+ "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics",
108
+ "initialValues": {
109
+ "entertainment": "Activités et divertissement",
110
+ },
111
+ "separator": ";",
112
+ },
113
+ },
114
+ {
115
+ "name": widget.name,
116
+ "value": widget.value,
117
+ "pattern": widget.pattern,
118
+ "pattern_options": widget.get_pattern_options(),
119
+ },
120
+ )
@@ -1,9 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  from Acquisition import aq_parent
4
+ from io import BytesIO
4
5
  from imio.smartweb.common.config import TRANSLATED_VOCABULARIES
5
6
  from imio.smartweb.common.interfaces import ICropping
6
7
  from imio.smartweb.locales import SmartwebMessageFactory as _
8
+ from PIL import Image
7
9
  from plone import api
8
10
  from plone.app.imagecropping.storage import Storage
9
11
  from plone.dexterity.utils import iterSchemata
@@ -203,3 +205,27 @@ def get_parent_of_type(context, content_type):
203
205
  return parent
204
206
  parent = aq_parent(parent)
205
207
  return None
208
+
209
+
210
+ def _get_pil_mimetype(pil_image):
211
+ """Retourne le MIME type d'une image PIL."""
212
+ format_to_mime = {
213
+ "JPEG": "image/jpeg",
214
+ "PNG": "image/png",
215
+ "GIF": "image/gif",
216
+ "BMP": "image/bmp",
217
+ "TIFF": "image/tiff",
218
+ "WEBP": "image/webp",
219
+ "SVG": "image/svg+xml",
220
+ }
221
+ return format_to_mime.get(pil_image.format, "application/octet-stream")
222
+
223
+
224
+ def get_image_format(named_blob_image):
225
+ """Détecte le format d'une image à partir de son contenu binaire."""
226
+ if named_blob_image and named_blob_image.data:
227
+ try:
228
+ with Image.open(BytesIO(named_blob_image.data)) as img:
229
+ return _get_pil_mimetype(img)
230
+ except Exception:
231
+ return None
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: imio.smartweb.common
3
- Version: 1.2.26
3
+ Version: 1.2.28
4
4
  Summary: Common utilities, vocabularies, taxonomies for imio.smartweb & co products
5
5
  Home-page: https://github.com/imio/imio.smartweb.common
6
6
  Author: iMio
@@ -15,10 +15,13 @@ Classifier: Environment :: Web Environment
15
15
  Classifier: Framework :: Plone
16
16
  Classifier: Framework :: Plone :: Addon
17
17
  Classifier: Framework :: Plone :: 6.0
18
+ Classifier: Framework :: Plone :: 6.1
18
19
  Classifier: Programming Language :: Python
19
20
  Classifier: Programming Language :: Python :: 3
20
21
  Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
21
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
22
25
  Classifier: Operating System :: OS Independent
23
26
  Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
24
27
  Requires-Python: >=3.10
@@ -51,6 +54,19 @@ Requires-Dist: plone.app.robotframework[debug]; extra == "test"
51
54
  Requires-Dist: plone.restapi[test]; extra == "test"
52
55
  Requires-Dist: freezegun; extra == "test"
53
56
  Requires-Dist: mock; extra == "test"
57
+ Dynamic: author
58
+ Dynamic: author-email
59
+ Dynamic: classifier
60
+ Dynamic: description
61
+ Dynamic: home-page
62
+ Dynamic: keywords
63
+ Dynamic: license
64
+ Dynamic: license-file
65
+ Dynamic: project-url
66
+ Dynamic: provides-extra
67
+ Dynamic: requires-dist
68
+ Dynamic: requires-python
69
+ Dynamic: summary
54
70
 
55
71
  .. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
56
72
  If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html
@@ -162,6 +178,23 @@ Changelog
162
178
  =========
163
179
 
164
180
 
181
+ 1.2.28 (2025-04-30)
182
+ -------------------
183
+
184
+ - Upgrade dev environment to Plone 6.1-latest
185
+ [remdub]
186
+
187
+ - Add tests for Plone 6.1-latest and add Python 3.13
188
+ [remdub]
189
+
190
+
191
+ 1.2.27 (2025-03-19)
192
+ -------------------
193
+
194
+ - WEB-4122 : Create adapter/validator to filter valid image mimetype in our solutions
195
+ [boulch]
196
+
197
+
165
198
  1.2.26 (2025-03-12)
166
199
  -------------------
167
200
 
@@ -218,7 +251,8 @@ Changelog
218
251
  1.2.19 (2025-01-09)
219
252
  -------------------
220
253
 
221
- - Nothing changed yet.
254
+ - WEB-4153 : Override @vocabularies endpoint to add a cache ruleset on it
255
+ [remdub]
222
256
 
223
257
 
224
258
  1.2.18 (2024-07-01)
@@ -1,11 +1,11 @@
1
- imio.smartweb.common-1.2.26-py3.8-nspkg.pth,sha256=XZ3YhlzwpUCC8tXtelHRqxVxo3NWomIiMsUfUshrbeE,1011
1
+ imio.smartweb.common-1.2.28-py3.13-nspkg.pth,sha256=XZ3YhlzwpUCC8tXtelHRqxVxo3NWomIiMsUfUshrbeE,1011
2
2
  imio/smartweb/common/__init__.py,sha256=Na9XBfEQUMrm2c5jbqQgwWeg40ih0aXVG1vT8NeAjMQ,2709
3
- imio/smartweb/common/adapters.py,sha256=rLlObjqZm3hs2hgUT-LmJytwhT-E1rTvbpIi0mmKQqY,610
4
- imio/smartweb/common/adapters.zcml,sha256=ndYNj0J_BFfVpX_7JhY2asSwLzXG-WmjLdfwL9hX_No,254
3
+ imio/smartweb/common/adapters.py,sha256=BjnzwhRhSYXziKUzmNTRBOXqDv4k8C8kfmwqZE7r1yU,1413
4
+ imio/smartweb/common/adapters.zcml,sha256=VO3luZDtRL9FIIEghxPrqpx8paZF3m6MGEy-8kF1sOQ,437
5
5
  imio/smartweb/common/caching.py,sha256=aN7gX9rT63fnmUuZnx82Mbu3ghjJUeOiLvLEp9OiFm4,895
6
6
  imio/smartweb/common/caching_overrides.zcml,sha256=ysa5DgVGzO1Fp22d9Wg-vNyLlqfRR77WBV-7L6j0Hpo,526
7
7
  imio/smartweb/common/config.py,sha256=imgOo0_BBIbXGFNvBnhPReLOSY4JqIOH_QCAl0j0XGI,435
8
- imio/smartweb/common/configure.zcml,sha256=IQMv1giqgunu55osPlnVAq2MwM3FjJOGPgrxuO1e_74,894
8
+ imio/smartweb/common/configure.zcml,sha256=5TiJ-6jxqeuc8ab9TWDP7B37t6TWsxb8BMQLQKqIwO4,951
9
9
  imio/smartweb/common/contact_utils.py,sha256=Pr-Nhz9MRnfirZ7RbmF5JZw9fX4gWa0dWkvJlQBiDKY,11341
10
10
  imio/smartweb/common/indexers.py,sha256=TvvKglWI0JM5_jwetlpvqcjwkid_2PhaCZGKZV4sD34,1148
11
11
  imio/smartweb/common/indexers.zcml,sha256=End1fDod99sr0xw8PaakgeTAZYq-HLOGw3MNA8K_CTs,324
@@ -19,7 +19,7 @@ imio/smartweb/common/subscribers.py,sha256=pbPQJ1YrfPlYCfxLAJ5sOy_5OToAfs2egX68z
19
19
  imio/smartweb/common/subscribers.zcml,sha256=8v2lqNNVAHlrh2G3jtjVgr3Asrw8WJLS9jSX5U6juFg,971
20
20
  imio/smartweb/common/testing.py,sha256=GKlYMHJUSxZFVX0o_R_c_Au1VYlkd-GjykQqfONHv7I,1985
21
21
  imio/smartweb/common/testing.zcml,sha256=7N-ALtklyWeLSzZmlxN2Tp-aZe_3An--w_6BGl1991E,172
22
- imio/smartweb/common/utils.py,sha256=S4Kygk-ukllxNdNOLX6D0Zl5SDVoWaS2JqV7MbGuBkA,6952
22
+ imio/smartweb/common/utils.py,sha256=sSq72k41ELmlW5jc7JkRgKLXKQbbd68-87JtEDHmTCQ,7738
23
23
  imio/smartweb/common/vocabularies.py,sha256=QRIOWLOALzZDM92o1iUTWgDBBcrdd9BYz7miNjpYCDA,3835
24
24
  imio/smartweb/common/vocabularies.zcml,sha256=iFJer5q3wabBp_EZivPPVUqI1_9w5P_Ft1RGJB5Yqxs,940
25
25
  imio/smartweb/common/behaviors/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
@@ -27,9 +27,9 @@ imio/smartweb/common/behaviors/configure.zcml,sha256=RfGH8DIybHpxxe2HUsjH2QKSiWY
27
27
  imio/smartweb/common/behaviors/iam.py,sha256=17ON7M6FHXOM_8NOHT_QnJJuAIs4diWCrguHP6Lh5oA,825
28
28
  imio/smartweb/common/behaviors/topics.py,sha256=K9XkhTBxxp_nBBeQ-ovUpmOc6raXIiYqmzJtlKVdhbI,863
29
29
  imio/smartweb/common/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- imio/smartweb/common/browser/collective_taxonomy_controlpanel.py,sha256=PVeXOr0cDYpg7g695wtrhsuSc6MSO0d_JGvcQUaDWRM,1908
30
+ imio/smartweb/common/browser/collective_taxonomy_controlpanel.py,sha256=vHSd1rSlfK1SI4o9BIYIWIsh6S9QuHgkSZokoKEDFGM,1784
31
31
  imio/smartweb/common/browser/configure.zcml,sha256=agEY6fPCePV2UnzvVMUF-Wft0nU6HaHnMwv_lCk4_dQ,3534
32
- imio/smartweb/common/browser/cropping.py,sha256=7xkTvs_0qUo9tC2tAIj77ZQn2RClKOgAwE0L6WhGGxg,2720
32
+ imio/smartweb/common/browser/cropping.py,sha256=MjnXr-sfzjbJnscuX6rfyyEiwTmH9Pmu0sh_WirNnUk,2686
33
33
  imio/smartweb/common/browser/description.pt,sha256=ZXKpsMQDJGC0dxVUg5v1W6LsG1_OWuYuWevZuF-Zn2Y,151
34
34
  imio/smartweb/common/browser/description.py,sha256=BRpHkVzwyeM-SUzkEbtHn2fm8pQREtcHIW7feoQlBPQ,517
35
35
  imio/smartweb/common/browser/edit_taxonomy_data.pt,sha256=PWM7SGaWAkrPZ7jxVRBry8ed5_1PD7fucCMgmMCx9tg,6937
@@ -99,7 +99,7 @@ imio/smartweb/common/tests/test_utils.py,sha256=S4QrNVvkHv3Oxp45fWQ65dmGsk7POgUn
99
99
  imio/smartweb/common/tests/test_viewlets.py,sha256=NVEZWEmYo4K_-81Q6w-JTx2nT_3NBcJCl3946MAUnhU,1738
100
100
  imio/smartweb/common/tests/test_vocabularies.py,sha256=C-78USTvOHljuMSLkNb9onSRxLEJmBQLpktetAO74RE,848
101
101
  imio/smartweb/common/tests/test_vocabulary.py,sha256=4E5i5znt_hLhnnRay1iBaOZRmQyFJs8-OMdPm4iSGSg,1638
102
- imio/smartweb/common/tests/test_widgets.py,sha256=FQ2FphLRZQ1yuMngQ6cu4LxDaLVTAg1VyIUILV0XRUI,2009
102
+ imio/smartweb/common/tests/test_widgets.py,sha256=Yglnzt5kG7mBoaA2r-fr9vOTuXkM0w-KDTooXMCnqpA,4515
103
103
  imio/smartweb/common/tests/resources/image.png,sha256=GBnPJt2ALEefn8GJAY1Lh8o9L6l6G77GJSyS0uveHvQ,1185
104
104
  imio/smartweb/common/tests/resources/image_1400x800.png,sha256=Iy3bWGH4NBlgYC5BolZiNYFTKmCm0_I9MZDZo4sw_V4,30604
105
105
  imio/smartweb/common/tests/resources/image_1800x700.png,sha256=aQcMisSFQO78c6QX4mO7qIfDb9SDRmfzTuPjxMJ_0HM,32643
@@ -137,10 +137,10 @@ imio/smartweb/common/viewlets/skip_to_content.pt,sha256=-tb3HkoGG8H_gBZL4eiJrPcW
137
137
  imio/smartweb/common/viewlets/skip_to_content.py,sha256=wm22NUf8Qh5uzz8p4vkLCdFNiDv9zUGAueRyXAIXQDo,496
138
138
  imio/smartweb/common/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
139
  imio/smartweb/common/widgets/select.py,sha256=vfVdbecH7qDfJvWV6TfkpqocD6AA5G4yIq7XqSOuVNw,1142
140
- imio.smartweb.common-1.2.26.dist-info/LICENSE.GPL,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
141
- imio.smartweb.common-1.2.26.dist-info/LICENSE.rst,sha256=5dd78Fdt0e-oM2ICBrMpjHnT8vEP-jhBDF7akXni6B4,655
142
- imio.smartweb.common-1.2.26.dist-info/METADATA,sha256=SHbP0lM5sL-Ir2Ulg7dO7MWyI2AQAHstbGnilpO8jfM,16550
143
- imio.smartweb.common-1.2.26.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
144
- imio.smartweb.common-1.2.26.dist-info/namespace_packages.txt,sha256=Pg8AH8t9viMMW1hJbNZvTy_n2jXG2igIYUpon5RA4Js,19
145
- imio.smartweb.common-1.2.26.dist-info/top_level.txt,sha256=ZktC0EGzThvMTAin9_q_41rzvvfMT2FYbP8pbhSLMSA,5
146
- imio.smartweb.common-1.2.26.dist-info/RECORD,,
140
+ imio_smartweb_common-1.2.28.dist-info/licenses/LICENSE.GPL,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
141
+ imio_smartweb_common-1.2.28.dist-info/licenses/LICENSE.rst,sha256=5dd78Fdt0e-oM2ICBrMpjHnT8vEP-jhBDF7akXni6B4,655
142
+ imio_smartweb_common-1.2.28.dist-info/METADATA,sha256=9ZJX-fjl9O8XVGQrpj-BqWpBpWs8U50pMAVbVQQAilQ,17322
143
+ imio_smartweb_common-1.2.28.dist-info/WHEEL,sha256=ooBFpIzZCPdw3uqIQsOo4qqbA4ZRPxHnOH7peeONza0,91
144
+ imio_smartweb_common-1.2.28.dist-info/namespace_packages.txt,sha256=Pg8AH8t9viMMW1hJbNZvTy_n2jXG2igIYUpon5RA4Js,19
145
+ imio_smartweb_common-1.2.28.dist-info/top_level.txt,sha256=ZktC0EGzThvMTAin9_q_41rzvvfMT2FYbP8pbhSLMSA,5
146
+ imio_smartweb_common-1.2.28.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (80.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5