99from enum import Enum
1010from functools import cache
1111from pathlib import Path
12- from typing import TYPE_CHECKING , Any
12+ from typing import TYPE_CHECKING
1313from urllib .parse import urlparse
1414from urllib .request import url2pathname
1515
1919from ultimate_notion import Emoji , NotionFile , Session
2020from ultimate_notion .blocks import PDF as UnoPDF # noqa: N811
2121from ultimate_notion .blocks import Audio as UnoAudio
22- from ultimate_notion .blocks import Block
22+ from ultimate_notion .blocks import Block , ParentBlock
2323from ultimate_notion .blocks import Image as UnoImage
2424from ultimate_notion .blocks import Video as UnoVideo
2525from ultimate_notion .obj_api .blocks import Block as UnoObjAPIBlock
@@ -133,16 +133,14 @@ def _is_existing_equivalent(
133133
134134
135135@beartype
136- def _block_from_details (
136+ def _block_with_uploaded_file (
137137 * ,
138- details : dict [ str , Any ] ,
138+ block : Block ,
139139 session : Session ,
140140) -> Block :
141141 """
142- Create a Block from a serialized block details .
142+ Replace a file block with an uploaded file block .
143143 """
144- block = Block .wrap_obj_ref (UnoObjAPIBlock .model_validate (obj = details ))
145-
146144 if isinstance (block , _FILE_BLOCK_TYPES ):
147145 parsed = urlparse (url = block .url )
148146 if parsed .scheme == "file" :
@@ -166,7 +164,22 @@ def _block_from_details(
166164
167165 uploaded_file .wait_until_uploaded ()
168166
169- return block .__class__ (file = uploaded_file , caption = block .caption )
167+ block = block .__class__ (file = uploaded_file , caption = block .caption )
168+
169+ elif isinstance (block , ParentBlock ) and block .children :
170+ new_child_blocks = [
171+ _block_with_uploaded_file (block = child_block , session = session )
172+ for child_block in block .children
173+ ]
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
182+ block .append (blocks = new_child_blocks )
170183
171184 return block
172185
@@ -278,9 +291,13 @@ def main(
278291 existing_page_block .delete ()
279292
280293 block_objs_to_upload = [
281- _block_from_details ( details = details , session = session )
294+ Block . wrap_obj_ref ( UnoObjAPIBlock . model_validate ( obj = details ) )
282295 for details in blocks [delete_start_index :]
283296 ]
284- page .append (blocks = block_objs_to_upload )
297+ block_objs_with_uploaded_files = [
298+ _block_with_uploaded_file (block = block , session = session )
299+ for block in block_objs_to_upload
300+ ]
301+ page .append (blocks = block_objs_with_uploaded_files )
285302
286303 click .echo (message = f"Updated existing page: '{ title } ' ({ page .url } )" )
0 commit comments