|
22 | 22 | import pathlib |
23 | 23 | import re |
24 | 24 | import weakref |
25 | | -from collections.abc import Iterable as IterableT |
26 | 25 | from typing import Any, Callable, Iterable, Optional, Tuple, Union |
27 | 26 |
|
28 | 27 | import libzim.writer |
29 | 28 |
|
30 | 29 | from ..constants import ( |
31 | 30 | DEFAULT_DEV_ZIM_METADATA, |
32 | 31 | FRONT_ARTICLE_MIMETYPES, |
33 | | - ILLUSTRATIONS_METADATA_RE, |
34 | 32 | MANDATORY_ZIM_METADATA_KEYS, |
35 | | - MAXIMUM_DESCRIPTION_METADATA_LENGTH, |
36 | | - MAXIMUM_LONG_DESCRIPTION_METADATA_LENGTH, |
37 | 33 | ) |
38 | 34 | from ..filesystem import delete_callback, get_content_mimetype, get_file_mimetype |
39 | 35 | from ..i18n import is_valid_iso_639_3 |
40 | | -from ..image.probing import is_valid_image |
41 | 36 | from ..types import get_mime_for_name |
42 | 37 | from .items import StaticItem |
| 38 | +from .metadata import ( |
| 39 | + validate_counter, |
| 40 | + validate_date, |
| 41 | + validate_description, |
| 42 | + validate_illustrations, |
| 43 | + validate_language, |
| 44 | + validate_longdescription, |
| 45 | + validate_required_values, |
| 46 | + validate_standard_str_types, |
| 47 | + validate_tags, |
| 48 | + validate_title, |
| 49 | +) |
43 | 50 |
|
44 | 51 | DUPLICATE_EXC_STR = re.compile( |
45 | 52 | r"^Impossible to add(.+)" |
@@ -155,78 +162,17 @@ def validate_metadata( |
155 | 162 | Also enforces recommendations |
156 | 163 | See https://wiki.openzim.org/wiki/Metadata""" |
157 | 164 |
|
158 | | - # spec doesnt require any value but empty strings are not useful |
159 | | - if name in MANDATORY_ZIM_METADATA_KEYS and not value: |
160 | | - raise ValueError(f"Missing value for {name}") |
161 | | - |
162 | | - # most require/standard and al |
163 | | - if name in ( |
164 | | - "Name", |
165 | | - "Title", |
166 | | - "Creator", |
167 | | - "Publisher", |
168 | | - "Description", |
169 | | - "LongDescription", |
170 | | - "License", |
171 | | - "Relation", |
172 | | - "Relation", |
173 | | - "Flavour", |
174 | | - "Source", |
175 | | - "Scraper", |
176 | | - ) and not isinstance(value, str): |
177 | | - raise ValueError(f"Invalid type for {name}") |
178 | | - |
179 | | - if name == "Title" and len(value) > 30: |
180 | | - raise ValueError(f"{name} is too long.") |
181 | | - |
182 | | - if name == "Date": |
183 | | - if not isinstance(value, (datetime.datetime, datetime.date, str)): |
184 | | - raise ValueError(f"Invalid type for {name}.") |
185 | | - elif isinstance(value, str): |
186 | | - match = re.match( |
187 | | - r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", value |
188 | | - ) |
189 | | - try: |
190 | | - datetime.date(**{k: int(v) for k, v in match.groupdict().items()}) |
191 | | - except Exception as exc: |
192 | | - raise ValueError(f"Invalid {name} format: {exc}") |
193 | | - |
194 | | - if name == "Language" and not is_valid_iso_639_3(value): |
195 | | - raise ValueError(f"{value} is not ISO-639-3.") |
196 | | - |
197 | | - if name == "Counter": |
198 | | - raise ValueError(f"{name} cannot be set. libzim sets it.") |
199 | | - |
200 | | - if name == "Description" and len(value) > MAXIMUM_DESCRIPTION_METADATA_LENGTH: |
201 | | - raise ValueError(f"{name} is too long.") |
202 | | - |
203 | | - if ( |
204 | | - name == "LongDescription" |
205 | | - and len(value) > MAXIMUM_LONG_DESCRIPTION_METADATA_LENGTH |
206 | | - ): |
207 | | - raise ValueError(f"{name} is too long.") |
208 | | - |
209 | | - if name == "Tags" and ( |
210 | | - not isinstance(value, IterableT) |
211 | | - or not all([isinstance(tag, str) for tag in value]) |
212 | | - ): |
213 | | - raise ValueError(f"Invalid type(s) for {name}") |
214 | | - |
215 | | - if name.startswith("Illustration_"): |
216 | | - match = ILLUSTRATIONS_METADATA_RE.match(name) |
217 | | - if match and not is_valid_image( |
218 | | - image=value, |
219 | | - imformat="PNG", |
220 | | - size=( |
221 | | - int(match.groupdict()["width"]), |
222 | | - int(match.groupdict()["height"]), |
223 | | - ), |
224 | | - ): |
225 | | - raise ValueError( |
226 | | - f"{name} is not a " |
227 | | - f"{match.groupdict()['width']}x{match.groupdict()['height']} " |
228 | | - "PNG Image" |
229 | | - ) |
| 165 | + validate_required_values(name, value) |
| 166 | + validate_standard_str_types(name, value) |
| 167 | + |
| 168 | + validate_title(name, value) |
| 169 | + validate_date(name, value) |
| 170 | + validate_language(name, value) |
| 171 | + validate_counter(name, value) |
| 172 | + validate_description(name, value) |
| 173 | + validate_longdescription(name, value) |
| 174 | + validate_tags(name, value) |
| 175 | + validate_illustrations(name, value) |
230 | 176 |
|
231 | 177 | def add_metadata( |
232 | 178 | self, |
|
0 commit comments