notionary 0.2.27__py3-none-any.whl → 0.3.0__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/__init__.py +4 -4
- notionary/blocks/client.py +90 -216
- notionary/blocks/enums.py +167 -0
- notionary/blocks/rich_text/markdown_rich_text_converter.py +280 -0
- notionary/blocks/rich_text/models.py +178 -0
- notionary/blocks/rich_text/name_id_resolver/__init__.py +13 -0
- notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -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 +144 -0
- notionary/blocks/rich_text/rich_text_patterns.py +42 -0
- notionary/blocks/schemas.py +778 -0
- notionary/comments/__init__.py +1 -22
- notionary/comments/client.py +52 -187
- notionary/comments/factory.py +38 -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 +104 -0
- notionary/data_source/properties/schemas.py +402 -0
- notionary/data_source/query/builder.py +448 -0
- notionary/data_source/query/resolver.py +114 -0
- notionary/data_source/query/schema.py +302 -0
- notionary/data_source/query/validator.py +73 -0
- notionary/data_source/schema/registry.py +104 -0
- notionary/data_source/schema/service.py +136 -0
- notionary/data_source/schemas.py +27 -0
- notionary/data_source/service.py +377 -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 +168 -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 +57 -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 +204 -0
- notionary/http/models.py +50 -0
- notionary/page/blocks/client.py +1 -0
- notionary/page/content/factory.py +73 -0
- notionary/page/content/markdown/__init__.py +5 -0
- notionary/page/content/markdown/builder.py +226 -0
- notionary/page/content/markdown/nodes/__init__.py +52 -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 +41 -0
- notionary/page/content/markdown/nodes/callout.py +34 -0
- notionary/page/content/markdown/nodes/code.py +28 -0
- notionary/page/content/markdown/nodes/columns.py +69 -0
- notionary/page/content/markdown/nodes/container.py +64 -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 +36 -0
- notionary/page/content/markdown/nodes/image.py +23 -0
- notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
- notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
- notionary/page/content/markdown/nodes/numbered_list.py +38 -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 +27 -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 +38 -0
- notionary/page/content/markdown/nodes/toggle.py +27 -0
- notionary/page/content/markdown/nodes/video.py +23 -0
- notionary/page/content/parser/context.py +126 -0
- notionary/page/content/parser/factory.py +210 -0
- notionary/page/content/parser/parsers/__init__.py +58 -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 +85 -0
- notionary/page/content/parser/parsers/callout.py +100 -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 +76 -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 +115 -0
- notionary/page/content/parser/parsers/image.py +42 -0
- notionary/page/content/parser/parsers/numbered_list.py +89 -0
- notionary/page/content/parser/parsers/paragraph.py +37 -0
- notionary/page/content/parser/parsers/pdf.py +42 -0
- notionary/page/content/parser/parsers/quote.py +125 -0
- notionary/page/content/parser/parsers/space.py +41 -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 +96 -0
- notionary/page/content/parser/parsers/toggle.py +70 -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 +95 -0
- notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +114 -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 +11 -0
- notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +130 -0
- notionary/page/content/parser/pre_processsing/handlers/indentation.py +84 -0
- notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
- notionary/page/content/parser/pre_processsing/handlers/whitespace.py +73 -0
- notionary/page/content/parser/pre_processsing/service.py +15 -0
- notionary/page/content/parser/service.py +78 -0
- notionary/page/content/renderer/context.py +51 -0
- notionary/page/content/renderer/factory.py +231 -0
- notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
- notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -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 +55 -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 +50 -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 +53 -0
- notionary/page/content/renderer/renderers/column_list.py +44 -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 +95 -0
- notionary/page/content/renderer/renderers/image.py +31 -0
- notionary/page/content/renderer/renderers/numbered_list.py +42 -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 +52 -0
- notionary/page/content/renderer/renderers/video.py +31 -0
- notionary/page/content/renderer/service.py +50 -0
- notionary/page/content/service.py +68 -0
- notionary/page/content/syntax/__init__.py +4 -0
- notionary/page/content/syntax/grammar.py +10 -0
- notionary/page/content/syntax/models.py +66 -0
- notionary/page/content/syntax/registry.py +393 -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 +308 -0
- notionary/page/properties/service.py +261 -0
- notionary/page/schemas.py +13 -0
- notionary/page/service.py +225 -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/shared/typings.py +3 -0
- notionary/user/__init__.py +4 -8
- notionary/user/base.py +138 -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/date.py +51 -0
- notionary/utils/decorators.py +122 -0
- notionary/utils/fuzzy.py +68 -0
- notionary/utils/mixins/logging.py +58 -0
- notionary/utils/pagination.py +100 -0
- notionary/utils/uuid_utils.py +20 -0
- notionary/workspace/__init__.py +4 -0
- notionary/workspace/client.py +62 -0
- notionary/workspace/query/__init__.py +3 -0
- notionary/workspace/query/builder.py +60 -0
- notionary/workspace/query/models.py +61 -0
- notionary/workspace/query/service.py +100 -0
- notionary/workspace/schemas.py +21 -0
- notionary/workspace/service.py +116 -0
- notionary-0.3.0.dist-info/METADATA +201 -0
- notionary-0.3.0.dist-info/RECORD +209 -0
- {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info}/WHEEL +1 -1
- {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info/licenses}/LICENSE +9 -9
- notionary/base_notion_client.py +0 -219
- 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/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/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 -712
- 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/logging_mixin.py +0 -59
- 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.27.dist-info/METADATA +0 -270
- notionary-0.2.27.dist-info/RECORD +0 -202
- /notionary/{database → user}/factory.py +0 -0
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.divider.divider_element import DividerElement
|
|
2
|
-
from notionary.blocks.divider.divider_markdown_node import (
|
|
3
|
-
DividerMarkdownNode,
|
|
4
|
-
)
|
|
5
|
-
from notionary.blocks.divider.divider_models import CreateDividerBlock, DividerBlock
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"DividerElement",
|
|
9
|
-
"DividerBlock",
|
|
10
|
-
"CreateDividerBlock",
|
|
11
|
-
"DividerMarkdownNode",
|
|
12
|
-
]
|
|
@@ -1,41 +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.divider.divider_models import CreateDividerBlock, DividerBlock
|
|
8
|
-
from notionary.blocks.models import Block, BlockCreateResult
|
|
9
|
-
from notionary.blocks.types import BlockType
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DividerElement(BaseBlockElement):
|
|
13
|
-
"""
|
|
14
|
-
Handles conversion between Markdown horizontal dividers and Notion divider blocks.
|
|
15
|
-
|
|
16
|
-
Markdown divider syntax:
|
|
17
|
-
- Three or more hyphens (---) on a line by themselves
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
PATTERN = re.compile(r"^\s*-{3,}\s*$")
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
def match_notion(cls, block: Block) -> bool:
|
|
24
|
-
"""Check if this element can handle the given Notion block."""
|
|
25
|
-
return block.type == BlockType.DIVIDER and block.divider
|
|
26
|
-
|
|
27
|
-
@classmethod
|
|
28
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
|
29
|
-
"""Convert markdown horizontal rule to Notion divider, with preceding empty paragraph."""
|
|
30
|
-
if not cls.PATTERN.match(text.strip()):
|
|
31
|
-
return None
|
|
32
|
-
|
|
33
|
-
divider = DividerBlock()
|
|
34
|
-
|
|
35
|
-
return CreateDividerBlock(divider=divider)
|
|
36
|
-
|
|
37
|
-
@classmethod
|
|
38
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
|
39
|
-
if block.type != BlockType.DIVIDER or not block.divider:
|
|
40
|
-
return None
|
|
41
|
-
return "---"
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class DividerMarkdownNode(MarkdownNode):
|
|
5
|
-
"""
|
|
6
|
-
Enhanced Divider node with Pydantic integration.
|
|
7
|
-
Programmatic interface for creating Markdown divider lines (---).
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def to_markdown(self) -> str:
|
|
11
|
-
return "---"
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.embed.embed_element import EmbedElement
|
|
2
|
-
from notionary.blocks.embed.embed_markdown_node import (
|
|
3
|
-
EmbedMarkdownNode,
|
|
4
|
-
)
|
|
5
|
-
from notionary.blocks.embed.embed_models import CreateEmbedBlock, EmbedBlock
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"EmbedElement",
|
|
9
|
-
"EmbedBlock",
|
|
10
|
-
"CreateEmbedBlock",
|
|
11
|
-
"EmbedMarkdownNode",
|
|
12
|
-
]
|
|
@@ -1,98 +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.embed.embed_models import CreateEmbedBlock, EmbedBlock
|
|
8
|
-
from notionary.blocks.file.file_element_models import (
|
|
9
|
-
ExternalFile,
|
|
10
|
-
FileUploadFile,
|
|
11
|
-
NotionHostedFile,
|
|
12
|
-
)
|
|
13
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
|
14
|
-
from notionary.blocks.models import Block, BlockCreateResult, BlockType
|
|
15
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
|
16
|
-
from notionary.blocks.rich_text.text_inline_formatter import TextInlineFormatter
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class EmbedElement(BaseBlockElement):
|
|
20
|
-
"""
|
|
21
|
-
Handles conversion between Markdown embeds and Notion embed blocks.
|
|
22
|
-
|
|
23
|
-
Markdown embed syntax:
|
|
24
|
-
- [embed](https://example.com) - URL only
|
|
25
|
-
- [embed](https://example.com "Caption") - URL + caption
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
PATTERN = re.compile(
|
|
29
|
-
r"^\[embed\]\(" # prefix
|
|
30
|
-
r"(https?://[^\s\"]+)" # URL
|
|
31
|
-
r"(?:\s+\"([^\"]+)\")?" # optional caption
|
|
32
|
-
r"\)$"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
@classmethod
|
|
36
|
-
def match_notion(cls, block: Block) -> bool:
|
|
37
|
-
return block.type == BlockType.EMBED and block.embed
|
|
38
|
-
|
|
39
|
-
@classmethod
|
|
40
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
|
41
|
-
"""Convert markdown embed syntax to Notion EmbedBlock."""
|
|
42
|
-
match = cls.PATTERN.match(text.strip())
|
|
43
|
-
if not match:
|
|
44
|
-
return None
|
|
45
|
-
|
|
46
|
-
url, rich_text = match.group(1), match.group(2) or ""
|
|
47
|
-
|
|
48
|
-
# Build EmbedBlock
|
|
49
|
-
embed_block = EmbedBlock(url=url, caption=[])
|
|
50
|
-
if rich_text.strip():
|
|
51
|
-
rich_text_obj = RichTextObject.from_plain_text(rich_text.strip())
|
|
52
|
-
embed_block.caption = [rich_text_obj]
|
|
53
|
-
|
|
54
|
-
return CreateEmbedBlock(embed=embed_block)
|
|
55
|
-
|
|
56
|
-
@classmethod
|
|
57
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
|
58
|
-
if block.type != BlockType.EMBED or not block.embed:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
fo = block.embed
|
|
62
|
-
|
|
63
|
-
if isinstance(fo, (ExternalFile, NotionHostedFile)):
|
|
64
|
-
url = fo.url
|
|
65
|
-
elif isinstance(fo, FileUploadFile):
|
|
66
|
-
return None
|
|
67
|
-
else:
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
|
-
if not fo.caption:
|
|
71
|
-
return f"[embed]({url})"
|
|
72
|
-
|
|
73
|
-
text_parts = []
|
|
74
|
-
for rt in fo.caption:
|
|
75
|
-
if rt.plain_text:
|
|
76
|
-
text_parts.append(rt.plain_text)
|
|
77
|
-
else:
|
|
78
|
-
formatted_text = await TextInlineFormatter.extract_text_with_formatting(
|
|
79
|
-
[rt]
|
|
80
|
-
)
|
|
81
|
-
text_parts.append(formatted_text)
|
|
82
|
-
text = "".join(text_parts)
|
|
83
|
-
|
|
84
|
-
return f'[embed]({url} "{text}")'
|
|
85
|
-
|
|
86
|
-
@classmethod
|
|
87
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
|
88
|
-
"""Get system prompt information for embed blocks."""
|
|
89
|
-
return BlockElementMarkdownInformation(
|
|
90
|
-
block_type=cls.__name__,
|
|
91
|
-
description="Embed blocks display interactive content from external URLs like videos, maps, or widgets",
|
|
92
|
-
syntax_examples=[
|
|
93
|
-
"[embed](https://youtube.com/watch?v=123)",
|
|
94
|
-
'[embed](https://maps.google.com/location "Map Location")',
|
|
95
|
-
'[embed](https://codepen.io/pen/123 "Interactive Demo")',
|
|
96
|
-
],
|
|
97
|
-
usage_guidelines="Use for embedding interactive content that supports iframe embedding. URL must be from a supported platform. Caption describes the embedded content.",
|
|
98
|
-
)
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EmbedMarkdownNode(MarkdownNode):
|
|
7
|
-
"""
|
|
8
|
-
Enhanced Embed node with Pydantic integration.
|
|
9
|
-
Programmatic interface for creating Notion-style Markdown embed blocks.
|
|
10
|
-
Example: [embed](https://example.com "Optional caption")
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
url: str
|
|
14
|
-
caption: Optional[str] = None
|
|
15
|
-
|
|
16
|
-
def to_markdown(self) -> str:
|
|
17
|
-
if self.caption:
|
|
18
|
-
return f'[embed]({self.url} "{self.caption}")'
|
|
19
|
-
return f"[embed]({self.url})"
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
from typing_extensions import Literal
|
|
3
|
-
|
|
4
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class EmbedBlock(BaseModel):
|
|
8
|
-
url: str
|
|
9
|
-
caption: list[RichTextObject] = Field(default_factory=list)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class CreateEmbedBlock(BaseModel):
|
|
13
|
-
type: Literal["embed"] = "embed"
|
|
14
|
-
embed: EmbedBlock
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.equation.equation_element import EquationElement
|
|
2
|
-
from notionary.blocks.equation.equation_element_markdown_node import (
|
|
3
|
-
EquationMarkdownNode,
|
|
4
|
-
)
|
|
5
|
-
from notionary.blocks.equation.equation_models import CreateEquationBlock, EquationBlock
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"EquationElement",
|
|
9
|
-
"EquationBlock",
|
|
10
|
-
"CreateEquationBlock",
|
|
11
|
-
"EquationMarkdownNode",
|
|
12
|
-
"EquationMarkdownBlockParams",
|
|
13
|
-
]
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
import textwrap
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from notionary.blocks.base_block_element import BaseBlockElement
|
|
8
|
-
from notionary.blocks.equation.equation_models import CreateEquationBlock, EquationBlock
|
|
9
|
-
from notionary.blocks.syntax_prompt_builder import BlockElementMarkdownInformation
|
|
10
|
-
from notionary.blocks.models import Block, BlockCreateResult
|
|
11
|
-
from notionary.blocks.types import BlockType
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class EquationElement(BaseBlockElement):
|
|
15
|
-
"""
|
|
16
|
-
Supports standard Markdown equation syntax:
|
|
17
|
-
|
|
18
|
-
- $$E = mc^2$$ # simple equations
|
|
19
|
-
- $$E = mc^2 + \\frac{a}{b}$$ # complex equations with LaTeX
|
|
20
|
-
|
|
21
|
-
Uses $$...$$ parsing for block equations.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
_EQUATION_PATTERN = re.compile(
|
|
25
|
-
r"^\$\$\s*(?P<expression>.*?)\s*\$\$$",
|
|
26
|
-
re.DOTALL,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
@classmethod
|
|
30
|
-
def match_notion(cls, block: Block) -> bool:
|
|
31
|
-
return block.type == BlockType.EQUATION and block.equation
|
|
32
|
-
|
|
33
|
-
@classmethod
|
|
34
|
-
async def markdown_to_notion(cls, text: str) -> BlockCreateResult:
|
|
35
|
-
input_text = text.strip()
|
|
36
|
-
|
|
37
|
-
equation_match = cls._EQUATION_PATTERN.match(input_text)
|
|
38
|
-
if not equation_match:
|
|
39
|
-
return None
|
|
40
|
-
|
|
41
|
-
expression = equation_match.group("expression").strip()
|
|
42
|
-
if not expression:
|
|
43
|
-
return None
|
|
44
|
-
|
|
45
|
-
return CreateEquationBlock(equation=EquationBlock(expression=expression))
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def create_from_markdown_block(
|
|
49
|
-
cls, opening_line: str, equation_lines: list[str]
|
|
50
|
-
) -> BlockCreateResult:
|
|
51
|
-
"""
|
|
52
|
-
Create a complete equation block from markdown components.
|
|
53
|
-
Handles multiline equations like:
|
|
54
|
-
$$
|
|
55
|
-
some
|
|
56
|
-
inline formula here
|
|
57
|
-
$$
|
|
58
|
-
|
|
59
|
-
Automatically handles:
|
|
60
|
-
- Indentation removal from multiline strings
|
|
61
|
-
- Single backslash conversion to double backslash for LaTeX line breaks
|
|
62
|
-
"""
|
|
63
|
-
# Check if opening line is just $$
|
|
64
|
-
if opening_line.strip() != "$$":
|
|
65
|
-
return None
|
|
66
|
-
|
|
67
|
-
# Process equation lines if any exist
|
|
68
|
-
if equation_lines:
|
|
69
|
-
# Remove common indentation from all lines
|
|
70
|
-
raw_content = "\n".join(equation_lines)
|
|
71
|
-
dedented_content = textwrap.dedent(raw_content)
|
|
72
|
-
|
|
73
|
-
# Fix single backslashes at line ends for LaTeX line breaks
|
|
74
|
-
fixed_lines = cls._fix_latex_line_breaks(dedented_content.splitlines())
|
|
75
|
-
expression = "\n".join(fixed_lines).strip()
|
|
76
|
-
|
|
77
|
-
if expression:
|
|
78
|
-
return CreateEquationBlock(
|
|
79
|
-
equation=EquationBlock(expression=expression)
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
return None
|
|
83
|
-
|
|
84
|
-
@classmethod
|
|
85
|
-
def _fix_latex_line_breaks(cls, lines: list[str]) -> list[str]:
|
|
86
|
-
"""
|
|
87
|
-
Fix lines that end with single backslashes by converting them to double backslashes.
|
|
88
|
-
This makes LaTeX line breaks work correctly when users write single backslashes.
|
|
89
|
-
|
|
90
|
-
Examples:
|
|
91
|
-
- "a = b + c \" -> "a = b + c \\"
|
|
92
|
-
- "a = b + c \\\\" -> "a = b + c \\\\" (unchanged)
|
|
93
|
-
"""
|
|
94
|
-
fixed_lines = []
|
|
95
|
-
|
|
96
|
-
for line in lines:
|
|
97
|
-
# Check if line ends with backslashes
|
|
98
|
-
backslash_match = re.search(r"(\\+)$", line)
|
|
99
|
-
if backslash_match:
|
|
100
|
-
backslashes = backslash_match.group(1)
|
|
101
|
-
# If odd number of backslashes, the last one needs to be doubled
|
|
102
|
-
if len(backslashes) % 2 == 1:
|
|
103
|
-
line = line + "\\"
|
|
104
|
-
|
|
105
|
-
fixed_lines.append(line)
|
|
106
|
-
|
|
107
|
-
return fixed_lines
|
|
108
|
-
|
|
109
|
-
@classmethod
|
|
110
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
|
111
|
-
if block.type != BlockType.EQUATION or not block.equation:
|
|
112
|
-
return None
|
|
113
|
-
|
|
114
|
-
expression = (block.equation.expression or "").strip()
|
|
115
|
-
if not expression:
|
|
116
|
-
return None
|
|
117
|
-
|
|
118
|
-
return f"$${expression}$$"
|
|
119
|
-
|
|
120
|
-
@classmethod
|
|
121
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
|
122
|
-
"""Get system prompt information for equation blocks."""
|
|
123
|
-
return BlockElementMarkdownInformation(
|
|
124
|
-
block_type=cls.__name__,
|
|
125
|
-
description="Mathematical equations using standard Markdown LaTeX syntax",
|
|
126
|
-
syntax_examples=[
|
|
127
|
-
"$$E = mc^2$$",
|
|
128
|
-
"$$\\frac{a}{b} + \\sqrt{c}$$",
|
|
129
|
-
"$$\\int_0^\\infty e^{-x} dx = 1$$",
|
|
130
|
-
"$$\\sum_{i=1}^n i = \\frac{n(n+1)}{2}$$",
|
|
131
|
-
],
|
|
132
|
-
usage_guidelines="Use for mathematical expressions and formulas. Supports LaTeX syntax. Wrap equations in double dollar signs ($$).",
|
|
133
|
-
)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.markdown.markdown_node import MarkdownNode
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class EquationMarkdownNode(MarkdownNode):
|
|
5
|
-
"""
|
|
6
|
-
Enhanced Equation node with Pydantic integration.
|
|
7
|
-
Programmatic interface for creating Markdown equation blocks.
|
|
8
|
-
Uses standard Markdown equation syntax with double dollar signs.
|
|
9
|
-
|
|
10
|
-
Examples:
|
|
11
|
-
$$E = mc^2$$
|
|
12
|
-
$$\\frac{a}{b} + \\sqrt{c}$$
|
|
13
|
-
$$\\int_0^\\infty e^{-x} dx = 1$$
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
expression: str
|
|
17
|
-
|
|
18
|
-
def to_markdown(self) -> str:
|
|
19
|
-
expr = self.expression.strip()
|
|
20
|
-
if not expr:
|
|
21
|
-
return "$$$$"
|
|
22
|
-
|
|
23
|
-
return f"$${expr}$$"
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.file.file_element import FileElement
|
|
2
|
-
from notionary.blocks.file.file_element_markdown_node import (
|
|
3
|
-
FileMarkdownNode,
|
|
4
|
-
)
|
|
5
|
-
from notionary.blocks.file.file_element_models import (
|
|
6
|
-
CreateFileBlock,
|
|
7
|
-
ExternalFile,
|
|
8
|
-
FileBlock,
|
|
9
|
-
FileType,
|
|
10
|
-
FileUploadFile,
|
|
11
|
-
NotionHostedFile,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
__all__ = [
|
|
15
|
-
"FileElement",
|
|
16
|
-
"FileType",
|
|
17
|
-
"ExternalFile",
|
|
18
|
-
"NotionHostedFile",
|
|
19
|
-
"FileUploadFile",
|
|
20
|
-
"FileBlock",
|
|
21
|
-
"CreateFileBlock",
|
|
22
|
-
"FileMarkdownNode",
|
|
23
|
-
]
|
|
@@ -1,133 +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.base_block_element import BaseBlockElement
|
|
8
|
-
from notionary.blocks.file.file_element_models import (
|
|
9
|
-
CreateFileBlock,
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
class FileElement(BaseBlockElement, CaptionMixin, FileUploadMixin):
|
|
22
|
-
r"""
|
|
23
|
-
Handles conversion between Markdown file embeds and Notion file blocks.
|
|
24
|
-
|
|
25
|
-
Supports both external URLs and local file uploads.
|
|
26
|
-
|
|
27
|
-
Markdown file syntax:
|
|
28
|
-
- [file](https://example.com/document.pdf) - External URL
|
|
29
|
-
- [file](./local/document.pdf) - Local file (will be uploaded)
|
|
30
|
-
- [file](C:\Documents\report.pdf) - Absolute local path (will be uploaded)
|
|
31
|
-
- [file](https://example.com/document.pdf)(caption:Annual Report) - With caption
|
|
32
|
-
- (caption:Important document)[file](./doc.pdf) - Caption before URL
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
FILE_PATTERN = re.compile(r"\[file\]\(([^)]+)\)")
|
|
36
|
-
|
|
37
|
-
@classmethod
|
|
38
|
-
def match_notion(cls, block: Block) -> bool:
|
|
39
|
-
return bool(block.type == BlockType.FILE and block.file)
|
|
40
|
-
|
|
41
|
-
@classmethod
|
|
42
|
-
async def markdown_to_notion(cls, text: str) -> Optional[BlockCreateResult]:
|
|
43
|
-
"""Convert markdown file link to Notion FileBlock."""
|
|
44
|
-
file_path = cls._extract_file_path(text.strip())
|
|
45
|
-
if not file_path:
|
|
46
|
-
return None
|
|
47
|
-
|
|
48
|
-
cls.logger.info(f"Processing file: {file_path}")
|
|
49
|
-
|
|
50
|
-
# Extract caption
|
|
51
|
-
caption_text = cls.extract_caption(text.strip())
|
|
52
|
-
caption_rich_text = cls.build_caption_rich_text(caption_text or "")
|
|
53
|
-
|
|
54
|
-
# Determine if it's a local file or external URL
|
|
55
|
-
if cls._is_local_file_path(file_path):
|
|
56
|
-
cls.logger.debug(f"Detected local file: {file_path}")
|
|
57
|
-
|
|
58
|
-
# Upload the local file using mixin method
|
|
59
|
-
file_upload_id = await cls._upload_local_file(file_path, "file")
|
|
60
|
-
if not file_upload_id:
|
|
61
|
-
cls.logger.error(f"Failed to upload file: {file_path}")
|
|
62
|
-
return None
|
|
63
|
-
|
|
64
|
-
# Create FILE_UPLOAD block
|
|
65
|
-
file_block = FileBlock(
|
|
66
|
-
type=FileType.FILE_UPLOAD,
|
|
67
|
-
file_upload=FileUploadFile(id=file_upload_id),
|
|
68
|
-
caption=caption_rich_text,
|
|
69
|
-
name=Path(file_path).name,
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
else:
|
|
73
|
-
cls.logger.debug(f"Using external URL: {file_path}")
|
|
74
|
-
|
|
75
|
-
file_block = FileBlock(
|
|
76
|
-
type=FileType.EXTERNAL,
|
|
77
|
-
external=ExternalFile(url=file_path),
|
|
78
|
-
caption=caption_rich_text,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
return CreateFileBlock(file=file_block)
|
|
82
|
-
|
|
83
|
-
@classmethod
|
|
84
|
-
async def notion_to_markdown(cls, block: Block) -> Optional[str]:
|
|
85
|
-
if block.type != BlockType.FILE or not block.file:
|
|
86
|
-
return None
|
|
87
|
-
|
|
88
|
-
fb: FileBlock = block.file
|
|
89
|
-
|
|
90
|
-
# Determine the source for markdown
|
|
91
|
-
if fb.type == FileType.EXTERNAL and fb.external:
|
|
92
|
-
source = fb.external.url
|
|
93
|
-
elif fb.type == FileType.FILE and fb.file:
|
|
94
|
-
source = fb.file.url
|
|
95
|
-
else:
|
|
96
|
-
return None
|
|
97
|
-
|
|
98
|
-
result = f"[file]({source})"
|
|
99
|
-
|
|
100
|
-
# Add caption if present
|
|
101
|
-
caption_markdown = await cls.format_caption_for_markdown(fb.caption or [])
|
|
102
|
-
if caption_markdown:
|
|
103
|
-
result += caption_markdown
|
|
104
|
-
|
|
105
|
-
return result
|
|
106
|
-
|
|
107
|
-
@classmethod
|
|
108
|
-
def get_system_prompt_information(cls) -> Optional[BlockElementMarkdownInformation]:
|
|
109
|
-
"""Get system prompt information for file blocks."""
|
|
110
|
-
return BlockElementMarkdownInformation(
|
|
111
|
-
block_type=cls.__name__,
|
|
112
|
-
description="File blocks embed files from external URLs or upload local files with optional captions",
|
|
113
|
-
syntax_examples=[
|
|
114
|
-
"[file](https://example.com/document.pdf)",
|
|
115
|
-
"[file](./local/document.pdf)",
|
|
116
|
-
"[file](C:\\Documents\\report.xlsx)",
|
|
117
|
-
"[file](https://example.com/document.pdf)(caption:Annual Report)",
|
|
118
|
-
"(caption:Q1 Data)[file](./spreadsheet.xlsx)",
|
|
119
|
-
"[file](./manual.docx)(caption:**User** manual)",
|
|
120
|
-
],
|
|
121
|
-
usage_guidelines="Use for both external URLs and local files. Local files will be automatically uploaded to Notion. Supports various file formats including PDFs, documents, spreadsheets, images. Caption supports rich text formatting and should describe the file content or purpose.",
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
@classmethod
|
|
125
|
-
def _extract_file_path(cls, text: str) -> Optional[str]:
|
|
126
|
-
"""Extract file path/URL from text, handling caption patterns."""
|
|
127
|
-
clean_text = cls.remove_caption(text)
|
|
128
|
-
|
|
129
|
-
match = cls.FILE_PATTERN.search(clean_text)
|
|
130
|
-
if match:
|
|
131
|
-
return match.group(1).strip()
|
|
132
|
-
|
|
133
|
-
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 FileMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
|
|
8
|
-
"""
|
|
9
|
-
Enhanced File node with Pydantic integration.
|
|
10
|
-
Programmatic interface for creating Notion-style Markdown file embeds.
|
|
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
|
-
- [file](https://example.com/document.pdf)
|
|
21
|
-
- [file](https://example.com/document.pdf)(caption:User manual)
|
|
22
|
-
"""
|
|
23
|
-
base_markdown = f"[file]({self.url})"
|
|
24
|
-
return self.append_caption_to_markdown(base_markdown, self.caption)
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
|
-
from typing import Literal, Optional
|
|
3
|
-
|
|
4
|
-
from pydantic import BaseModel, Field
|
|
5
|
-
|
|
6
|
-
from notionary.blocks.rich_text.rich_text_models import RichTextObject
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class FileType(str, Enum):
|
|
10
|
-
EXTERNAL = "external"
|
|
11
|
-
FILE = "file"
|
|
12
|
-
FILE_UPLOAD = "file_upload"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ExternalFile(BaseModel):
|
|
16
|
-
url: str
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class NotionHostedFile(BaseModel):
|
|
20
|
-
url: str
|
|
21
|
-
expiry_time: str
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class FileUploadFile(BaseModel):
|
|
25
|
-
id: str
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class FileBlock(BaseModel):
|
|
29
|
-
caption: list[RichTextObject] = Field(default_factory=list)
|
|
30
|
-
type: FileType
|
|
31
|
-
external: Optional[ExternalFile] = None
|
|
32
|
-
file: Optional[NotionHostedFile] = None
|
|
33
|
-
file_upload: Optional[FileUploadFile] = None
|
|
34
|
-
name: Optional[str] = None
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class CreateFileBlock(BaseModel):
|
|
38
|
-
type: Literal["file"] = "file"
|
|
39
|
-
file: FileBlock
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from notionary.blocks.heading.heading_element import HeadingElement
|
|
2
|
-
from notionary.blocks.heading.heading_markdown_node import (
|
|
3
|
-
HeadingMarkdownNode,
|
|
4
|
-
)
|
|
5
|
-
from notionary.blocks.heading.heading_models import (
|
|
6
|
-
CreateHeading1Block,
|
|
7
|
-
CreateHeading2Block,
|
|
8
|
-
CreateHeading3Block,
|
|
9
|
-
HeadingBlock,
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
__all__ = [
|
|
13
|
-
"HeadingElement",
|
|
14
|
-
"HeadingBlock",
|
|
15
|
-
"CreateHeading1Block",
|
|
16
|
-
"CreateHeading2Block",
|
|
17
|
-
"CreateHeading3Block",
|
|
18
|
-
"HeadingMarkdownNode",
|
|
19
|
-
]
|