3232_FileBlock = UnoImage | UnoVideo | UnoAudio | UnoPDF
3333
3434
35+ @beartype
36+ def _block_without_children (
37+ * ,
38+ block : ParentBlock ,
39+ ) -> ParentBlock :
40+ """
41+ Return a copy of a block without children.
42+ """
43+ serialized_block_without_children = block .obj_ref .serialize_for_api ()
44+
45+ # Delete the ID, else the block will have the children from Notion.
46+ if "id" in serialized_block_without_children :
47+ del serialized_block_without_children ["id" ]
48+
49+ block_without_children = Block .wrap_obj_ref (
50+ UnoObjAPIBlock .model_validate (obj = serialized_block_without_children )
51+ )
52+ assert isinstance (block_without_children , ParentBlock )
53+ assert not block_without_children .children
54+ return block_without_children
55+
56+
3557@beartype
3658@cache
3759def _calculate_file_sha (* , file_path : Path ) -> str :
@@ -107,18 +129,17 @@ def _is_existing_equivalent(
107129 parsed = urlparse (url = local_block .url )
108130 if parsed .scheme == "file" :
109131 assert isinstance (existing_page_block , _FILE_BLOCK_TYPES )
110- if not isinstance (existing_page_block .file_info , NotionFile ):
111- return False
112-
113- if (
114- existing_page_block .file_info .name
115- != local_block .file_info .name
116- ):
117- return False
118132
119133 if (
120- existing_page_block .file_info .caption
121- != local_block .file_info .caption
134+ not isinstance (existing_page_block .file_info , NotionFile )
135+ or (
136+ existing_page_block .file_info .name
137+ != local_block .file_info .name
138+ )
139+ or (
140+ existing_page_block .file_info .caption
141+ != local_block .file_info .caption
142+ )
122143 ):
123144 return False
124145
@@ -128,6 +149,33 @@ def _is_existing_equivalent(
128149 file_url = existing_page_block .file_info .url ,
129150 )
130151 return local_file_sha == existing_file_sha
152+ elif isinstance (existing_page_block , ParentBlock ):
153+ assert isinstance (local_block , ParentBlock )
154+ existing_page_block_without_children = _block_without_children (
155+ block = existing_page_block ,
156+ )
157+
158+ local_block_without_children = _block_without_children (
159+ block = local_block ,
160+ )
161+
162+ if (
163+ existing_page_block_without_children
164+ != local_block_without_children
165+ ) or (len (existing_page_block .children ) != len (local_block .children )):
166+ return False
167+
168+ return all (
169+ _is_existing_equivalent (
170+ existing_page_block = existing_child_block ,
171+ local_block = local_child_block ,
172+ )
173+ for (existing_child_block , local_child_block ) in zip (
174+ existing_page_block .children ,
175+ local_block .children ,
176+ strict = False ,
177+ )
178+ )
131179
132180 return existing_page_block == local_block
133181
@@ -171,14 +219,7 @@ def _block_with_uploaded_file(
171219 _block_with_uploaded_file (block = child_block , session = session )
172220 for child_block in block .children
173221 ]
174- serialized_block_without_children = block .obj_ref .serialize_for_api ()
175- block = Block .wrap_obj_ref (
176- UnoObjAPIBlock .model_validate (
177- obj = serialized_block_without_children
178- )
179- )
180- assert isinstance (block , ParentBlock )
181- assert not block .children
222+ block = _block_without_children (block = block )
182223 block .append (blocks = new_child_blocks )
183224
184225 return block
0 commit comments