2222import pathlib
2323import re
2424import weakref
25- from typing import Any , Callable , Dict , List , Optional , Tuple , Union
25+ from typing import Any , Callable , Iterable , Optional , Tuple , Union
2626
2727import libzim .writer
2828
29- from ..constants import FRONT_ARTICLE_MIMETYPES
29+ from ..constants import (
30+ DEFAULT_DEV_ZIM_METADATA ,
31+ FRONT_ARTICLE_MIMETYPES ,
32+ MANDATORY_ZIM_METADATA_KEYS ,
33+ )
3034from ..filesystem import delete_callback , get_content_mimetype , get_file_mimetype
3135from ..types import get_mime_for_name
3236from .items import StaticItem
@@ -80,28 +84,16 @@ class Creator(libzim.writer.Creator):
8084 def __init__ (
8185 self ,
8286 filename : pathlib .Path ,
83- main_path : str = None ,
84- language : Optional [Union [str , List [str ]]] = "eng" ,
87+ main_path : str ,
8588 compression : Optional [str ] = None ,
8689 workaround_nocancel : Optional [bool ] = True ,
8790 ignore_duplicates : Optional [bool ] = False ,
88- ** metadata : Dict [str , Union [str , datetime .date , datetime .datetime ]]
8991 ):
9092 super ().__init__ (filename = filename )
93+ self ._metadata = dict ()
9194 self .can_finish = True
9295
93- if main_path :
94- self .main_path = main_path
95-
96- if language :
97- if not isinstance (language , list ):
98- language = language .split ("," )
99- self .config_indexing (True , language [0 ])
100- ld = {"Language" : "," .join (language )}
101- if metadata :
102- metadata .update (ld )
103- else :
104- metadata = ld
96+ self .set_mainpath (main_path )
10597
10698 if compression :
10799 self .config_compression (
@@ -110,26 +102,108 @@ def __init__(
110102 else compression
111103 )
112104
113- if metadata :
114- self .metadata = metadata
115-
116105 self .workaround_nocancel = workaround_nocancel
117106 self .ignore_duplicates = ignore_duplicates
118107
119108 def start (self ):
109+ if not all (
110+ [
111+ key in self ._metadata .keys () and self ._metadata .get (key , None )
112+ for key in MANDATORY_ZIM_METADATA_KEYS
113+ ]
114+ ):
115+ raise ValueError ("Mandatory metadata are not all set." )
116+
117+ for name , value in self ._metadata .items ():
118+ if value :
119+ self ._validate_metadata (name , value )
120+
120121 super ().__enter__ ()
121122
122- if getattr (self , "main_path" , None ):
123- self .set_mainpath (self .main_path )
123+ self .add_illustration (48 , self ._metadata ["Illustration_48x48@1" ])
124+ del self ._metadata ["Illustration_48x48@1" ]
125+ for name , value in self ._metadata .items ():
126+ if value :
127+ self .add_metadata (name , value )
124128
125- if getattr (self , "metadata" , None ):
126- self .update_metadata (** self .metadata )
127129 return self
128130
129- def update_metadata (self , ** kwargs ):
130- if kwargs :
131- for name , value in kwargs .items ():
132- self .add_metadata (name , value )
131+ def _validate_metadata (self , name , value ):
132+ if name == "Counter" :
133+ raise ValueError ("You do not need to set Counter." )
134+
135+ if name == "Description" and len (value ) > 80 :
136+ raise ValueError ("Description is too long." )
137+
138+ if name == "LongDescription" and len (value ) > 4000 :
139+ raise ValueError ("LongDescription is too long." )
140+
141+ def config_metadata (
142+ self ,
143+ * ,
144+ Name : str ,
145+ Language : str ,
146+ Title : str ,
147+ Description : str ,
148+ LongDescription : Optional [str ] = None ,
149+ Creator : str ,
150+ Publisher : str ,
151+ Date : Union [datetime .datetime , datetime .date , str ],
152+ Illustration_48x48_at_1 : bytes ,
153+ Tags : Optional [Union [Iterable [str ], str ]] = None ,
154+ Scraper : Optional [str ] = None ,
155+ Flavour : Optional [str ] = None ,
156+ Source : Optional [str ] = None ,
157+ License : Optional [str ] = None ,
158+ Relation : Optional [str ] = None ,
159+ ** extras : str ,
160+ ):
161+ """
162+ A chaining functions which configures the metadata of the Creator class.
163+ You must set all mandatory metadata in this phase.
164+
165+ Parameters:
166+ check out: https://wiki.openzim.org/wiki/Metadata
167+ all the extra metadata must be plain text.
168+
169+ Returns:
170+ Self
171+ """
172+ self ._metadata .update (
173+ {
174+ "Name" : Name ,
175+ "Title" : Title ,
176+ "Creator" : Creator ,
177+ "Publisher" : Publisher ,
178+ "Date" : Date ,
179+ "Description" : Description ,
180+ "Language" : Language ,
181+ "License" : License ,
182+ "LongDescription" : LongDescription ,
183+ "Tags" : Tags ,
184+ "Relation" : Relation ,
185+ "Flavour" : Flavour ,
186+ "Source" : Source ,
187+ "Scraper" : Scraper ,
188+ "Illustration_48x48@1" : Illustration_48x48_at_1 ,
189+ }
190+ )
191+ self ._metadata .update (extras )
192+ language = self ._metadata .get ("Language" , "" ).split ("," )
193+ self .config_indexing (True , language [0 ])
194+
195+ return self
196+
197+ def config_dev_metadata (self , ** extras : str ):
198+ """
199+ A Test function. It will set the default test metadata for a Creator instance.
200+
201+ Returns:
202+ Self
203+ """
204+ devel_default_metadata = DEFAULT_DEV_ZIM_METADATA .copy ()
205+ devel_default_metadata .update (extras )
206+ return self .config_metadata (** devel_default_metadata )
133207
134208 def add_item_for (
135209 self ,
@@ -254,9 +328,6 @@ def add_redirect(
254328 self .can_finish = False # pragma: no cover
255329 raise
256330
257- def add_default_illustration (self , content : bytes ):
258- self .add_illustration (48 , content )
259-
260331 def finish (self , exc_type = None , exc_val = None , exc_tb = None ):
261332 """Triggers finalization of ZIM creation and create final ZIM file."""
262333 if not getattr (self , "can_finish" , False ):
0 commit comments