4
4
from pathlib import Path
5
5
6
6
import frontmatter
7
+ import orjson
7
8
8
9
from geotribu_cli .constants import (
9
10
GeotribuDefaults ,
10
11
YamlHeaderAvailableLicense ,
11
12
YamlHeaderMandatoryKeys ,
12
13
)
13
14
from geotribu_cli .json .json_client import JsonFeedClient
14
- from geotribu_cli .utils .check_image_size import get_image_dimensions_by_url
15
15
from geotribu_cli .utils .check_path import check_path
16
+ from geotribu_cli .utils .file_downloader import download_remote_file_to_local
16
17
from geotribu_cli .utils .slugger import sluggy
17
18
18
19
logger = logging .getLogger (__name__ )
@@ -49,14 +50,6 @@ def parser_header_check(
49
50
type = Path ,
50
51
help = "Chemin qui contient les presentations markdown des auteurs/autrices" ,
51
52
)
52
- subparser .add_argument (
53
- "-minw" ,
54
- "--min-width" ,
55
- dest = "min_image_width" ,
56
- default = 400 ,
57
- type = int ,
58
- help = "Largeur minimum de l'image à vérifier" ,
59
- )
60
53
subparser .add_argument (
61
54
"-maxw" ,
62
55
"--max-width" ,
@@ -65,14 +58,6 @@ def parser_header_check(
65
58
type = int ,
66
59
help = "Largeur maximum de l'image à vérifier" ,
67
60
)
68
- subparser .add_argument (
69
- "-minh" ,
70
- "--min-height" ,
71
- dest = "min_image_height" ,
72
- default = 400 ,
73
- type = int ,
74
- help = "Hauteur minimum de l'image à vérifier" ,
75
- )
76
61
subparser .add_argument (
77
62
"-maxh" ,
78
63
"--max-height" ,
@@ -81,6 +66,22 @@ def parser_header_check(
81
66
type = int ,
82
67
help = "Hauteur maximum de l'image à vérifier" ,
83
68
)
69
+ subparser .add_argument (
70
+ "-minr" ,
71
+ "--min-ratio" ,
72
+ dest = "min_image_ratio" ,
73
+ default = 1.45 ,
74
+ type = float ,
75
+ help = "Ratio largeur / hauteur minimum de l'image à vérifier" ,
76
+ )
77
+ subparser .add_argument (
78
+ "-maxr" ,
79
+ "--max-ratio" ,
80
+ dest = "max_image_ratio" ,
81
+ default = 1.55 ,
82
+ type = float ,
83
+ help = "Ratio largeur / hauteur maximum de l'image à vérifier" ,
84
+ )
84
85
subparser .add_argument (
85
86
"-r" ,
86
87
"--raise" ,
@@ -105,11 +106,64 @@ def check_author_md(author: str, folder: Path) -> bool:
105
106
return os .path .exists (p )
106
107
107
108
109
+ def download_image_sizes () -> dict :
110
+ """Downloads image dimensions file from CDN
111
+
112
+ Returns:
113
+ Dict of image dimensions
114
+ """
115
+ # download images sizes and indexes
116
+ local_dims = download_remote_file_to_local (
117
+ remote_url_to_download = f"{ defaults_settings .cdn_base_url } img/search-index.json" ,
118
+ local_file_path = defaults_settings .geotribu_working_folder .joinpath (
119
+ "img/search-index.json"
120
+ ),
121
+ expiration_rotating_hours = 24 ,
122
+ )
123
+ with local_dims .open ("rb" ) as fd :
124
+ img_dims = orjson .loads (fd .read ())
125
+ return img_dims ["images" ]
126
+
127
+
108
128
def check_image_size (
109
- image_url : str , minw : int , maxw : int , minh : int , maxh : int
129
+ image_url : str , images : dict , max_width : int , max_height : int
110
130
) -> bool :
111
- width , height = get_image_dimensions_by_url (image_url )
112
- return minw <= width <= maxw and minh <= height <= maxh
131
+ """Checks if an image respects provided max dimensions using CDN index file
132
+
133
+ Args:
134
+ image_url: HTTP url of the image to check
135
+ images: Dictionary of image dimensions (see download_image_sizes())
136
+ max_width: maximum width of the image
137
+ max_height: maximum height of the image
138
+
139
+ Returns:
140
+ True if image max dimensions are respected
141
+ False if not
142
+ """
143
+ key = image_url .replace (f"{ defaults_settings .cdn_base_url } img/" , "" )
144
+ if key not in images :
145
+ return False
146
+ width , height = images [key ]
147
+ return width <= max_width and height <= max_height
148
+
149
+
150
+ def check_image_ratio (
151
+ image_url : str , images : dict , min_ratio : int , max_ratio : int
152
+ ) -> bool :
153
+ key = image_url .replace (f"{ defaults_settings .cdn_base_url } img/" , "" )
154
+ if key not in images :
155
+ return False
156
+ width , height = images [key ]
157
+ ratio = width / height
158
+ return min_ratio <= ratio <= max_ratio
159
+
160
+
161
+ def check_image_extension (
162
+ image_url : str ,
163
+ allowed_extensions : tuple [str ] = defaults_settings .images_header_extensions ,
164
+ ) -> bool :
165
+ ext = image_url .split ("." )[- 1 ]
166
+ return ext in allowed_extensions
113
167
114
168
115
169
def get_existing_tags () -> list [str ]:
@@ -190,24 +244,54 @@ def run(args: argparse.Namespace) -> None:
190
244
# check that image size is okay
191
245
if "image" in yaml_meta :
192
246
if not yaml_meta ["image" ]:
193
- logger .error ("Pas d'URL pour l'image" )
194
- elif not check_image_size (
195
- yaml_meta ["image" ],
196
- args .min_image_width ,
197
- args .max_image_width ,
198
- args .min_image_height ,
199
- args .max_image_height ,
200
- ):
201
- msg = (
202
- f"Les dimensions de l'image ne sont pas dans l'intervalle autorisé "
203
- f"(w:{ args .min_image_width } -{ args .max_image_width } ,"
204
- f"h:{ args .min_image_height } -{ args .max_image_height } )"
205
- )
206
- logger .error (msg )
207
- if args .raise_exceptions :
208
- raise ValueError (msg )
247
+ logger .warning ("Pas d'URL pour l'image" )
209
248
else :
210
- logger .info ("Dimensions de l'image ok" )
249
+ # check image max size
250
+ if not check_image_size (
251
+ yaml_meta ["image" ],
252
+ download_image_sizes (),
253
+ args .max_image_width ,
254
+ args .max_image_height ,
255
+ ):
256
+ msg = (
257
+ f"Les dimensions de l'image ne sont pas dans l'intervalle autorisé "
258
+ f"(w:{ args .min_image_width } -{ args .max_image_width } ,"
259
+ f"h:{ args .min_image_height } -{ args .max_image_height } )"
260
+ )
261
+ logger .error (msg )
262
+ if args .raise_exceptions :
263
+ raise ValueError (msg )
264
+ else :
265
+ logger .info ("Dimensions de l'image ok" )
266
+
267
+ # check image max ratio
268
+ if not check_image_ratio (
269
+ yaml_meta ["image" ],
270
+ download_image_sizes (),
271
+ args .min_image_ratio ,
272
+ args .max_image_ratio ,
273
+ ):
274
+ msg = (
275
+ f"Le ratio largeur / hauteur de l'image n'est pas dans l'intervalle autorisé "
276
+ f"(min:{ args .min_image_ratio } ,"
277
+ f"max:{ args .max_image_ratio } )"
278
+ )
279
+ logger .error (msg )
280
+ if args .raise_exceptions :
281
+ raise ValueError (msg )
282
+ else :
283
+ logger .info ("Ratio de l'image ok" )
284
+
285
+ # check image extension
286
+ if not check_image_extension (
287
+ yaml_meta ["image" ],
288
+ ):
289
+ msg = f"L'extension de l'image n'est pas autorisée, doit être parmi : { ',' .join (defaults_settings .images_header_extensions )} "
290
+ logger .error (msg )
291
+ if args .raise_exceptions :
292
+ raise ValueError (msg )
293
+ else :
294
+ logger .info ("Extension de l'image ok" )
211
295
212
296
# check that author md file is present
213
297
if args .authors_folder :
0 commit comments