imio.smartweb.common 1.2.26__py3-none-any.whl → 1.2.27__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,13 @@
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 plone.namedfile.utils import get_contenttype
8
+ from zope.component import adapter
4
9
  from zope.component import getUtility
10
+ from zope.interface import Interface
5
11
 
6
12
 
7
13
  class BaseCroppingProvider(object):
@@ -17,3 +23,25 @@ class BaseCroppingProvider(object):
17
23
  scales = list(allowed_sizes.keys())
18
24
  scales.remove("banner")
19
25
  return scales
26
+
27
+
28
+ @adapter(INamedImageField, Interface)
29
+ class ImageContenttypeValidator:
30
+ def __init__(self, field, value):
31
+ self.field = field
32
+ self.value = value
33
+
34
+ def __call__(self):
35
+ if self.value is None:
36
+ return
37
+ mimetype = get_image_format(self.value)
38
+
39
+ valid_mimetypes = [
40
+ "image/gif",
41
+ "image/jpeg",
42
+ "image/png",
43
+ "image/svg+xml",
44
+ "image/webp",
45
+ ]
46
+ if mimetype not in valid_mimetypes:
47
+ 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>
@@ -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" />
@@ -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.2
2
2
  Name: imio.smartweb.common
3
- Version: 1.2.26
3
+ Version: 1.2.27
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
@@ -51,6 +51,18 @@ Requires-Dist: plone.app.robotframework[debug]; extra == "test"
51
51
  Requires-Dist: plone.restapi[test]; extra == "test"
52
52
  Requires-Dist: freezegun; extra == "test"
53
53
  Requires-Dist: mock; extra == "test"
54
+ Dynamic: author
55
+ Dynamic: author-email
56
+ Dynamic: classifier
57
+ Dynamic: description
58
+ Dynamic: home-page
59
+ Dynamic: keywords
60
+ Dynamic: license
61
+ Dynamic: project-url
62
+ Dynamic: provides-extra
63
+ Dynamic: requires-dist
64
+ Dynamic: requires-python
65
+ Dynamic: summary
54
66
 
55
67
  .. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
56
68
  If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html
@@ -162,6 +174,13 @@ Changelog
162
174
  =========
163
175
 
164
176
 
177
+ 1.2.27 (2025-03-19)
178
+ -------------------
179
+
180
+ - WEB-4122 : Create adapter/validator to filter valid image mimetype in our solutions
181
+ [boulch]
182
+
183
+
165
184
  1.2.26 (2025-03-12)
166
185
  -------------------
167
186
 
@@ -218,7 +237,8 @@ Changelog
218
237
  1.2.19 (2025-01-09)
219
238
  -------------------
220
239
 
221
- - Nothing changed yet.
240
+ - WEB-4153 : Override @vocabularies endpoint to add a cache ruleset on it
241
+ [remdub]
222
242
 
223
243
 
224
244
  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.27-py3.12-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=1v1OGFJq8sW8R6bQyxQQyrQroQCT0LNm-BbavZj6KGc,1463
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
@@ -29,7 +29,7 @@ imio/smartweb/common/behaviors/topics.py,sha256=K9XkhTBxxp_nBBeQ-ovUpmOc6raXIiYq
29
29
  imio/smartweb/common/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  imio/smartweb/common/browser/collective_taxonomy_controlpanel.py,sha256=PVeXOr0cDYpg7g695wtrhsuSc6MSO0d_JGvcQUaDWRM,1908
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
@@ -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.27.dist-info/LICENSE.GPL,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
141
+ imio.smartweb.common-1.2.27.dist-info/LICENSE.rst,sha256=5dd78Fdt0e-oM2ICBrMpjHnT8vEP-jhBDF7akXni6B4,655
142
+ imio.smartweb.common-1.2.27.dist-info/METADATA,sha256=m6KkmZrY2eaI-5xgj43Atbgp2J6Hr1c4gwEhaQNnrAs,16995
143
+ imio.smartweb.common-1.2.27.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
144
+ imio.smartweb.common-1.2.27.dist-info/namespace_packages.txt,sha256=Pg8AH8t9viMMW1hJbNZvTy_n2jXG2igIYUpon5RA4Js,19
145
+ imio.smartweb.common-1.2.27.dist-info/top_level.txt,sha256=ZktC0EGzThvMTAin9_q_41rzvvfMT2FYbP8pbhSLMSA,5
146
+ imio.smartweb.common-1.2.27.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5