notionary 0.2.26__py3-none-any.whl → 0.2.28__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- notionary/__init__.py +5 -20
- notionary/blocks/client.py +87 -215
- notionary/blocks/enums.py +167 -0
- notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
- notionary/blocks/rich_text/models.py +164 -0
- notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
- notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
- notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
- notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
- notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
- notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
- notionary/blocks/rich_text/rich_text_patterns.py +39 -0
- notionary/blocks/schemas.py +746 -0
- notionary/comments/client.py +52 -187
- notionary/comments/factory.py +40 -0
- notionary/comments/models.py +5 -127
- notionary/comments/schemas.py +240 -0
- notionary/comments/service.py +34 -0
- notionary/data_source/http/client.py +11 -0
- notionary/data_source/http/data_source_instance_client.py +94 -0
- notionary/data_source/properties/models.py +406 -0
- notionary/data_source/query/builder.py +429 -0
- notionary/data_source/query/resolver.py +114 -0
- notionary/data_source/query/schema.py +304 -0
- notionary/data_source/query/validator.py +73 -0
- notionary/data_source/schemas.py +27 -0
- notionary/data_source/service.py +353 -0
- notionary/database/client.py +30 -135
- notionary/database/database_metadata_update_client.py +19 -0
- notionary/database/schemas.py +29 -0
- notionary/database/service.py +169 -0
- notionary/exceptions/__init__.py +33 -0
- notionary/exceptions/api.py +41 -0
- notionary/exceptions/base.py +2 -0
- notionary/exceptions/block_parsing.py +16 -0
- notionary/exceptions/data_source/__init__.py +6 -0
- notionary/exceptions/data_source/builder.py +182 -0
- notionary/exceptions/data_source/properties.py +34 -0
- notionary/exceptions/properties.py +58 -0
- notionary/exceptions/search.py +33 -0
- notionary/file_upload/client.py +18 -30
- notionary/file_upload/models.py +7 -8
- notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
- notionary/http/client.py +205 -0
- notionary/http/models.py +49 -0
- notionary/page/blocks/client.py +1 -0
- notionary/page/content/factory.py +68 -0
- notionary/page/content/markdown/__init__.py +5 -0
- notionary/page/content/markdown/builder.py +304 -0
- notionary/page/content/markdown/nodes/__init__.py +54 -0
- notionary/page/content/markdown/nodes/audio.py +23 -0
- notionary/page/content/markdown/nodes/base.py +12 -0
- notionary/page/content/markdown/nodes/bookmark.py +25 -0
- notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
- notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
- notionary/page/content/markdown/nodes/callout.py +32 -0
- notionary/page/content/markdown/nodes/code.py +30 -0
- notionary/page/content/markdown/nodes/columns.py +51 -0
- notionary/page/content/markdown/nodes/divider.py +14 -0
- notionary/page/content/markdown/nodes/embed.py +23 -0
- notionary/page/content/markdown/nodes/equation.py +19 -0
- notionary/page/content/markdown/nodes/file.py +23 -0
- notionary/page/content/markdown/nodes/heading.py +16 -0
- notionary/page/content/markdown/nodes/image.py +23 -0
- notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
- notionary/page/content/markdown/nodes/numbered_list.py +15 -0
- notionary/page/content/markdown/nodes/paragraph.py +14 -0
- notionary/page/content/markdown/nodes/pdf.py +23 -0
- notionary/page/content/markdown/nodes/quote.py +15 -0
- notionary/page/content/markdown/nodes/space.py +14 -0
- notionary/page/content/markdown/nodes/table.py +45 -0
- notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
- notionary/page/content/markdown/nodes/todo.py +22 -0
- notionary/page/content/markdown/nodes/toggle.py +28 -0
- notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
- notionary/page/content/markdown/nodes/video.py +23 -0
- notionary/page/content/parser/context.py +49 -0
- notionary/page/content/parser/factory.py +219 -0
- notionary/page/content/parser/parsers/__init__.py +60 -0
- notionary/page/content/parser/parsers/audio.py +40 -0
- notionary/page/content/parser/parsers/base.py +30 -0
- notionary/page/content/parser/parsers/bookmark.py +33 -0
- notionary/page/content/parser/parsers/breadcrumb.py +33 -0
- notionary/page/content/parser/parsers/bulleted_list.py +41 -0
- notionary/page/content/parser/parsers/callout.py +129 -0
- notionary/page/content/parser/parsers/caption.py +55 -0
- notionary/page/content/parser/parsers/code.py +81 -0
- notionary/page/content/parser/parsers/column.py +117 -0
- notionary/page/content/parser/parsers/column_list.py +81 -0
- notionary/page/content/parser/parsers/divider.py +33 -0
- notionary/page/content/parser/parsers/embed.py +33 -0
- notionary/page/content/parser/parsers/equation.py +65 -0
- notionary/page/content/parser/parsers/file.py +42 -0
- notionary/page/content/parser/parsers/heading.py +58 -0
- notionary/page/content/parser/parsers/image.py +42 -0
- notionary/page/content/parser/parsers/numbered_list.py +45 -0
- notionary/page/content/parser/parsers/paragraph.py +36 -0
- notionary/page/content/parser/parsers/pdf.py +42 -0
- notionary/page/content/parser/parsers/quote.py +65 -0
- notionary/page/content/parser/parsers/space.py +35 -0
- notionary/page/content/parser/parsers/table.py +144 -0
- notionary/page/content/parser/parsers/table_of_contents.py +32 -0
- notionary/page/content/parser/parsers/todo.py +58 -0
- notionary/page/content/parser/parsers/toggle.py +127 -0
- notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
- notionary/page/content/parser/parsers/video.py +42 -0
- notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
- notionary/page/content/parser/post_processing/port.py +9 -0
- notionary/page/content/parser/post_processing/service.py +16 -0
- notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
- notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
- notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
- notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
- notionary/page/content/parser/pre_processsing/service.py +15 -0
- notionary/page/content/parser/service.py +69 -0
- notionary/page/content/renderer/context.py +48 -0
- notionary/page/content/renderer/factory.py +240 -0
- notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
- notionary/page/content/renderer/post_processing/port.py +7 -0
- notionary/page/content/renderer/post_processing/service.py +15 -0
- notionary/page/content/renderer/renderers/__init__.py +57 -0
- notionary/page/content/renderer/renderers/audio.py +31 -0
- notionary/page/content/renderer/renderers/base.py +31 -0
- notionary/page/content/renderer/renderers/bookmark.py +25 -0
- notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
- notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
- notionary/page/content/renderer/renderers/callout.py +65 -0
- notionary/page/content/renderer/renderers/captioned_block.py +58 -0
- notionary/page/content/renderer/renderers/code.py +34 -0
- notionary/page/content/renderer/renderers/column.py +44 -0
- notionary/page/content/renderer/renderers/column_list.py +31 -0
- notionary/page/content/renderer/renderers/divider.py +22 -0
- notionary/page/content/renderer/renderers/embed.py +25 -0
- notionary/page/content/renderer/renderers/equation.py +37 -0
- notionary/page/content/renderer/renderers/fallback.py +24 -0
- notionary/page/content/renderer/renderers/file.py +40 -0
- notionary/page/content/renderer/renderers/heading.py +69 -0
- notionary/page/content/renderer/renderers/image.py +31 -0
- notionary/page/content/renderer/renderers/numbered_list.py +41 -0
- notionary/page/content/renderer/renderers/paragraph.py +40 -0
- notionary/page/content/renderer/renderers/pdf.py +31 -0
- notionary/page/content/renderer/renderers/quote.py +49 -0
- notionary/page/content/renderer/renderers/table.py +115 -0
- notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
- notionary/page/content/renderer/renderers/table_row.py +17 -0
- notionary/page/content/renderer/renderers/todo.py +56 -0
- notionary/page/content/renderer/renderers/toggle.py +53 -0
- notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
- notionary/page/content/renderer/renderers/video.py +31 -0
- notionary/page/content/renderer/service.py +50 -0
- notionary/page/content/service.py +65 -0
- notionary/page/content/syntax/models.py +68 -0
- notionary/page/content/syntax/service.py +453 -0
- notionary/page/page_context.py +7 -16
- notionary/page/page_http_client.py +15 -0
- notionary/page/page_metadata_update_client.py +19 -0
- notionary/page/properties/client.py +144 -0
- notionary/page/properties/factory.py +26 -0
- notionary/page/properties/models.py +307 -0
- notionary/page/properties/service.py +257 -0
- notionary/page/schemas.py +13 -0
- notionary/page/service.py +222 -0
- notionary/shared/entity/client.py +29 -0
- notionary/shared/entity/dto_parsers.py +53 -0
- notionary/shared/entity/entity_metadata_update_client.py +41 -0
- notionary/shared/entity/schemas.py +45 -0
- notionary/shared/entity/service.py +171 -0
- notionary/shared/models/cover.py +20 -0
- notionary/shared/models/file.py +21 -0
- notionary/shared/models/icon.py +28 -0
- notionary/shared/models/parent.py +41 -0
- notionary/shared/properties/type.py +30 -0
- notionary/user/__init__.py +4 -8
- notionary/user/base.py +89 -0
- notionary/user/bot.py +70 -0
- notionary/user/client.py +22 -111
- notionary/user/person.py +41 -0
- notionary/user/schemas.py +67 -0
- notionary/user/service.py +65 -0
- notionary/utils/async_retry.py +39 -0
- notionary/utils/date.py +51 -0
- notionary/utils/fuzzy.py +56 -0
- notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
- notionary/utils/pagination.py +50 -0
- notionary/utils/singleton.py +13 -0
- notionary/utils/uuid_utils.py +20 -0
- notionary/workspace/__init__.py +3 -0
- notionary/workspace/client.py +62 -0
- notionary/workspace/query/builder.py +60 -0
- notionary/workspace/query/models.py +60 -0
- notionary/workspace/query/service.py +93 -0
- notionary/workspace/schemas.py +21 -0
- notionary/workspace/service.py +116 -0
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
- notionary-0.2.28.dist-info/RECORD +200 -0
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
- {notionary-0.2.26.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
- notionary/base_notion_client.py +0 -219
- notionary/blocks/__init__.py +0 -5
- notionary/blocks/_bootstrap.py +0 -271
- notionary/blocks/audio/__init__.py +0 -11
- notionary/blocks/audio/audio_element.py +0 -158
- notionary/blocks/audio/audio_markdown_node.py +0 -24
- notionary/blocks/audio/audio_models.py +0 -10
- notionary/blocks/base_block_element.py +0 -42
- notionary/blocks/bookmark/__init__.py +0 -12
- notionary/blocks/bookmark/bookmark_element.py +0 -83
- notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
- notionary/blocks/bookmark/bookmark_models.py +0 -15
- notionary/blocks/breadcrumbs/__init__.py +0 -15
- notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
- notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
- notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
- notionary/blocks/bulleted_list/__init__.py +0 -15
- notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
- notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
- notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
- notionary/blocks/callout/__init__.py +0 -12
- notionary/blocks/callout/callout_element.py +0 -99
- notionary/blocks/callout/callout_markdown_node.py +0 -19
- notionary/blocks/callout/callout_models.py +0 -33
- notionary/blocks/child_database/__init__.py +0 -14
- notionary/blocks/child_database/child_database_element.py +0 -59
- notionary/blocks/child_database/child_database_models.py +0 -12
- notionary/blocks/child_page/__init__.py +0 -9
- notionary/blocks/child_page/child_page_element.py +0 -94
- notionary/blocks/child_page/child_page_models.py +0 -12
- notionary/blocks/code/__init__.py +0 -11
- notionary/blocks/code/code_element.py +0 -149
- notionary/blocks/code/code_markdown_node.py +0 -80
- notionary/blocks/code/code_models.py +0 -94
- notionary/blocks/column/__init__.py +0 -25
- notionary/blocks/column/column_element.py +0 -65
- notionary/blocks/column/column_list_element.py +0 -52
- notionary/blocks/column/column_list_markdown_node.py +0 -34
- notionary/blocks/column/column_markdown_node.py +0 -42
- notionary/blocks/column/column_models.py +0 -26
- notionary/blocks/divider/__init__.py +0 -12
- notionary/blocks/divider/divider_element.py +0 -41
- notionary/blocks/divider/divider_markdown_node.py +0 -11
- notionary/blocks/divider/divider_models.py +0 -12
- notionary/blocks/embed/__init__.py +0 -12
- notionary/blocks/embed/embed_element.py +0 -98
- notionary/blocks/embed/embed_markdown_node.py +0 -19
- notionary/blocks/embed/embed_models.py +0 -14
- notionary/blocks/equation/__init__.py +0 -13
- notionary/blocks/equation/equation_element.py +0 -133
- notionary/blocks/equation/equation_element_markdown_node.py +0 -23
- notionary/blocks/equation/equation_models.py +0 -11
- notionary/blocks/file/__init__.py +0 -23
- notionary/blocks/file/file_element.py +0 -133
- notionary/blocks/file/file_element_markdown_node.py +0 -24
- notionary/blocks/file/file_element_models.py +0 -39
- notionary/blocks/heading/__init__.py +0 -19
- notionary/blocks/heading/heading_element.py +0 -112
- notionary/blocks/heading/heading_markdown_node.py +0 -16
- notionary/blocks/heading/heading_models.py +0 -29
- notionary/blocks/image_block/__init__.py +0 -11
- notionary/blocks/image_block/image_element.py +0 -130
- notionary/blocks/image_block/image_markdown_node.py +0 -25
- notionary/blocks/image_block/image_models.py +0 -10
- notionary/blocks/markdown/markdown_builder.py +0 -525
- notionary/blocks/markdown/markdown_document_model.py +0 -0
- notionary/blocks/markdown/markdown_node.py +0 -25
- notionary/blocks/mixins/captions/__init__.py +0 -4
- notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
- notionary/blocks/mixins/captions/caption_mixin.py +0 -92
- notionary/blocks/mixins/file_upload/__init__.py +0 -3
- notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
- notionary/blocks/models.py +0 -174
- notionary/blocks/numbered_list/__init__.py +0 -16
- notionary/blocks/numbered_list/numbered_list_element.py +0 -65
- notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
- notionary/blocks/numbered_list/numbered_list_models.py +0 -17
- notionary/blocks/paragraph/__init__.py +0 -15
- notionary/blocks/paragraph/paragraph_element.py +0 -58
- notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
- notionary/blocks/paragraph/paragraph_models.py +0 -16
- notionary/blocks/pdf/__init__.py +0 -11
- notionary/blocks/pdf/pdf_element.py +0 -146
- notionary/blocks/pdf/pdf_markdown_node.py +0 -24
- notionary/blocks/pdf/pdf_models.py +0 -11
- notionary/blocks/quote/__init__.py +0 -14
- notionary/blocks/quote/quote_element.py +0 -75
- notionary/blocks/quote/quote_markdown_node.py +0 -16
- notionary/blocks/quote/quote_models.py +0 -18
- notionary/blocks/registry/__init__.py +0 -3
- notionary/blocks/registry/block_registry.py +0 -150
- notionary/blocks/rich_text/__init__.py +0 -33
- notionary/blocks/rich_text/rich_text_models.py +0 -221
- notionary/blocks/rich_text/text_inline_formatter.py +0 -456
- notionary/blocks/syntax_prompt_builder.py +0 -137
- notionary/blocks/table/__init__.py +0 -19
- notionary/blocks/table/table_element.py +0 -225
- notionary/blocks/table/table_markdown_node.py +0 -42
- notionary/blocks/table/table_models.py +0 -28
- notionary/blocks/table_of_contents/__init__.py +0 -17
- notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
- notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
- notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
- notionary/blocks/todo/__init__.py +0 -12
- notionary/blocks/todo/todo_element.py +0 -81
- notionary/blocks/todo/todo_markdown_node.py +0 -21
- notionary/blocks/todo/todo_models.py +0 -18
- notionary/blocks/toggle/__init__.py +0 -12
- notionary/blocks/toggle/toggle_element.py +0 -112
- notionary/blocks/toggle/toggle_markdown_node.py +0 -31
- notionary/blocks/toggle/toggle_models.py +0 -17
- notionary/blocks/toggleable_heading/__init__.py +0 -11
- notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
- notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
- notionary/blocks/types.py +0 -130
- notionary/blocks/video/__init__.py +0 -11
- notionary/blocks/video/video_element.py +0 -187
- notionary/blocks/video/video_element_models.py +0 -10
- notionary/blocks/video/video_markdown_node.py +0 -26
- notionary/comments/__init__.py +0 -26
- notionary/database/__init__.py +0 -4
- notionary/database/database.py +0 -480
- notionary/database/database_filter_builder.py +0 -173
- notionary/database/database_provider.py +0 -227
- notionary/database/exceptions.py +0 -13
- notionary/database/factory.py +0 -0
- notionary/database/models.py +0 -337
- notionary/database/notion_database.py +0 -487
- notionary/file_upload/__init__.py +0 -7
- notionary/page/client.py +0 -124
- notionary/page/markdown_whitespace_processor.py +0 -129
- notionary/page/models.py +0 -322
- notionary/page/notion_page.py +0 -674
- notionary/page/page_content_deleting_service.py +0 -117
- notionary/page/page_content_writer.py +0 -80
- notionary/page/property_formatter.py +0 -99
- notionary/page/reader/handler/__init__.py +0 -19
- notionary/page/reader/handler/base_block_renderer.py +0 -44
- notionary/page/reader/handler/block_processing_context.py +0 -35
- notionary/page/reader/handler/block_rendering_context.py +0 -48
- notionary/page/reader/handler/column_list_renderer.py +0 -51
- notionary/page/reader/handler/column_renderer.py +0 -60
- notionary/page/reader/handler/equation_renderer.py +0 -0
- notionary/page/reader/handler/line_renderer.py +0 -73
- notionary/page/reader/handler/numbered_list_renderer.py +0 -85
- notionary/page/reader/handler/toggle_renderer.py +0 -69
- notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
- notionary/page/reader/page_content_retriever.py +0 -81
- notionary/page/search_filter_builder.py +0 -132
- notionary/page/utils.py +0 -60
- notionary/page/writer/handler/__init__.py +0 -24
- notionary/page/writer/handler/code_handler.py +0 -72
- notionary/page/writer/handler/column_handler.py +0 -141
- notionary/page/writer/handler/column_list_handler.py +0 -139
- notionary/page/writer/handler/equation_handler.py +0 -74
- notionary/page/writer/handler/line_handler.py +0 -35
- notionary/page/writer/handler/line_processing_context.py +0 -54
- notionary/page/writer/handler/regular_line_handler.py +0 -86
- notionary/page/writer/handler/table_handler.py +0 -66
- notionary/page/writer/handler/toggle_handler.py +0 -159
- notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
- notionary/page/writer/markdown_to_notion_converter.py +0 -139
- notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
- notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
- notionary/page/writer/notion_text_length_processor.py +0 -150
- notionary/schemas/__init__.py +0 -3
- notionary/schemas/base.py +0 -73
- notionary/shared/__init__.py +0 -3
- notionary/shared/name_to_id_resolver.py +0 -203
- notionary/telemetry/__init__.py +0 -19
- notionary/telemetry/service.py +0 -136
- notionary/telemetry/views.py +0 -73
- notionary/user/base_notion_user.py +0 -53
- notionary/user/models.py +0 -84
- notionary/user/notion_bot_user.py +0 -226
- notionary/user/notion_user.py +0 -255
- notionary/user/notion_user_manager.py +0 -101
- notionary/util/__init__.py +0 -15
- notionary/util/concurrency_limiter.py +0 -0
- notionary/util/factory_decorator.py +0 -0
- notionary/util/factory_only.py +0 -37
- notionary/util/fuzzy.py +0 -75
- notionary/util/page_id_utils.py +0 -27
- notionary/util/singleton.py +0 -18
- notionary/util/singleton_metaclass.py +0 -22
- notionary/workspace.py +0 -105
- notionary-0.2.26.dist-info/RECORD +0 -202
notionary/blocks/_bootstrap.py
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from typing import Optional, Union
|
4
|
-
|
5
|
-
_bootstrapped = False
|
6
|
-
|
7
|
-
|
8
|
-
def bootstrap_blocks() -> None:
|
9
|
-
global _bootstrapped
|
10
|
-
if _bootstrapped:
|
11
|
-
return
|
12
|
-
|
13
|
-
from notionary.blocks import (
|
14
|
-
bookmark,
|
15
|
-
breadcrumbs,
|
16
|
-
bulleted_list,
|
17
|
-
callout,
|
18
|
-
child_page,
|
19
|
-
code,
|
20
|
-
column,
|
21
|
-
divider,
|
22
|
-
embed,
|
23
|
-
equation,
|
24
|
-
file,
|
25
|
-
heading,
|
26
|
-
image_block,
|
27
|
-
models,
|
28
|
-
numbered_list,
|
29
|
-
paragraph,
|
30
|
-
quote,
|
31
|
-
table,
|
32
|
-
table_of_contents,
|
33
|
-
todo,
|
34
|
-
toggle,
|
35
|
-
toggleable_heading,
|
36
|
-
video,
|
37
|
-
child_database,
|
38
|
-
)
|
39
|
-
|
40
|
-
# Collect all exports from modules
|
41
|
-
ns = {}
|
42
|
-
for m in (
|
43
|
-
bookmark,
|
44
|
-
breadcrumbs,
|
45
|
-
bulleted_list,
|
46
|
-
callout,
|
47
|
-
child_page,
|
48
|
-
code,
|
49
|
-
column,
|
50
|
-
divider,
|
51
|
-
embed,
|
52
|
-
equation,
|
53
|
-
file,
|
54
|
-
heading,
|
55
|
-
image_block,
|
56
|
-
numbered_list,
|
57
|
-
paragraph,
|
58
|
-
quote,
|
59
|
-
table,
|
60
|
-
todo,
|
61
|
-
toggle,
|
62
|
-
video,
|
63
|
-
toggleable_heading,
|
64
|
-
table_of_contents,
|
65
|
-
child_database,
|
66
|
-
):
|
67
|
-
ns.update(vars(m))
|
68
|
-
|
69
|
-
# Add missing types that are needed for model rebuilding
|
70
|
-
# These are the types that are only defined in TYPE_CHECKING in block_models
|
71
|
-
from notionary.blocks.bookmark.bookmark_models import (
|
72
|
-
BookmarkBlock,
|
73
|
-
CreateBookmarkBlock,
|
74
|
-
)
|
75
|
-
from notionary.blocks.breadcrumbs.breadcrumb_models import (
|
76
|
-
BreadcrumbBlock,
|
77
|
-
CreateBreadcrumbBlock,
|
78
|
-
)
|
79
|
-
from notionary.blocks.bulleted_list.bulleted_list_models import (
|
80
|
-
BulletedListItemBlock,
|
81
|
-
CreateBulletedListItemBlock,
|
82
|
-
)
|
83
|
-
from notionary.blocks.callout.callout_models import CalloutBlock, CreateCalloutBlock
|
84
|
-
from notionary.blocks.child_page.child_page_models import (
|
85
|
-
ChildPageBlock,
|
86
|
-
CreateChildPageBlock,
|
87
|
-
)
|
88
|
-
from notionary.blocks.code.code_models import CodeBlock, CreateCodeBlock
|
89
|
-
from notionary.blocks.column.column_models import (
|
90
|
-
ColumnBlock,
|
91
|
-
ColumnListBlock,
|
92
|
-
CreateColumnBlock,
|
93
|
-
CreateColumnListBlock,
|
94
|
-
)
|
95
|
-
from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
|
96
|
-
from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
|
97
|
-
from notionary.blocks.equation.equation_models import (
|
98
|
-
CreateEquationBlock,
|
99
|
-
EquationBlock,
|
100
|
-
)
|
101
|
-
from notionary.blocks.file.file_element_models import CreateFileBlock, FileBlock
|
102
|
-
from notionary.blocks.heading.heading_models import (
|
103
|
-
CreateHeading1Block,
|
104
|
-
CreateHeading2Block,
|
105
|
-
CreateHeading3Block,
|
106
|
-
HeadingBlock,
|
107
|
-
)
|
108
|
-
from notionary.blocks.image_block.image_models import CreateImageBlock
|
109
|
-
from notionary.blocks.numbered_list.numbered_list_models import (
|
110
|
-
CreateNumberedListItemBlock,
|
111
|
-
NumberedListItemBlock,
|
112
|
-
)
|
113
|
-
from notionary.blocks.paragraph.paragraph_models import (
|
114
|
-
CreateParagraphBlock,
|
115
|
-
ParagraphBlock,
|
116
|
-
)
|
117
|
-
from notionary.blocks.pdf.pdf_models import CreatePdfBlock
|
118
|
-
from notionary.blocks.quote.quote_models import CreateQuoteBlock, QuoteBlock
|
119
|
-
from notionary.blocks.table.table_models import TableBlock, TableRowBlock
|
120
|
-
from notionary.blocks.table_of_contents.table_of_contents_models import (
|
121
|
-
CreateTableOfContentsBlock,
|
122
|
-
TableOfContentsBlock,
|
123
|
-
)
|
124
|
-
from notionary.blocks.todo.todo_models import CreateToDoBlock, ToDoBlock
|
125
|
-
from notionary.blocks.toggle.toggle_models import CreateToggleBlock, ToggleBlock
|
126
|
-
from notionary.blocks.types import BlockType
|
127
|
-
from notionary.blocks.video.video_element_models import CreateVideoBlock
|
128
|
-
from notionary.blocks.child_database.child_database_models import (
|
129
|
-
CreateChildDatabaseBlock,
|
130
|
-
ChildDatabaseBlock,
|
131
|
-
)
|
132
|
-
|
133
|
-
# Define the Union types that are needed for model rebuilding
|
134
|
-
BlockCreateRequest = Union[
|
135
|
-
CreateBookmarkBlock,
|
136
|
-
CreateBreadcrumbBlock,
|
137
|
-
CreateBulletedListItemBlock,
|
138
|
-
CreateCalloutBlock,
|
139
|
-
CreateChildPageBlock,
|
140
|
-
CreateCodeBlock,
|
141
|
-
CreateColumnListBlock,
|
142
|
-
CreateColumnBlock,
|
143
|
-
CreateDividerBlock,
|
144
|
-
CreateEmbedBlock,
|
145
|
-
CreateEquationBlock,
|
146
|
-
CreateFileBlock,
|
147
|
-
CreateHeading1Block,
|
148
|
-
CreateHeading2Block,
|
149
|
-
CreateHeading3Block,
|
150
|
-
CreateImageBlock,
|
151
|
-
CreateNumberedListItemBlock,
|
152
|
-
CreateParagraphBlock,
|
153
|
-
CreateQuoteBlock,
|
154
|
-
CreateToDoBlock,
|
155
|
-
CreateToggleBlock,
|
156
|
-
CreateVideoBlock,
|
157
|
-
CreateTableOfContentsBlock,
|
158
|
-
CreatePdfBlock,
|
159
|
-
CreateChildDatabaseBlock,
|
160
|
-
]
|
161
|
-
|
162
|
-
BlockCreateResult = Optional[BlockCreateRequest]
|
163
|
-
|
164
|
-
# Add all block types to namespace
|
165
|
-
ns.update(
|
166
|
-
{
|
167
|
-
"BlockType": BlockType,
|
168
|
-
"BookmarkBlock": BookmarkBlock,
|
169
|
-
"CreateBookmarkBlock": CreateBookmarkBlock,
|
170
|
-
"BreadcrumbBlock": BreadcrumbBlock,
|
171
|
-
"CreateBreadcrumbBlock": CreateBreadcrumbBlock,
|
172
|
-
"BulletedListItemBlock": BulletedListItemBlock,
|
173
|
-
"CreateBulletedListItemBlock": CreateBulletedListItemBlock,
|
174
|
-
"CalloutBlock": CalloutBlock,
|
175
|
-
"CreateCalloutBlock": CreateCalloutBlock,
|
176
|
-
"ChildPageBlock": ChildPageBlock,
|
177
|
-
"CreateChildPageBlock": CreateChildPageBlock,
|
178
|
-
"CodeBlock": CodeBlock,
|
179
|
-
"CreateCodeBlock": CreateCodeBlock,
|
180
|
-
"ColumnBlock": ColumnBlock,
|
181
|
-
"ColumnListBlock": ColumnListBlock,
|
182
|
-
"CreateColumnBlock": CreateColumnBlock,
|
183
|
-
"CreateColumnListBlock": CreateColumnListBlock,
|
184
|
-
"DividerBlock": DividerBlock,
|
185
|
-
"CreateDividerBlock": CreateDividerBlock,
|
186
|
-
"EmbedBlock": EmbedBlock,
|
187
|
-
"CreateEmbedBlock": CreateEmbedBlock,
|
188
|
-
"EquationBlock": EquationBlock,
|
189
|
-
"CreateEquationBlock": CreateEquationBlock,
|
190
|
-
"FileBlock": FileBlock,
|
191
|
-
"CreateFileBlock": CreateFileBlock,
|
192
|
-
"HeadingBlock": HeadingBlock,
|
193
|
-
"CreateHeading1Block": CreateHeading1Block,
|
194
|
-
"CreateHeading2Block": CreateHeading2Block,
|
195
|
-
"CreateHeading3Block": CreateHeading3Block,
|
196
|
-
"CreateImageBlock": CreateImageBlock,
|
197
|
-
"NumberedListItemBlock": NumberedListItemBlock,
|
198
|
-
"CreateNumberedListItemBlock": CreateNumberedListItemBlock,
|
199
|
-
"ParagraphBlock": ParagraphBlock,
|
200
|
-
"CreateParagraphBlock": CreateParagraphBlock,
|
201
|
-
"QuoteBlock": QuoteBlock,
|
202
|
-
"CreateQuoteBlock": CreateQuoteBlock,
|
203
|
-
"TableBlock": TableBlock,
|
204
|
-
"TableRowBlock": TableRowBlock,
|
205
|
-
"ToDoBlock": ToDoBlock,
|
206
|
-
"CreateToDoBlock": CreateToDoBlock,
|
207
|
-
"ToggleBlock": ToggleBlock,
|
208
|
-
"CreateToggleBlock": CreateToggleBlock,
|
209
|
-
"CreateVideoBlock": CreateVideoBlock,
|
210
|
-
"TableOfContentsBlock": TableOfContentsBlock,
|
211
|
-
"CreateTableOfContentsBlock": CreateTableOfContentsBlock,
|
212
|
-
"ChildDatabaseBlock": ChildDatabaseBlock,
|
213
|
-
# Add the Union types
|
214
|
-
"BlockCreateRequest": BlockCreateRequest,
|
215
|
-
"BlockCreateResult": BlockCreateResult,
|
216
|
-
}
|
217
|
-
)
|
218
|
-
|
219
|
-
# Now rebuild with complete namespace
|
220
|
-
models.Block.model_rebuild(_types_namespace=ns)
|
221
|
-
models.BlockChildrenResponse.model_rebuild(_types_namespace=ns)
|
222
|
-
|
223
|
-
# Rebuild all individual block models
|
224
|
-
BookmarkBlock.model_rebuild()
|
225
|
-
BreadcrumbBlock.model_rebuild()
|
226
|
-
BulletedListItemBlock.model_rebuild()
|
227
|
-
CalloutBlock.model_rebuild()
|
228
|
-
ChildPageBlock.model_rebuild()
|
229
|
-
CodeBlock.model_rebuild()
|
230
|
-
ColumnBlock.model_rebuild()
|
231
|
-
ColumnListBlock.model_rebuild()
|
232
|
-
DividerBlock.model_rebuild()
|
233
|
-
EmbedBlock.model_rebuild()
|
234
|
-
EquationBlock.model_rebuild()
|
235
|
-
FileBlock.model_rebuild()
|
236
|
-
HeadingBlock.model_rebuild()
|
237
|
-
NumberedListItemBlock.model_rebuild()
|
238
|
-
ParagraphBlock.model_rebuild()
|
239
|
-
QuoteBlock.model_rebuild()
|
240
|
-
TableBlock.model_rebuild()
|
241
|
-
TableRowBlock.model_rebuild()
|
242
|
-
ToDoBlock.model_rebuild()
|
243
|
-
ToggleBlock.model_rebuild()
|
244
|
-
TableOfContentsBlock.model_rebuild()
|
245
|
-
|
246
|
-
# Rebuild create models
|
247
|
-
CreateBookmarkBlock.model_rebuild()
|
248
|
-
CreateBreadcrumbBlock.model_rebuild()
|
249
|
-
CreateBulletedListItemBlock.model_rebuild()
|
250
|
-
CreateCalloutBlock.model_rebuild()
|
251
|
-
CreateChildPageBlock.model_rebuild()
|
252
|
-
CreateCodeBlock.model_rebuild()
|
253
|
-
CreateColumnListBlock.model_rebuild()
|
254
|
-
CreateColumnBlock.model_rebuild()
|
255
|
-
CreateDividerBlock.model_rebuild()
|
256
|
-
CreateEmbedBlock.model_rebuild()
|
257
|
-
CreateEquationBlock.model_rebuild()
|
258
|
-
CreateFileBlock.model_rebuild()
|
259
|
-
CreateHeading1Block.model_rebuild()
|
260
|
-
CreateHeading2Block.model_rebuild()
|
261
|
-
CreateHeading3Block.model_rebuild()
|
262
|
-
CreateImageBlock.model_rebuild()
|
263
|
-
CreateNumberedListItemBlock.model_rebuild()
|
264
|
-
CreateParagraphBlock.model_rebuild()
|
265
|
-
CreateQuoteBlock.model_rebuild()
|
266
|
-
CreateToDoBlock.model_rebuild()
|
267
|
-
CreateToggleBlock.model_rebuild()
|
268
|
-
CreateVideoBlock.model_rebuild()
|
269
|
-
CreateTableOfContentsBlock.model_rebuild()
|
270
|
-
|
271
|
-
_bootstrapped = True
|
@@ -1,11 +0,0 @@
|
|
1
|
-
from notionary.blocks.audio.audio_element import AudioElement
|
2
|
-
from notionary.blocks.audio.audio_markdown_node import (
|
3
|
-
AudioMarkdownNode,
|
4
|
-
)
|
5
|
-
from notionary.blocks.audio.audio_models import CreateAudioBlock
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"AudioElement",
|
9
|
-
"CreateAudioBlock",
|
10
|
-
"AudioMarkdownNode",
|
11
|
-
]
|
@@ -1,158 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import re
|
4
|
-
from pathlib import Path
|
5
|
-
from typing import Optional
|
6
|
-
|
7
|
-
from notionary.blocks.audio.audio_models import CreateAudioBlock
|
8
|
-
from notionary.blocks.base_block_element import BaseBlockElement
|
9
|
-
from notionary.blocks.file.file_element_models import (
|
10
|
-
ExternalFile,
|
11
|
-
FileBlock,
|
12
|
-
FileType,
|
13
|
-
FileUploadFile,
|
14
|
-
)
|
15
|
-
from notionary.blocks.mixins.captions import CaptionMixin
|
16
|
-
from notionary.blocks.mixins.file_upload.file_upload_mixin import FileUploadMixin
|
17
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
18
|
-
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
19
|
-
from notionary.util.logging_mixin import LoggingMixin
|
20
|
-
|
21
|
-
|
22
|
-
class AudioElement(BaseBlockElement, FileUploadMixin, LoggingMixin, CaptionMixin):
|
23
|
-
r"""
|
24
|
-
Handles conversion between Markdown audio embeds and Notion audio blocks.
|
25
|
-
|
26
|
-
Supports both external URLs and local audio file uploads.
|
27
|
-
|
28
|
-
Markdown audio syntax:
|
29
|
-
- [audio](https://example.com/audio.mp3) - External URL
|
30
|
-
- [audio](./local/song.mp3) - Local audio file (will be uploaded)
|
31
|
-
- [audio](C:\Music\podcast.wav) - Absolute local path (will be uploaded)
|
32
|
-
- [audio](https://example.com/audio.mp3)(caption:Episode 1) - URL with caption
|
33
|
-
"""
|
34
|
-
|
35
|
-
AUDIO_PATTERN = re.compile(r"\[audio\]\(([^)]+)\)")
|
36
|
-
SUPPORTED_EXTENSIONS = {".mp3", ".wav", ".ogg", ".oga", ".m4a"}
|
37
|
-
|
38
|
-
@classmethod
|
39
|
-
def match_notion(cls, block: Block) -> bool:
|
40
|
-
"""Check if this element can handle the given Notion block."""
|
41
|
-
return block.type == BlockType.AUDIO
|
42
|
-
|
43
|
-
@classmethod
|
44
|
-
async def markdown_to_notion(cls, text: str) -> Optional[BlockCreateResult]:
|
45
|
-
"""Convert markdown audio embed to Notion audio block."""
|
46
|
-
# Extract the path/URL
|
47
|
-
path = cls._extract_audio_path(text.strip())
|
48
|
-
if not path:
|
49
|
-
return None
|
50
|
-
|
51
|
-
# Check if it's a local file path
|
52
|
-
if cls._is_local_file_path(path):
|
53
|
-
# Verify file exists and has supported extension
|
54
|
-
audio_path = Path(path)
|
55
|
-
if not audio_path.exists():
|
56
|
-
cls.logger.warning(f"Audio file not found: {path}")
|
57
|
-
return None
|
58
|
-
|
59
|
-
if audio_path.suffix.lower() not in cls.SUPPORTED_EXTENSIONS:
|
60
|
-
cls.logger.warning(f"Unsupported audio format: {audio_path.suffix}")
|
61
|
-
return None
|
62
|
-
|
63
|
-
cls.logger.info(f"Uploading local audio file: {path}")
|
64
|
-
|
65
|
-
# Upload the local audio file
|
66
|
-
file_upload_id = await cls._upload_local_file(path, "audio")
|
67
|
-
if not file_upload_id:
|
68
|
-
cls.logger.error(f"Failed to upload audio file: {path}")
|
69
|
-
return None
|
70
|
-
|
71
|
-
cls.logger.info(
|
72
|
-
f"Successfully uploaded audio file with ID: {file_upload_id}"
|
73
|
-
)
|
74
|
-
|
75
|
-
# Use mixin to extract caption (if present anywhere in text)
|
76
|
-
caption_text = cls.extract_caption(text.strip())
|
77
|
-
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
78
|
-
|
79
|
-
audio_content = FileBlock(
|
80
|
-
type=FileType.FILE_UPLOAD,
|
81
|
-
file_upload=FileUploadFile(id=file_upload_id),
|
82
|
-
caption=caption_rich_text,
|
83
|
-
)
|
84
|
-
|
85
|
-
return CreateAudioBlock(audio=audio_content)
|
86
|
-
|
87
|
-
else:
|
88
|
-
# Handle external URL - accept any URL (validation happens at API level)
|
89
|
-
# Use mixin to extract caption (if present anywhere in text)
|
90
|
-
caption_text = cls.extract_caption(text.strip())
|
91
|
-
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
92
|
-
|
93
|
-
audio_content = FileBlock(
|
94
|
-
type=FileType.EXTERNAL,
|
95
|
-
external=ExternalFile(url=path),
|
96
|
-
caption=caption_rich_text,
|
97
|
-
)
|
98
|
-
|
99
|
-
return CreateAudioBlock(audio=audio_content)
|
100
|
-
|
101
|
-
@classmethod
|
102
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
103
|
-
"""Convert Notion audio block to markdown audio embed."""
|
104
|
-
if block.type != BlockType.AUDIO or block.audio is None:
|
105
|
-
return None
|
106
|
-
|
107
|
-
audio = block.audio
|
108
|
-
url = None
|
109
|
-
|
110
|
-
# Handle both external URLs and uploaded files
|
111
|
-
if audio.type == FileType.EXTERNAL and audio.external is not None:
|
112
|
-
url = audio.external.url
|
113
|
-
elif audio.type == FileType.FILE_UPLOAD and audio.file_upload is not None:
|
114
|
-
url = audio.file_upload.url
|
115
|
-
|
116
|
-
if not url:
|
117
|
-
return None
|
118
|
-
|
119
|
-
result = f"[audio]({url})"
|
120
|
-
|
121
|
-
# Add caption if present
|
122
|
-
caption_markdown = await cls.format_caption_for_markdown(audio.caption or [])
|
123
|
-
if caption_markdown:
|
124
|
-
result += caption_markdown
|
125
|
-
|
126
|
-
return result
|
127
|
-
|
128
|
-
@classmethod
|
129
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
130
|
-
"""Get system prompt information for audio blocks."""
|
131
|
-
return BlockElementMarkdownInformation(
|
132
|
-
block_type=cls.__name__,
|
133
|
-
description="Audio blocks embed audio files from external URLs or local files with optional captions",
|
134
|
-
syntax_examples=[
|
135
|
-
"[audio](https://example.com/song.mp3)",
|
136
|
-
"[audio](./local/podcast.wav)",
|
137
|
-
"[audio](C:\\Music\\interview.mp3)",
|
138
|
-
"[audio](https://example.com/podcast.wav)(caption:Episode 1)",
|
139
|
-
"(caption:Background music)[audio](./song.mp3)",
|
140
|
-
"[audio](./interview.mp3)(caption:**Live** interview)",
|
141
|
-
],
|
142
|
-
usage_guidelines="Use for embedding audio files like music, podcasts, or sound effects. Supports both external URLs and local file uploads. Supports common audio formats (mp3, wav, ogg, m4a). Caption supports rich text formatting and is optional.",
|
143
|
-
)
|
144
|
-
|
145
|
-
@classmethod
|
146
|
-
def _is_likely_audio_url(cls, url: str) -> bool:
|
147
|
-
return any(url.lower().endswith(ext) for ext in cls.SUPPORTED_EXTENSIONS)
|
148
|
-
|
149
|
-
@classmethod
|
150
|
-
def _extract_audio_path(cls, text: str) -> Optional[str]:
|
151
|
-
"""Extract audio path/URL from text, handling caption patterns."""
|
152
|
-
clean_text = cls.remove_caption(text)
|
153
|
-
|
154
|
-
match = cls.AUDIO_PATTERN.search(clean_text)
|
155
|
-
if match:
|
156
|
-
return match.group(1).strip()
|
157
|
-
|
158
|
-
return None
|
@@ -1,24 +0,0 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
4
|
-
from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
|
5
|
-
|
6
|
-
|
7
|
-
class AudioMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
|
8
|
-
"""
|
9
|
-
Enhanced Audio node with Pydantic integration.
|
10
|
-
Programmatic interface for creating Notion-style audio blocks.
|
11
|
-
"""
|
12
|
-
|
13
|
-
url: str
|
14
|
-
caption: Optional[str] = None
|
15
|
-
|
16
|
-
def to_markdown(self) -> str:
|
17
|
-
"""Return the Markdown representation.
|
18
|
-
|
19
|
-
Examples:
|
20
|
-
- [audio](https://example.com/song.mp3)
|
21
|
-
- [audio](https://example.com/song.mp3)(caption:Background music)
|
22
|
-
"""
|
23
|
-
base_markdown = f"[audio]({self.url})"
|
24
|
-
return self.append_caption_to_markdown(base_markdown, self.caption)
|
@@ -1,42 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from abc import ABC
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
7
|
-
from notionary.blocks.models import Block, BlockCreateResult
|
8
|
-
|
9
|
-
|
10
|
-
class BaseBlockElement(ABC):
|
11
|
-
"""Base class for elements that can be converted between Markdown and Notion."""
|
12
|
-
|
13
|
-
@classmethod
|
14
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
15
|
-
"""
|
16
|
-
Convert markdown to Notion block content.
|
17
|
-
|
18
|
-
Returns:
|
19
|
-
- BlockContent: Single block content (e.g., ToDoBlock, ParagraphBlock)
|
20
|
-
- list[BlockContent]: Multiple block contents
|
21
|
-
- None: Cannot convert this markdown
|
22
|
-
"""
|
23
|
-
|
24
|
-
@classmethod
|
25
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
26
|
-
"""Convert Notion block to markdown."""
|
27
|
-
|
28
|
-
@classmethod
|
29
|
-
def match_notion(cls, block: Block) -> bool:
|
30
|
-
"""Check if this element can handle the given Notion block."""
|
31
|
-
# Default implementation - subclasses should override this method
|
32
|
-
# Cannot call async notion_to_markdown here
|
33
|
-
return False
|
34
|
-
|
35
|
-
@classmethod
|
36
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
37
|
-
"""Get system prompt information for this block element.
|
38
|
-
|
39
|
-
Subclasses should override this method to provide their specific information.
|
40
|
-
Return None if the element should not be included in documentation.
|
41
|
-
"""
|
42
|
-
return None
|
@@ -1,12 +0,0 @@
|
|
1
|
-
from notionary.blocks.bookmark.bookmark_element import BookmarkElement
|
2
|
-
from notionary.blocks.bookmark.bookmark_markdown_node import (
|
3
|
-
BookmarkMarkdownNode,
|
4
|
-
)
|
5
|
-
from notionary.blocks.bookmark.bookmark_models import BookmarkBlock, CreateBookmarkBlock
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"BookmarkElement",
|
9
|
-
"BookmarkBlock",
|
10
|
-
"CreateBookmarkBlock",
|
11
|
-
"BookmarkMarkdownNode",
|
12
|
-
]
|
@@ -1,83 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import re
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
from notionary.blocks.base_block_element import BaseBlockElement
|
7
|
-
from notionary.blocks.bookmark.bookmark_models import BookmarkBlock, CreateBookmarkBlock
|
8
|
-
from notionary.blocks.mixins.captions import CaptionMixin
|
9
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
10
|
-
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
11
|
-
|
12
|
-
|
13
|
-
class BookmarkElement(BaseBlockElement, CaptionMixin):
|
14
|
-
"""
|
15
|
-
Handles conversion between Markdown bookmarks and Notion bookmark blocks.
|
16
|
-
|
17
|
-
Markdown bookmark syntax:
|
18
|
-
- [bookmark](https://example.com) - URL only
|
19
|
-
- [bookmark](https://example.com)(caption:This is a caption) - URL with caption
|
20
|
-
- (caption:This is a caption)[bookmark](https://example.com) - caption before URL
|
21
|
-
"""
|
22
|
-
|
23
|
-
# Flexible pattern that can handle caption in any position
|
24
|
-
BOOKMARK_PATTERN = re.compile(r"\[bookmark\]\((https?://[^\s\"]+)\)")
|
25
|
-
|
26
|
-
@classmethod
|
27
|
-
def match_notion(cls, block: Block) -> bool:
|
28
|
-
return block.type == BlockType.BOOKMARK and block.bookmark
|
29
|
-
|
30
|
-
@classmethod
|
31
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
32
|
-
"""
|
33
|
-
Convert a markdown bookmark into a Notion BookmarkBlock.
|
34
|
-
"""
|
35
|
-
# First remove captions to get clean text for URL extraction
|
36
|
-
clean_text = cls.remove_caption(text.strip())
|
37
|
-
|
38
|
-
# Use our own regex to find the bookmark URL
|
39
|
-
bookmark_match = cls.BOOKMARK_PATTERN.search(clean_text)
|
40
|
-
if not bookmark_match:
|
41
|
-
return None
|
42
|
-
|
43
|
-
url = bookmark_match.group(1)
|
44
|
-
|
45
|
-
caption_text = cls.extract_caption(text.strip())
|
46
|
-
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
47
|
-
|
48
|
-
bookmark_data = BookmarkBlock(url=url, caption=caption_rich_text)
|
49
|
-
return CreateBookmarkBlock(bookmark=bookmark_data)
|
50
|
-
|
51
|
-
@classmethod
|
52
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
53
|
-
if block.type != BlockType.BOOKMARK or block.bookmark is None:
|
54
|
-
return None
|
55
|
-
|
56
|
-
bm = block.bookmark
|
57
|
-
url = bm.url
|
58
|
-
if not url:
|
59
|
-
return None
|
60
|
-
|
61
|
-
result = f"[bookmark]({url})"
|
62
|
-
|
63
|
-
# Add caption if present
|
64
|
-
caption_markdown = await cls.format_caption_for_markdown(bm.caption or [])
|
65
|
-
if caption_markdown:
|
66
|
-
result += caption_markdown
|
67
|
-
|
68
|
-
return result
|
69
|
-
|
70
|
-
@classmethod
|
71
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
72
|
-
"""Get system prompt information for bookmark blocks."""
|
73
|
-
return BlockElementMarkdownInformation(
|
74
|
-
block_type=cls.__name__,
|
75
|
-
description="Bookmark blocks create previews of web pages with optional captions",
|
76
|
-
syntax_examples=[
|
77
|
-
"[bookmark](https://example.com)",
|
78
|
-
"[bookmark](https://example.com)(caption:This is a caption)",
|
79
|
-
"(caption:Check out this repository)[bookmark](https://github.com/user/repo)",
|
80
|
-
"[bookmark](https://github.com/user/repo)(caption:Check out this awesome repository)",
|
81
|
-
],
|
82
|
-
usage_guidelines="Use for linking to external websites with rich previews. URL is required. Caption supports rich text formatting and is optional.",
|
83
|
-
)
|
@@ -1,28 +0,0 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
4
|
-
from notionary.blocks.mixins.captions import CaptionMarkdownNodeMixin
|
5
|
-
|
6
|
-
|
7
|
-
class BookmarkMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
|
8
|
-
"""
|
9
|
-
Enhanced Bookmark node with Pydantic integration.
|
10
|
-
Programmatic interface for creating Notion-style bookmark Markdown blocks.
|
11
|
-
"""
|
12
|
-
|
13
|
-
url: str
|
14
|
-
title: Optional[str] = None
|
15
|
-
caption: Optional[str] = None
|
16
|
-
|
17
|
-
def to_markdown(self) -> str:
|
18
|
-
"""Return the Markdown representation.
|
19
|
-
|
20
|
-
Examples:
|
21
|
-
- [bookmark](https://example.com)
|
22
|
-
- [bookmark](https://example.com)(caption:Some caption)
|
23
|
-
"""
|
24
|
-
# Use simple bookmark syntax like BookmarkElement
|
25
|
-
base_markdown = f"[bookmark]({self.url})"
|
26
|
-
|
27
|
-
# Append caption using mixin helper
|
28
|
-
return self.append_caption_to_markdown(base_markdown, self.caption)
|
@@ -1,15 +0,0 @@
|
|
1
|
-
from typing import Literal
|
2
|
-
|
3
|
-
from pydantic import BaseModel, Field
|
4
|
-
|
5
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
6
|
-
|
7
|
-
|
8
|
-
class BookmarkBlock(BaseModel):
|
9
|
-
caption: list[RichTextObject] = Field(default_factory=list)
|
10
|
-
url: str
|
11
|
-
|
12
|
-
|
13
|
-
class CreateBookmarkBlock(BaseModel):
|
14
|
-
type: Literal["bookmark"] = "bookmark"
|
15
|
-
bookmark: BookmarkBlock
|
@@ -1,15 +0,0 @@
|
|
1
|
-
from notionary.blocks.breadcrumbs.breadcrumb_element import BreadcrumbElement
|
2
|
-
from notionary.blocks.breadcrumbs.breadcrumb_markdown_node import (
|
3
|
-
BreadcrumbMarkdownNode,
|
4
|
-
)
|
5
|
-
from notionary.blocks.breadcrumbs.breadcrumb_models import (
|
6
|
-
BreadcrumbBlock,
|
7
|
-
CreateBreadcrumbBlock,
|
8
|
-
)
|
9
|
-
|
10
|
-
__all__ = [
|
11
|
-
"BreadcrumbElement",
|
12
|
-
"BreadcrumbBlock",
|
13
|
-
"CreateBreadcrumbBlock",
|
14
|
-
"BreadcrumbMarkdownNode",
|
15
|
-
]
|