notionary 0.1.13__py3-none-any.whl → 0.1.14__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 +2 -2
- notionary/{converters/elements → elements}/audio_element.py +1 -1
- notionary/{converters/registry → elements}/block_element_registry.py +2 -5
- notionary/elements/block_element_registry_builder.py +401 -0
- notionary/{converters/elements → elements}/bookmark_element.py +1 -1
- notionary/{converters/elements → elements}/callout_element.py +2 -2
- notionary/{converters/elements → elements}/code_block_element.py +1 -1
- notionary/{converters/elements → elements}/column_element.py +1 -1
- notionary/{converters/elements → elements}/divider_element.py +1 -1
- notionary/{converters/elements → elements}/embed_element.py +1 -1
- notionary/{converters/elements → elements}/heading_element.py +2 -2
- notionary/{converters/elements → elements}/image_element.py +1 -1
- notionary/{converters/elements → elements}/list_element.py +2 -2
- notionary/elements/mention_element.py +135 -0
- notionary/{converters/elements → elements}/paragraph_element.py +2 -2
- notionary/{converters/elements → elements}/qoute_element.py +1 -1
- notionary/{converters/elements → elements}/table_element.py +2 -2
- notionary/{converters/elements → elements}/todo_lists.py +2 -2
- notionary/{converters/elements → elements}/toggle_element.py +1 -1
- notionary/{converters/elements → elements}/video_element.py +1 -1
- notionary/notion_client.py +0 -1
- notionary/page/content/page_content_manager.py +4 -3
- notionary/{converters → page}/markdown_to_notion_converter.py +2 -4
- notionary/page/notion_page.py +23 -5
- notionary/page/notion_page_factory.py +1 -15
- notionary/page/notion_to_markdown_converter.py +245 -0
- {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/METADATA +1 -1
- notionary-0.1.14.dist-info/RECORD +56 -0
- notionary/converters/__init__.py +0 -50
- notionary/converters/notion_to_markdown_converter.py +0 -45
- notionary/converters/registry/block_element_registry_builder.py +0 -284
- notionary-0.1.13.dist-info/RECORD +0 -56
- /notionary/{converters/elements → elements}/notion_block_element.py +0 -0
- /notionary/{converters/elements → elements}/text_inline_formatter.py +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/WHEEL +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/licenses/LICENSE +0 -0
- {notionary-0.1.13.dist-info → notionary-0.1.14.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ import re
|
|
2
2
|
from typing import Dict, Any, Optional, List, Tuple
|
3
3
|
from typing_extensions import override
|
4
4
|
|
5
|
-
from notionary.
|
5
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
6
6
|
|
7
7
|
|
8
8
|
class QuoteElement(NotionBlockElement):
|
@@ -3,8 +3,8 @@
|
|
3
3
|
from typing import Dict, Any, Optional, List, Tuple
|
4
4
|
from typing_extensions import override
|
5
5
|
import re
|
6
|
-
from notionary.
|
7
|
-
from notionary.
|
6
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
7
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
8
8
|
|
9
9
|
|
10
10
|
class TableElement(NotionBlockElement):
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Dict, Any, Optional
|
3
3
|
from typing_extensions import override
|
4
|
-
from notionary.
|
5
|
-
from notionary.
|
4
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
5
|
+
from notionary.elements.text_inline_formatter import TextInlineFormatter
|
6
6
|
|
7
7
|
|
8
8
|
class TodoElement(NotionBlockElement):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Dict, Any, Optional, List, Tuple, Callable
|
3
3
|
|
4
|
-
from notionary.
|
4
|
+
from notionary.elements.notion_block_element import NotionBlockElement
|
5
5
|
|
6
6
|
|
7
7
|
class ToggleElement(NotionBlockElement):
|
notionary/notion_client.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
+
import json
|
1
2
|
from typing import Any, Dict, List, Optional
|
2
3
|
|
4
|
+
from notionary.elements.block_element_registry import BlockElementRegistry
|
3
5
|
from notionary.notion_client import NotionClient
|
4
|
-
from notionary.converters.registry.block_element_registry import BlockElementRegistry
|
5
6
|
|
6
|
-
from notionary.
|
7
|
+
from notionary.page.markdown_to_notion_converter import (
|
7
8
|
MarkdownToNotionConverter,
|
8
9
|
)
|
9
|
-
from notionary.
|
10
|
+
from notionary.page.notion_to_markdown_converter import (
|
10
11
|
NotionToMarkdownConverter,
|
11
12
|
)
|
12
13
|
from notionary.page.content.notion_page_content_chunker import (
|
@@ -1,9 +1,7 @@
|
|
1
1
|
from typing import Dict, Any, List, Optional, Tuple
|
2
2
|
|
3
|
-
from notionary.
|
4
|
-
|
5
|
-
)
|
6
|
-
from notionary.converters.registry.block_element_registry_builder import (
|
3
|
+
from notionary.elements.block_element_registry import BlockElementRegistry
|
4
|
+
from notionary.elements.block_element_registry_builder import (
|
7
5
|
BlockElementRegistryBuilder,
|
8
6
|
)
|
9
7
|
|
notionary/page/notion_page.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Any, Dict, List, Optional, Union
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
from notionary.converters.registry.block_element_registry_builder import (
|
3
|
+
|
4
|
+
from notionary.elements.block_element_registry import BlockElementRegistry
|
5
|
+
from notionary.elements.block_element_registry_builder import (
|
7
6
|
BlockElementRegistryBuilder,
|
8
7
|
)
|
9
8
|
from notionary.notion_client import NotionClient
|
@@ -412,6 +411,25 @@ class NotionPage(LoggingMixin):
|
|
412
411
|
"""
|
413
412
|
return await self._relation_manager.get_all_relations()
|
414
413
|
|
414
|
+
async def get_last_edited_time(self) -> str:
|
415
|
+
"""
|
416
|
+
Get the timestamp when the page was last edited.
|
417
|
+
|
418
|
+
Returns:
|
419
|
+
str: ISO 8601 formatted timestamp string of when the page was last edited.
|
420
|
+
"""
|
421
|
+
try:
|
422
|
+
page_data = await self._client.get_page(self._page_id)
|
423
|
+
if "last_edited_time" in page_data:
|
424
|
+
return page_data["last_edited_time"]
|
425
|
+
|
426
|
+
self.logger.warning("last_edited_time not found in page data")
|
427
|
+
return ""
|
428
|
+
|
429
|
+
except Exception as e:
|
430
|
+
self.logger.error("Error retrieving last edited time: %s", str(e))
|
431
|
+
return ""
|
432
|
+
|
415
433
|
async def _load_page_title(self) -> str:
|
416
434
|
"""
|
417
435
|
Load the page title from Notion API if not already loaded.
|
@@ -483,7 +501,7 @@ class NotionPage(LoggingMixin):
|
|
483
501
|
clean_id = self._page_id.replace("-", "")
|
484
502
|
|
485
503
|
return f"https://www.notion.so/{url_title}{clean_id}"
|
486
|
-
|
504
|
+
|
487
505
|
async def _get_db_property_service(self) -> Optional[DatabasePropertyService]:
|
488
506
|
"""
|
489
507
|
Gets the database property service, initializing it if necessary.
|
@@ -176,9 +176,7 @@ class NotionPageFactory(LoggingMixin):
|
|
176
176
|
best_score,
|
177
177
|
)
|
178
178
|
|
179
|
-
page = NotionPage(
|
180
|
-
page_id=page_id, title=matched_name, token=token
|
181
|
-
)
|
179
|
+
page = NotionPage(page_id=page_id, title=matched_name, token=token)
|
182
180
|
|
183
181
|
logger.info("Successfully created page instance for '%s'", matched_name)
|
184
182
|
await client.close()
|
@@ -242,15 +240,3 @@ class NotionPageFactory(LoggingMixin):
|
|
242
240
|
text_parts.append(text_obj["plain_text"])
|
243
241
|
|
244
242
|
return "".join(text_parts)
|
245
|
-
|
246
|
-
|
247
|
-
async def demo():
|
248
|
-
clipboard = await NotionPageFactory.from_page_name("Jarvis Clipboard")
|
249
|
-
icon = await clipboard.get_icon()
|
250
|
-
print(f"Icon: {icon}")
|
251
|
-
|
252
|
-
|
253
|
-
if __name__ == "__main__":
|
254
|
-
import asyncio
|
255
|
-
|
256
|
-
asyncio.run(demo())
|
@@ -0,0 +1,245 @@
|
|
1
|
+
from typing import Dict, Any, List, Optional
|
2
|
+
|
3
|
+
from notionary.elements.block_element_registry import (
|
4
|
+
BlockElementRegistry,
|
5
|
+
)
|
6
|
+
from notionary.elements.block_element_registry_builder import (
|
7
|
+
BlockElementRegistryBuilder,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
class NotionToMarkdownConverter:
|
12
|
+
"""Converts Notion blocks to Markdown text with support for nested structures."""
|
13
|
+
|
14
|
+
def __init__(self, block_registry: Optional[BlockElementRegistry] = None):
|
15
|
+
"""
|
16
|
+
Initialize the NotionToMarkdownConverter.
|
17
|
+
|
18
|
+
Args:
|
19
|
+
block_registry: Optional registry of Notion block elements
|
20
|
+
"""
|
21
|
+
self._block_registry = (
|
22
|
+
block_registry or BlockElementRegistryBuilder().create_standard_registry()
|
23
|
+
)
|
24
|
+
|
25
|
+
def convert(self, blocks: List[Dict[str, Any]]) -> str:
|
26
|
+
"""
|
27
|
+
Convert Notion blocks to Markdown text, handling nested structures.
|
28
|
+
|
29
|
+
Args:
|
30
|
+
blocks: List of Notion blocks
|
31
|
+
|
32
|
+
Returns:
|
33
|
+
Markdown text
|
34
|
+
"""
|
35
|
+
if not blocks:
|
36
|
+
return ""
|
37
|
+
|
38
|
+
markdown_parts = []
|
39
|
+
|
40
|
+
for block in blocks:
|
41
|
+
block_markdown = self._convert_single_block_with_children(block)
|
42
|
+
if block_markdown:
|
43
|
+
markdown_parts.append(block_markdown)
|
44
|
+
|
45
|
+
return "\n\n".join(filter(None, markdown_parts))
|
46
|
+
|
47
|
+
def _convert_single_block_with_children(self, block: Dict[str, Any]) -> str:
|
48
|
+
"""
|
49
|
+
Process a single block, including any children.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
block: Notion block to process
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
Markdown representation of the block and its children
|
56
|
+
"""
|
57
|
+
if not block:
|
58
|
+
return ""
|
59
|
+
|
60
|
+
block_markdown = self._block_registry.notion_to_markdown(block)
|
61
|
+
|
62
|
+
if not self._has_children(block):
|
63
|
+
return block_markdown
|
64
|
+
|
65
|
+
children_markdown = self.convert(block["children"])
|
66
|
+
if not children_markdown:
|
67
|
+
return block_markdown
|
68
|
+
|
69
|
+
block_type = block.get("type", "")
|
70
|
+
|
71
|
+
if block_type == "toggle":
|
72
|
+
return self._format_toggle_with_children(block_markdown, children_markdown)
|
73
|
+
|
74
|
+
if block_type in ["numbered_list_item", "bulleted_list_item"]:
|
75
|
+
return self._format_list_item_with_children(block_markdown, children_markdown)
|
76
|
+
|
77
|
+
if block_type in ["column_list", "column"]:
|
78
|
+
return children_markdown
|
79
|
+
|
80
|
+
return self._format_standard_block_with_children(block_markdown, children_markdown)
|
81
|
+
|
82
|
+
def _has_children(self, block: Dict[str, Any]) -> bool:
|
83
|
+
"""
|
84
|
+
Check if block has children that need processing.
|
85
|
+
|
86
|
+
Args:
|
87
|
+
block: Notion block to check
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
True if block has children to process
|
91
|
+
"""
|
92
|
+
return block.get("has_children", False) and "children" in block
|
93
|
+
|
94
|
+
def _format_toggle_with_children(self, toggle_markdown: str, children_markdown: str) -> str:
|
95
|
+
"""
|
96
|
+
Format toggle block with its children content.
|
97
|
+
|
98
|
+
Args:
|
99
|
+
toggle_markdown: Markdown for the toggle itself
|
100
|
+
children_markdown: Markdown for toggle's children
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
Formatted markdown with indented children
|
104
|
+
"""
|
105
|
+
indented_children = self._indent_text(children_markdown)
|
106
|
+
return f"{toggle_markdown}\n{indented_children}"
|
107
|
+
|
108
|
+
def _format_list_item_with_children(self, item_markdown: str, children_markdown: str) -> str:
|
109
|
+
"""
|
110
|
+
Format list item with its children content.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
item_markdown: Markdown for the list item itself
|
114
|
+
children_markdown: Markdown for item's children
|
115
|
+
|
116
|
+
Returns:
|
117
|
+
Formatted markdown with indented children
|
118
|
+
"""
|
119
|
+
indented_children = self._indent_text(children_markdown)
|
120
|
+
return f"{item_markdown}\n{indented_children}"
|
121
|
+
|
122
|
+
def _format_standard_block_with_children(self, block_markdown: str, children_markdown: str) -> str:
|
123
|
+
"""
|
124
|
+
Format standard block with its children content.
|
125
|
+
|
126
|
+
Args:
|
127
|
+
block_markdown: Markdown for the block itself
|
128
|
+
children_markdown: Markdown for block's children
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
Formatted markdown with children after block
|
132
|
+
"""
|
133
|
+
return f"{block_markdown}\n\n{children_markdown}"
|
134
|
+
|
135
|
+
def _indent_text(self, text: str, spaces: int = 4) -> str:
|
136
|
+
"""
|
137
|
+
Indent each line of text with specified number of spaces.
|
138
|
+
|
139
|
+
Args:
|
140
|
+
text: Text to indent
|
141
|
+
spaces: Number of spaces to use for indentation
|
142
|
+
|
143
|
+
Returns:
|
144
|
+
Indented text
|
145
|
+
"""
|
146
|
+
indent = " " * spaces
|
147
|
+
return "\n".join([f"{indent}{line}" for line in text.split("\n")])
|
148
|
+
|
149
|
+
def extract_toggle_content(self, blocks: List[Dict[str, Any]]) -> str:
|
150
|
+
"""
|
151
|
+
Extract only the content of toggles from blocks.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
blocks: List of Notion blocks
|
155
|
+
|
156
|
+
Returns:
|
157
|
+
Markdown text with toggle contents
|
158
|
+
"""
|
159
|
+
if not blocks:
|
160
|
+
return ""
|
161
|
+
|
162
|
+
toggle_contents = []
|
163
|
+
|
164
|
+
for block in blocks:
|
165
|
+
self._extract_toggle_content_recursive(block, toggle_contents)
|
166
|
+
|
167
|
+
return "\n".join(toggle_contents)
|
168
|
+
|
169
|
+
def _extract_toggle_content_recursive(self, block: Dict[str, Any], result: List[str]) -> None:
|
170
|
+
"""
|
171
|
+
Recursively extract toggle content from a block and its children.
|
172
|
+
|
173
|
+
Args:
|
174
|
+
block: Block to process
|
175
|
+
result: List to collect toggle content
|
176
|
+
"""
|
177
|
+
if self._is_toggle_with_children(block):
|
178
|
+
self._add_toggle_header_to_result(block, result)
|
179
|
+
self._add_toggle_children_to_result(block, result)
|
180
|
+
|
181
|
+
if self._has_children(block):
|
182
|
+
for child in block["children"]:
|
183
|
+
self._extract_toggle_content_recursive(child, result)
|
184
|
+
|
185
|
+
def _is_toggle_with_children(self, block: Dict[str, Any]) -> bool:
|
186
|
+
"""
|
187
|
+
Check if block is a toggle with children.
|
188
|
+
|
189
|
+
Args:
|
190
|
+
block: Block to check
|
191
|
+
|
192
|
+
Returns:
|
193
|
+
True if block is a toggle with children
|
194
|
+
"""
|
195
|
+
return block.get("type") == "toggle" and "children" in block
|
196
|
+
|
197
|
+
def _add_toggle_header_to_result(self, block: Dict[str, Any], result: List[str]) -> None:
|
198
|
+
"""
|
199
|
+
Add toggle header text to result list.
|
200
|
+
|
201
|
+
Args:
|
202
|
+
block: Toggle block
|
203
|
+
result: List to add header to
|
204
|
+
"""
|
205
|
+
toggle_text = self._extract_text_from_rich_text(
|
206
|
+
block.get("toggle", {}).get("rich_text", [])
|
207
|
+
)
|
208
|
+
|
209
|
+
if toggle_text:
|
210
|
+
result.append(f"### {toggle_text}")
|
211
|
+
|
212
|
+
def _add_toggle_children_to_result(self, block: Dict[str, Any], result: List[str]) -> None:
|
213
|
+
"""
|
214
|
+
Add formatted toggle children to result list.
|
215
|
+
|
216
|
+
Args:
|
217
|
+
block: Toggle block with children
|
218
|
+
result: List to add children content to
|
219
|
+
"""
|
220
|
+
for child in block.get("children", []):
|
221
|
+
child_type = child.get("type")
|
222
|
+
if not (child_type and child_type in child):
|
223
|
+
continue
|
224
|
+
|
225
|
+
child_text = self._extract_text_from_rich_text(
|
226
|
+
child.get(child_type, {}).get("rich_text", [])
|
227
|
+
)
|
228
|
+
|
229
|
+
if child_text:
|
230
|
+
result.append(f"- {child_text}")
|
231
|
+
|
232
|
+
def _extract_text_from_rich_text(self, rich_text: List[Dict[str, Any]]) -> str:
|
233
|
+
"""
|
234
|
+
Extract plain text from Notion's rich text array.
|
235
|
+
|
236
|
+
Args:
|
237
|
+
rich_text: List of rich text objects
|
238
|
+
|
239
|
+
Returns:
|
240
|
+
Concatenated plain text
|
241
|
+
"""
|
242
|
+
if not rich_text:
|
243
|
+
return ""
|
244
|
+
|
245
|
+
return "".join([rt.get("plain_text", "") for rt in rich_text])
|
@@ -0,0 +1,56 @@
|
|
1
|
+
notionary/__init__.py,sha256=sVqdwzMQcc9jf6FKi1qflilsx8rnWzluVhWewVi5gyI,717
|
2
|
+
notionary/notion_client.py,sha256=gRyTBVuCZCQod6L18VxzKl38Tn5oXdE0gPl7yGG8anQ,4446
|
3
|
+
notionary/database/database_discovery.py,sha256=qDGFhXG9s-_6CXdRg8tMiwX4dvX7jLjgAUFPSNlYtlI,4506
|
4
|
+
notionary/database/database_info_service.py,sha256=Ig6gx8jUSPYORJvfgEV5kV6t72pZQsWU8HPMqd43B-o,1336
|
5
|
+
notionary/database/notion_database.py,sha256=RY5MlXNE5DVNWLC_Derljsz87ZMHkE-05Vgm80kvLxg,7250
|
6
|
+
notionary/database/notion_database_factory.py,sha256=Af57yaUHidD8TKJ8uyXOc2nnqHm7on6VGFdDRjxiq9o,6692
|
7
|
+
notionary/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
|
8
|
+
notionary/elements/audio_element.py,sha256=XLARz5zlPPW_Qof6uhcYXFmyYzyS1fLdxdfsvh6GMOs,5589
|
9
|
+
notionary/elements/block_element_registry.py,sha256=2mEbCEIPRY15qk6NYcq9vf7Bq_5vuu1xbiJatoLFf7w,8530
|
10
|
+
notionary/elements/block_element_registry_builder.py,sha256=qPIGCAdzeZ3Xubxp1tysH8DqJMPZ7q1VEl0AbCsS01s,12107
|
11
|
+
notionary/elements/bookmark_element.py,sha256=83ciz2THxjeq7ofn-Xz9sG1Ifzm_gkIDmOo0A-pNsSo,8577
|
12
|
+
notionary/elements/callout_element.py,sha256=K8yk7nE3WP8nskJKbMunkRDFlhSCXrONmYS6hELN6QE,5932
|
13
|
+
notionary/elements/code_block_element.py,sha256=wbW_PfH6QBUFVfeELESuLiI5-GmLm2YUFP4xwFHgNV4,5173
|
14
|
+
notionary/elements/column_element.py,sha256=F_hnaBtQbnfRiKRVfpo9X5aNiw75SxeHfWOiMyMPcBw,10706
|
15
|
+
notionary/elements/divider_element.py,sha256=RCN87xFizAjKd8c_beywNW5lfXFFtOZPT8tyXgAh2D0,2776
|
16
|
+
notionary/elements/embed_element.py,sha256=LZjbSfwq0v8NGzwfUXpnGwvJ34IjYDwZzqyxVd2Iqt8,4768
|
17
|
+
notionary/elements/heading_element.py,sha256=GsfEg5XtohmtO8PBP9giezIg6pRWQ_CdPXjh7jOiytw,2756
|
18
|
+
notionary/elements/image_element.py,sha256=663H_FzE_bsovps3uCV12trNTmMAWBu5Ko1tSBNu2V4,4845
|
19
|
+
notionary/elements/list_element.py,sha256=-f4mPRPesqFYYXfiiqGpnADeAY2ZAF1sTDtkLcejvLg,4846
|
20
|
+
notionary/elements/mention_element.py,sha256=vltFnUJs83tIezqevSrMzXhICZFWyA28zflWd0Dmr-E,5497
|
21
|
+
notionary/elements/notion_block_element.py,sha256=lLRBDXhBeRaRzkbvdpYpr-U9nbkd62oVtqdSe-svT4c,1746
|
22
|
+
notionary/elements/paragraph_element.py,sha256=ULSPcwy_JbnKdQkMy-xMs_KtYI8k5uxh6b4EGMNldTk,2734
|
23
|
+
notionary/elements/qoute_element.py,sha256=3I2a7KboPF5QF6afu99HSIa62YUNfDJ6oaSDgyc9NjA,9041
|
24
|
+
notionary/elements/table_element.py,sha256=jCq1ZFNCdxYEI6ER21OZ64TYGjW162gH-A6DUbldxY4,11222
|
25
|
+
notionary/elements/text_inline_formatter.py,sha256=FE_Sq2cozpu5RVtMbnPq21gD06UjH3LMRYr3s16JKYo,10606
|
26
|
+
notionary/elements/todo_lists.py,sha256=PrLZdp1-q1gx7mBsL6NUQ5U18HxmkUw8yqVh9qJpArE,4233
|
27
|
+
notionary/elements/toggle_element.py,sha256=5cyWjkBgJcKdhhdrOn4bEM8Dpc5gXWhVbM4qZm9FNYM,7242
|
28
|
+
notionary/elements/video_element.py,sha256=uYCwFakna7pzpCDjjtxRhUkSkPfzJTttdKUKYSluqyw,6031
|
29
|
+
notionary/exceptions/database_exceptions.py,sha256=I-Tx6bYRLpi5pjGPtbT-Mqxvz3BFgYTiuZxknJeLxtI,2638
|
30
|
+
notionary/exceptions/page_creation_exception.py,sha256=4v7IuZD6GsQLrqhDLriGjuG3ML638gAO53zDCrLePuU,281
|
31
|
+
notionary/page/markdown_to_notion_converter.py,sha256=wTkH7o6367IWBtSqBrldpKx4rxHli176QfWtAenyysQ,15067
|
32
|
+
notionary/page/notion_page.py,sha256=KIjVeiMJGWWxR6ty1uuNvMoQf2IoRmSUxwMdDIyOu40,17635
|
33
|
+
notionary/page/notion_page_factory.py,sha256=UUEZ-cyEWL0OMVPrgjc4vJdcplEa1bO2yHCYooACYC8,8189
|
34
|
+
notionary/page/notion_to_markdown_converter.py,sha256=RJn8JCcoAOGAhVtZGc4NL-puBnMAAm3udY9w-qIDMqo,8231
|
35
|
+
notionary/page/content/notion_page_content_chunker.py,sha256=xRks74Dqec-De6-AVTxMPnXs-MSJBzSm1HfJfaHiKr8,3330
|
36
|
+
notionary/page/content/page_content_manager.py,sha256=Z0zYWLzcoY0wijWhQT5KU8uxRnZZMJ7MgDKa4U5iBY4,3932
|
37
|
+
notionary/page/metadata/metadata_editor.py,sha256=61uiw8oB25O8ePhytoJvZDetuof5sjPoM6aoHZGo4wc,4949
|
38
|
+
notionary/page/metadata/notion_icon_manager.py,sha256=ixZrWsHGVpmF05Ncy9LCt8vZlKAQHYFZW-2yI5JZZDI,1426
|
39
|
+
notionary/page/metadata/notion_page_cover_manager.py,sha256=qgQxQE-bx4oWjLFUQvpXD5GzO1Mx7w7htz1xC2BOqUg,1717
|
40
|
+
notionary/page/properites/database_property_service.py,sha256=AJuBGahbb53VQa6IGGHxBMoOgCy6vFZg08uR_eDjNUs,11570
|
41
|
+
notionary/page/properites/page_property_manager.py,sha256=Xl8Cwn8WVszqpFXT_NvASkmP5igpCTEgRVhG_F45424,6914
|
42
|
+
notionary/page/properites/property_formatter.py,sha256=d_Nr5XQxgjB6VIS0u3ey14MOUKY416o_BvdXjbkUNAQ,3667
|
43
|
+
notionary/page/properites/property_operation_result.py,sha256=PhxHJJxxG2BdDl7aswhWnMSmf9RQtoinKkRHDoqxwCs,3913
|
44
|
+
notionary/page/properites/property_value_extractor.py,sha256=1BfyCYrFzfIUmNTozavrLTjG--6P6Dy2tkewf6rHHwQ,2353
|
45
|
+
notionary/page/relations/notion_page_relation_manager.py,sha256=D7JZJLXjX2Jn3CIseJxoMK9qL9gp88t4NmL9Ihu06eg,12682
|
46
|
+
notionary/page/relations/notion_page_title_resolver.py,sha256=jUYsEkfyDgdh77oh2awYEB5g1vQqLBq6xYSXL-4uPH8,1722
|
47
|
+
notionary/page/relations/page_database_relation.py,sha256=F9aGXFjjL8ZLNbfTGeGm_QAyXhz2AEOw7GgDLdprEcE,2313
|
48
|
+
notionary/page/relations/relation_operation_result.py,sha256=NDxBzGntOxc_89ti-HG8xDSqfY6PwyGHKHrrKbCzNjM,5010
|
49
|
+
notionary/util/logging_mixin.py,sha256=fKsx9t90bwvL74ZX3dU-sXdC4TZCQyO6qU9I8txkw_U,1369
|
50
|
+
notionary/util/page_id_utils.py,sha256=EYNMxgf-7ghzL5K8lKZBZfW7g5CsdY0Xuj4IYmU8RPk,1381
|
51
|
+
notionary/util/singleton_decorator.py,sha256=GTNMfIlVNRUVMw_c88xqd12-DcqZJjmyidN54yqiNVw,472
|
52
|
+
notionary-0.1.14.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
|
53
|
+
notionary-0.1.14.dist-info/METADATA,sha256=aAgXmYYWBruH6azteEcg-N38clmDqszmgNVp3RWF0G0,6154
|
54
|
+
notionary-0.1.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
55
|
+
notionary-0.1.14.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
|
56
|
+
notionary-0.1.14.dist-info/RECORD,,
|
notionary/converters/__init__.py
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# Import converters
|
2
|
-
from .markdown_to_notion_converter import MarkdownToNotionConverter
|
3
|
-
from .notion_to_markdown_converter import NotionToMarkdownConverter
|
4
|
-
|
5
|
-
# Import registry classes
|
6
|
-
from .registry.block_element_registry import BlockElementRegistry
|
7
|
-
from .registry.block_element_registry_builder import BlockElementRegistryBuilder
|
8
|
-
|
9
|
-
# Import elements for type hints and direct use
|
10
|
-
from .elements.paragraph_element import ParagraphElement
|
11
|
-
from .elements.heading_element import HeadingElement
|
12
|
-
from .elements.callout_element import CalloutElement
|
13
|
-
from .elements.code_block_element import CodeBlockElement
|
14
|
-
from .elements.divider_element import DividerElement
|
15
|
-
from .elements.table_element import TableElement
|
16
|
-
from .elements.todo_lists import TodoElement
|
17
|
-
from .elements.list_element import BulletedListElement, NumberedListElement
|
18
|
-
from .elements.qoute_element import QuoteElement
|
19
|
-
from .elements.image_element import ImageElement
|
20
|
-
from .elements.video_element import VideoElement
|
21
|
-
from .elements.toggle_element import ToggleElement
|
22
|
-
from .elements.bookmark_element import BookmarkElement
|
23
|
-
from .elements.column_element import ColumnElement
|
24
|
-
|
25
|
-
default_registry = BlockElementRegistryBuilder.create_standard_registry()
|
26
|
-
|
27
|
-
# Define what to export
|
28
|
-
__all__ = [
|
29
|
-
"BlockElementRegistry",
|
30
|
-
"BlockElementRegistryBuilder",
|
31
|
-
"MarkdownToNotionConverter",
|
32
|
-
"NotionToMarkdownConverter",
|
33
|
-
"default_registry",
|
34
|
-
# Element classes
|
35
|
-
"ParagraphElement",
|
36
|
-
"HeadingElement",
|
37
|
-
"CalloutElement",
|
38
|
-
"CodeBlockElement",
|
39
|
-
"DividerElement",
|
40
|
-
"TableElement",
|
41
|
-
"TodoElement",
|
42
|
-
"QuoteElement",
|
43
|
-
"BulletedListElement",
|
44
|
-
"NumberedListElement",
|
45
|
-
"ImageElement",
|
46
|
-
"VideoElement",
|
47
|
-
"ToggleElement",
|
48
|
-
"BookmarkElement",
|
49
|
-
"ColumnElement",
|
50
|
-
]
|
@@ -1,45 +0,0 @@
|
|
1
|
-
from typing import Dict, Any, List, Optional
|
2
|
-
|
3
|
-
from notionary.converters.registry.block_element_registry import (
|
4
|
-
BlockElementRegistry,
|
5
|
-
)
|
6
|
-
from notionary.converters.registry.block_element_registry_builder import (
|
7
|
-
BlockElementRegistryBuilder,
|
8
|
-
)
|
9
|
-
|
10
|
-
|
11
|
-
class NotionToMarkdownConverter:
|
12
|
-
"""Converts Notion blocks to Markdown text."""
|
13
|
-
|
14
|
-
def __init__(self, block_registry: Optional[BlockElementRegistry] = None):
|
15
|
-
"""
|
16
|
-
Initialize the MarkdownToNotionConverter.
|
17
|
-
|
18
|
-
Args:
|
19
|
-
block_registry: Optional registry of Notion block elements
|
20
|
-
"""
|
21
|
-
self._block_registry = (
|
22
|
-
block_registry or BlockElementRegistryBuilder().create_standard_registry()
|
23
|
-
)
|
24
|
-
|
25
|
-
def convert(self, blocks: List[Dict[str, Any]]) -> str:
|
26
|
-
"""
|
27
|
-
Convert Notion blocks to Markdown text.
|
28
|
-
|
29
|
-
Args:
|
30
|
-
blocks: List of Notion blocks
|
31
|
-
|
32
|
-
Returns:
|
33
|
-
Markdown text
|
34
|
-
"""
|
35
|
-
if not blocks:
|
36
|
-
return ""
|
37
|
-
|
38
|
-
markdown_parts = []
|
39
|
-
|
40
|
-
for block in blocks:
|
41
|
-
markdown = self._block_registry.notion_to_markdown(block)
|
42
|
-
if markdown:
|
43
|
-
markdown_parts.append(markdown)
|
44
|
-
|
45
|
-
return "\n\n".join(markdown_parts)
|