notionary 0.1.11__py3-none-any.whl → 0.1.13__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 +21 -6
- notionary/{core/converters → converters}/elements/audio_element.py +7 -5
- notionary/{core/converters → converters}/elements/bookmark_element.py +1 -1
- notionary/{core/converters → converters}/elements/callout_element.py +2 -2
- notionary/{core/converters → converters}/elements/code_block_element.py +1 -1
- notionary/{core/converters → converters}/elements/column_element.py +1 -1
- notionary/{core/converters → converters}/elements/divider_element.py +1 -1
- notionary/{core/converters → converters}/elements/embed_element.py +3 -5
- notionary/{core/converters → converters}/elements/heading_element.py +2 -2
- notionary/{core/converters → converters}/elements/image_element.py +1 -1
- notionary/{core/converters → converters}/elements/list_element.py +2 -2
- notionary/{core/converters → converters}/elements/paragraph_element.py +2 -2
- notionary/{core/converters → converters}/elements/qoute_element.py +1 -1
- notionary/{core/converters → converters}/elements/table_element.py +2 -2
- notionary/{core/converters → converters}/elements/todo_lists.py +2 -2
- notionary/{core/converters → converters}/elements/toggle_element.py +24 -21
- notionary/{core/converters → converters}/elements/video_element.py +1 -1
- notionary/{core/converters → converters}/markdown_to_notion_converter.py +72 -111
- notionary/{core/converters → converters}/notion_to_markdown_converter.py +2 -2
- notionary/{core/converters → converters}/registry/block_element_registry.py +5 -5
- notionary/{core/converters → converters}/registry/block_element_registry_builder.py +18 -18
- notionary/database/database_discovery.py +142 -0
- notionary/{core/database → database}/database_info_service.py +1 -1
- notionary/{core/database/notion_database_manager.py → database/notion_database.py} +33 -57
- notionary/{core/database/notion_database_manager_factory.py → database/notion_database_factory.py} +18 -16
- notionary/{core/notion_client.py → notion_client.py} +4 -2
- notionary/page/content/notion_page_content_chunker.py +84 -0
- notionary/{core/page → page}/content/page_content_manager.py +29 -13
- notionary/{core/page → page}/metadata/metadata_editor.py +59 -46
- notionary/{core/page → page}/metadata/notion_icon_manager.py +10 -12
- notionary/{core/page → page}/metadata/notion_page_cover_manager.py +16 -21
- notionary/page/notion_page.py +504 -0
- notionary/page/notion_page_factory.py +256 -0
- notionary/{core/page → page}/properites/database_property_service.py +115 -99
- notionary/{core/page → page}/properites/page_property_manager.py +81 -52
- notionary/{core/page → page}/properites/property_formatter.py +1 -1
- notionary/{core/page → page}/properites/property_operation_result.py +43 -30
- notionary/{core/page → page}/properites/property_value_extractor.py +26 -8
- notionary/{core/page → page}/relations/notion_page_relation_manager.py +72 -53
- notionary/{core/page → page}/relations/notion_page_title_resolver.py +12 -12
- notionary/{core/page → page}/relations/page_database_relation.py +15 -15
- notionary/{core/page → page}/relations/relation_operation_result.py +50 -41
- notionary/util/page_id_utils.py +14 -8
- {notionary-0.1.11.dist-info → notionary-0.1.13.dist-info}/METADATA +1 -1
- notionary-0.1.13.dist-info/RECORD +56 -0
- notionary/core/database/notion_database_schema.py +0 -104
- notionary/core/page/notion_page_manager.py +0 -322
- notionary-0.1.11.dist-info/RECORD +0 -54
- /notionary/{core/converters → converters}/__init__.py +0 -0
- /notionary/{core/converters → converters}/elements/notion_block_element.py +0 -0
- /notionary/{core/converters → converters}/elements/text_inline_formatter.py +0 -0
- /notionary/{core/database → database}/models/page_result.py +0 -0
- {notionary-0.1.11.dist-info → notionary-0.1.13.dist-info}/WHEEL +0 -0
- {notionary-0.1.11.dist-info → notionary-0.1.13.dist-info}/licenses/LICENSE +0 -0
- {notionary-0.1.11.dist-info → notionary-0.1.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
notionary/__init__.py,sha256=kG1u5pB2PCrr2aXG4B1YhVqucPqU_LG-qyw5t5Bjayw,739
|
2
|
+
notionary/notion_client.py,sha256=VdIE1TSEZTy2BhR7Hnx_McndvQYxlu-aJN_7LeDpXgY,4497
|
3
|
+
notionary/converters/__init__.py,sha256=GOUehJbe4BKHtec1MqL1YGu3AX8zFtkwSZfhYkY5-P0,1798
|
4
|
+
notionary/converters/markdown_to_notion_converter.py,sha256=xmoXpE7KqaueUHAcDt76BTDUE_tNv4QbNtgBgX_YAXk,15100
|
5
|
+
notionary/converters/notion_to_markdown_converter.py,sha256=aX2qabOI6cp3bYOfDxJtODQYBQCp_zRFlezLXjwFV9Q,1277
|
6
|
+
notionary/converters/elements/audio_element.py,sha256=jCCReh0pBKjB4Dq46XZMkKJ1ZZy0DvjgFbeQKW5VGzM,5600
|
7
|
+
notionary/converters/elements/bookmark_element.py,sha256=Ki0Tv3lpYmo6g7OKtXg9smzMtbB2C5O9Qfr6QF8goko,8588
|
8
|
+
notionary/converters/elements/callout_element.py,sha256=tUUzTrt0JXhvvvnxCdF-KPp9mVsil_6bmUBhDeeRrYg,5954
|
9
|
+
notionary/converters/elements/code_block_element.py,sha256=wZh3LXA5qsan0Z9w7SnRKWJMYrw5cT7cfHZ61RtRKM8,5184
|
10
|
+
notionary/converters/elements/column_element.py,sha256=5i6jODlsaGz5S7gJFEzTYnmf1yPyM1-8oMJvJp3EUno,10717
|
11
|
+
notionary/converters/elements/divider_element.py,sha256=6Zv15SXLFkXo6HkiQ_iXGd_FfFr3tEObXrlNiw1gE2g,2787
|
12
|
+
notionary/converters/elements/embed_element.py,sha256=PMF2th4eSjKWUqkxgb0hTvt-ZO2W5mGspMExn_UBa2U,4779
|
13
|
+
notionary/converters/elements/heading_element.py,sha256=L-VZaXO1uFnfGNWkTmtHg5YXKLncR23MVFJvwJtqSuA,2778
|
14
|
+
notionary/converters/elements/image_element.py,sha256=sz5nXZzKTBb0U6QULOMVQ4XBdAHi6yOh9-TTodz_0-Q,4856
|
15
|
+
notionary/converters/elements/list_element.py,sha256=CRp8R1Kxn01dqZNal9EaAwV2D3Z4c_sXRZ0crZ4OTOI,4868
|
16
|
+
notionary/converters/elements/notion_block_element.py,sha256=lLRBDXhBeRaRzkbvdpYpr-U9nbkd62oVtqdSe-svT4c,1746
|
17
|
+
notionary/converters/elements/paragraph_element.py,sha256=-gIZr5MD_b7akh9euQ95PsiQlhvswC2S1VFgwBXRFQQ,2756
|
18
|
+
notionary/converters/elements/qoute_element.py,sha256=3Nr62ddgr4erncdBs-xhb2OMiPhlXAKuoqu-3hefTRc,9052
|
19
|
+
notionary/converters/elements/table_element.py,sha256=7eqFMYxZUx7aG25WEp1cNSMHDkKTWwZvUVpq4dTnvHc,11244
|
20
|
+
notionary/converters/elements/text_inline_formatter.py,sha256=FE_Sq2cozpu5RVtMbnPq21gD06UjH3LMRYr3s16JKYo,10606
|
21
|
+
notionary/converters/elements/todo_lists.py,sha256=6d74O11TfCr5umQa2xrsIiUv3PB9sZoDcWdfg21M7po,4255
|
22
|
+
notionary/converters/elements/toggle_element.py,sha256=69JSanxAGPXKwpBsMtXlvW0aCn080Me4gwk_DxTxM2Q,7253
|
23
|
+
notionary/converters/elements/video_element.py,sha256=XKfZcG8m8lZ5RyQGz_GgZCGPCMY3SjcvyuRJ6P1ymMI,6042
|
24
|
+
notionary/converters/registry/block_element_registry.py,sha256=Bi1DlEdP8xloqh_YeTh1PKzOKxtS1u1W-lu8kEcXY94,8690
|
25
|
+
notionary/converters/registry/block_element_registry_builder.py,sha256=UMJNE3bVMNqwTeA5pvNf-_gxYzIuUX1AOy1sYQXlBs4,9367
|
26
|
+
notionary/database/database_discovery.py,sha256=qDGFhXG9s-_6CXdRg8tMiwX4dvX7jLjgAUFPSNlYtlI,4506
|
27
|
+
notionary/database/database_info_service.py,sha256=Ig6gx8jUSPYORJvfgEV5kV6t72pZQsWU8HPMqd43B-o,1336
|
28
|
+
notionary/database/notion_database.py,sha256=RY5MlXNE5DVNWLC_Derljsz87ZMHkE-05Vgm80kvLxg,7250
|
29
|
+
notionary/database/notion_database_factory.py,sha256=Af57yaUHidD8TKJ8uyXOc2nnqHm7on6VGFdDRjxiq9o,6692
|
30
|
+
notionary/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
|
31
|
+
notionary/exceptions/database_exceptions.py,sha256=I-Tx6bYRLpi5pjGPtbT-Mqxvz3BFgYTiuZxknJeLxtI,2638
|
32
|
+
notionary/exceptions/page_creation_exception.py,sha256=4v7IuZD6GsQLrqhDLriGjuG3ML638gAO53zDCrLePuU,281
|
33
|
+
notionary/page/notion_page.py,sha256=u5lPCteJ5Bz89N40TlwF2cHjHAMmwYOi2NHMo5neJZU,17003
|
34
|
+
notionary/page/notion_page_factory.py,sha256=ucTrAaXvlD4pzfqRXfhygldfD8MLx4n23XpsWESXEr4,8466
|
35
|
+
notionary/page/content/notion_page_content_chunker.py,sha256=xRks74Dqec-De6-AVTxMPnXs-MSJBzSm1HfJfaHiKr8,3330
|
36
|
+
notionary/page/content/page_content_manager.py,sha256=X4p6jBJpFpOhtbiH2BOzwoAnWRLz1EDauV16QYJMW58,3942
|
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.13.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
|
53
|
+
notionary-0.1.13.dist-info/METADATA,sha256=oVy9WSKlRNiV1Hg_hnf8z4ZfZgo-bBl6qaF0S6zX0Z4,6154
|
54
|
+
notionary-0.1.13.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
55
|
+
notionary-0.1.13.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
|
56
|
+
notionary-0.1.13.dist-info/RECORD,,
|
@@ -1,104 +0,0 @@
|
|
1
|
-
from typing import (
|
2
|
-
AsyncGenerator,
|
3
|
-
Dict,
|
4
|
-
Optional,
|
5
|
-
Any,
|
6
|
-
)
|
7
|
-
from notionary.core.notion_client import NotionClient
|
8
|
-
from notionary.util.logging_mixin import LoggingMixin
|
9
|
-
|
10
|
-
class NotionDatabaseAccessor(LoggingMixin):
|
11
|
-
"""
|
12
|
-
A utility class that provides methods to access Notion databases.
|
13
|
-
Focused on efficient, paginated access to databases without unnecessary complexity.
|
14
|
-
"""
|
15
|
-
|
16
|
-
def __init__(self, client: Optional[NotionClient] = None) -> None:
|
17
|
-
"""
|
18
|
-
Initialize the accessor with a NotionClient.
|
19
|
-
|
20
|
-
Args:
|
21
|
-
client: NotionClient instance for API communication
|
22
|
-
"""
|
23
|
-
self._client = client if client else NotionClient()
|
24
|
-
self.logger.info("NotionDatabaseAccessor initialized")
|
25
|
-
|
26
|
-
async def iter_databases(
|
27
|
-
self, page_size: int = 100
|
28
|
-
) -> AsyncGenerator[Dict[str, Any], None]:
|
29
|
-
"""
|
30
|
-
Asynchronous generator that yields Notion databases one by one.
|
31
|
-
|
32
|
-
Uses the Notion API to provide paginated access to all databases
|
33
|
-
without loading all of them into memory at once.
|
34
|
-
|
35
|
-
Args:
|
36
|
-
page_size: The number of databases to fetch per request
|
37
|
-
|
38
|
-
Yields:
|
39
|
-
Individual database objects from the Notion API
|
40
|
-
"""
|
41
|
-
start_cursor: Optional[str] = None
|
42
|
-
|
43
|
-
while True:
|
44
|
-
body: Dict[str, Any] = {
|
45
|
-
"filter": {"value": "database", "property": "object"},
|
46
|
-
"page_size": page_size,
|
47
|
-
}
|
48
|
-
|
49
|
-
if start_cursor:
|
50
|
-
body["start_cursor"] = start_cursor
|
51
|
-
|
52
|
-
result = await self._client.post("search", data=body)
|
53
|
-
|
54
|
-
if not result or "results" not in result:
|
55
|
-
self.logger.error("Error fetching databases")
|
56
|
-
break
|
57
|
-
|
58
|
-
for database in result["results"]:
|
59
|
-
yield database
|
60
|
-
|
61
|
-
if "has_more" in result and result["has_more"] and "next_cursor" in result:
|
62
|
-
start_cursor = result["next_cursor"]
|
63
|
-
else:
|
64
|
-
break
|
65
|
-
|
66
|
-
async def get_database(self, database_id: str) -> Optional[Dict[str, Any]]:
|
67
|
-
"""
|
68
|
-
Get the details for a specific database.
|
69
|
-
|
70
|
-
Args:
|
71
|
-
database_id: The ID of the database
|
72
|
-
|
73
|
-
Returns:
|
74
|
-
Database details or None if not found
|
75
|
-
"""
|
76
|
-
db_details = await self._client.get(f"databases/{database_id}")
|
77
|
-
if not db_details:
|
78
|
-
self.logger.error("Failed to retrieve database %s", database_id)
|
79
|
-
return None
|
80
|
-
|
81
|
-
return db_details
|
82
|
-
|
83
|
-
def extract_database_title(self, database: Dict[str, Any]) -> str:
|
84
|
-
"""
|
85
|
-
Extract the database title from a Notion API response.
|
86
|
-
|
87
|
-
Args:
|
88
|
-
database: The database object from the Notion API
|
89
|
-
|
90
|
-
Returns:
|
91
|
-
The extracted title or "Untitled" if no title is found
|
92
|
-
"""
|
93
|
-
title = "Untitled"
|
94
|
-
|
95
|
-
if "title" in database:
|
96
|
-
title_parts = []
|
97
|
-
for text_obj in database["title"]:
|
98
|
-
if "plain_text" in text_obj:
|
99
|
-
title_parts.append(text_obj["plain_text"])
|
100
|
-
|
101
|
-
if title_parts:
|
102
|
-
title = "".join(title_parts)
|
103
|
-
|
104
|
-
return title
|
@@ -1,322 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
from typing import Any, Dict, List, Optional, Union
|
3
|
-
from notionary.core.converters.registry.block_element_registry import (
|
4
|
-
BlockElementRegistry,
|
5
|
-
)
|
6
|
-
from notionary.core.converters.registry.block_element_registry_builder import (
|
7
|
-
BlockElementRegistryBuilder,
|
8
|
-
)
|
9
|
-
from notionary.core.notion_client import NotionClient
|
10
|
-
from notionary.core.page.metadata.metadata_editor import MetadataEditor
|
11
|
-
from notionary.core.page.metadata.notion_icon_manager import NotionPageIconManager
|
12
|
-
from notionary.core.page.metadata.notion_page_cover_manager import NotionPageCoverManager
|
13
|
-
from notionary.core.page.properites.database_property_service import DatabasePropertyService
|
14
|
-
from notionary.core.page.relations.notion_page_relation_manager import NotionRelationManager
|
15
|
-
from notionary.core.page.content.page_content_manager import PageContentManager
|
16
|
-
from notionary.core.page.properites.page_property_manager import PagePropertyManager
|
17
|
-
from notionary.util.logging_mixin import LoggingMixin
|
18
|
-
from notionary.util.page_id_utils import extract_and_validate_page_id
|
19
|
-
from notionary.core.page.relations.page_database_relation import PageDatabaseRelation
|
20
|
-
|
21
|
-
class NotionPageManager(LoggingMixin):
|
22
|
-
"""
|
23
|
-
High-Level Facade for managing content and metadata of a Notion page.
|
24
|
-
"""
|
25
|
-
|
26
|
-
def __init__(
|
27
|
-
self,
|
28
|
-
page_id: Optional[str] = None,
|
29
|
-
title: Optional[str] = None,
|
30
|
-
url: Optional[str] = None,
|
31
|
-
token: Optional[str] = None,
|
32
|
-
):
|
33
|
-
self._page_id = extract_and_validate_page_id(page_id=page_id, url=url)
|
34
|
-
|
35
|
-
self.url = url
|
36
|
-
self._title = title
|
37
|
-
self._client = NotionClient(token=token)
|
38
|
-
self._page_data = None
|
39
|
-
|
40
|
-
self._block_element_registry = (
|
41
|
-
BlockElementRegistryBuilder.create_standard_registry()
|
42
|
-
)
|
43
|
-
|
44
|
-
self._page_content_manager = PageContentManager(
|
45
|
-
page_id=self._page_id,
|
46
|
-
client=self._client,
|
47
|
-
block_registry=self._block_element_registry,
|
48
|
-
)
|
49
|
-
self._metadata = MetadataEditor(self._page_id, self._client)
|
50
|
-
self._page_cover_manager = NotionPageCoverManager(page_id=self._page_id, client=self._client)
|
51
|
-
self._page_icon_manager = NotionPageIconManager(page_id=self._page_id, client=self._client)
|
52
|
-
|
53
|
-
self._db_relation = PageDatabaseRelation(page_id=self._page_id, client=self._client)
|
54
|
-
self._db_property_service = None
|
55
|
-
|
56
|
-
self._relation_manager = NotionRelationManager(page_id=self._page_id, client=self._client)
|
57
|
-
|
58
|
-
self._property_manager = PagePropertyManager(
|
59
|
-
self._page_id,
|
60
|
-
self._client,
|
61
|
-
self._metadata,
|
62
|
-
self._db_relation
|
63
|
-
)
|
64
|
-
|
65
|
-
async def _get_db_property_service(self) -> Optional[DatabasePropertyService]:
|
66
|
-
"""
|
67
|
-
Gets the database property service, initializing it if necessary.
|
68
|
-
This is a more intuitive way to work with the instance variable.
|
69
|
-
|
70
|
-
Returns:
|
71
|
-
Optional[DatabasePropertyService]: The database property service or None if not applicable
|
72
|
-
"""
|
73
|
-
if self._db_property_service is not None:
|
74
|
-
return self._db_property_service
|
75
|
-
|
76
|
-
database_id = await self._db_relation.get_parent_database_id()
|
77
|
-
if not database_id:
|
78
|
-
return None
|
79
|
-
|
80
|
-
self._db_property_service = DatabasePropertyService(database_id, self._client)
|
81
|
-
await self._db_property_service.load_schema()
|
82
|
-
return self._db_property_service
|
83
|
-
|
84
|
-
@property
|
85
|
-
def page_id(self) -> Optional[str]:
|
86
|
-
"""Get the ID of the page."""
|
87
|
-
return self._page_id
|
88
|
-
|
89
|
-
@property
|
90
|
-
def title(self) -> Optional[str]:
|
91
|
-
return self._title
|
92
|
-
|
93
|
-
@property
|
94
|
-
def block_registry(self) -> BlockElementRegistry:
|
95
|
-
return self._block_element_registry
|
96
|
-
|
97
|
-
@block_registry.setter
|
98
|
-
def block_registry(self, block_registry: BlockElementRegistry) -> None:
|
99
|
-
"""Set the block element registry for the page content manager."""
|
100
|
-
self._block_element_registry = block_registry
|
101
|
-
self._page_content_manager = PageContentManager(
|
102
|
-
page_id=self._page_id, client=self._client, block_registry=block_registry
|
103
|
-
)
|
104
|
-
|
105
|
-
async def append_markdown(self, markdown: str) -> str:
|
106
|
-
return await self._page_content_manager.append_markdown(markdown)
|
107
|
-
|
108
|
-
async def clear(self) -> str:
|
109
|
-
return await self._page_content_manager.clear()
|
110
|
-
|
111
|
-
async def replace_content(self, markdown: str) -> str:
|
112
|
-
await self._page_content_manager.clear()
|
113
|
-
return await self._page_content_manager.append_markdown(markdown)
|
114
|
-
|
115
|
-
async def get_text(self) -> str:
|
116
|
-
return await self._page_content_manager.get_text()
|
117
|
-
|
118
|
-
async def set_title(self, title: str) -> Optional[Dict[str, Any]]:
|
119
|
-
return await self._metadata.set_title(title)
|
120
|
-
|
121
|
-
async def set_page_icon(
|
122
|
-
self, emoji: Optional[str] = None, external_url: Optional[str] = None
|
123
|
-
) -> Optional[Dict[str, Any]]:
|
124
|
-
return await self._page_icon_manager.set_icon(emoji, external_url)
|
125
|
-
|
126
|
-
async def _get_page_data(self, force_refresh=False) -> Dict[str, Any]:
|
127
|
-
""" Gets the page data and caches it for future use.
|
128
|
-
"""
|
129
|
-
if self._page_data is None or force_refresh:
|
130
|
-
self._page_data = await self._client.get_page(self._page_id)
|
131
|
-
return self._page_data
|
132
|
-
|
133
|
-
async def get_icon(self) -> Optional[str]:
|
134
|
-
"""Retrieves the page icon - either emoji or external URL.
|
135
|
-
"""
|
136
|
-
return await self._page_icon_manager.get_icon()
|
137
|
-
|
138
|
-
async def get_cover_url(self) -> str:
|
139
|
-
return await self._page_cover_manager.get_cover_url()
|
140
|
-
|
141
|
-
async def set_page_cover(self, external_url: str) -> Optional[Dict[str, Any]]:
|
142
|
-
return await self._page_cover_manager.set_cover(external_url)
|
143
|
-
|
144
|
-
async def set_random_gradient_cover(self) -> Optional[Dict[str, Any]]:
|
145
|
-
return await self._page_cover_manager.set_random_gradient_cover()
|
146
|
-
|
147
|
-
async def get_properties(self) -> Dict[str, Any]:
|
148
|
-
"""Retrieves all properties of the page."""
|
149
|
-
return await self._property_manager.get_properties()
|
150
|
-
|
151
|
-
async def get_property_value(self, property_name: str) -> Any:
|
152
|
-
"""Get the value of a specific property."""
|
153
|
-
return await self._property_manager.get_property_value(
|
154
|
-
property_name,
|
155
|
-
self._relation_manager.get_relation_values
|
156
|
-
)
|
157
|
-
|
158
|
-
async def set_property_by_name(self, property_name: str, value: Any) -> Optional[Dict[str, Any]]:
|
159
|
-
""" Sets the value of a specific property by its name.
|
160
|
-
"""
|
161
|
-
return await self._property_manager.set_property_by_name(
|
162
|
-
property_name=property_name,
|
163
|
-
value=value,
|
164
|
-
)
|
165
|
-
|
166
|
-
async def is_database_page(self) -> bool:
|
167
|
-
""" Checks if this page belongs to a database.
|
168
|
-
"""
|
169
|
-
return await self._db_relation.is_database_page()
|
170
|
-
|
171
|
-
async def get_parent_database_id(self) -> Optional[str]:
|
172
|
-
""" Gets the ID of the database this page belongs to, if any
|
173
|
-
"""
|
174
|
-
return await self._db_relation.get_parent_database_id()
|
175
|
-
|
176
|
-
async def get_available_options_for_property(self, property_name: str) -> List[str]:
|
177
|
-
""" Gets the available option names for a property (select, multi_select, status).
|
178
|
-
"""
|
179
|
-
db_service = await self._get_db_property_service()
|
180
|
-
if db_service:
|
181
|
-
return await db_service.get_option_names(property_name)
|
182
|
-
return []
|
183
|
-
|
184
|
-
async def get_property_type(self, property_name: str) -> Optional[str]:
|
185
|
-
""" Gets the type of a specific property.
|
186
|
-
"""
|
187
|
-
db_service = await self._get_db_property_service()
|
188
|
-
if db_service:
|
189
|
-
return await db_service.get_property_type(property_name)
|
190
|
-
return None
|
191
|
-
|
192
|
-
async def get_database_metadata(self, include_types: Optional[List[str]] = None) -> Dict[str, Any]:
|
193
|
-
""" Gets complete metadata about the database this page belongs to.
|
194
|
-
"""
|
195
|
-
db_service = await self._get_db_property_service()
|
196
|
-
if db_service:
|
197
|
-
return await db_service.get_database_metadata(include_types)
|
198
|
-
return {"properties": {}}
|
199
|
-
|
200
|
-
async def get_relation_options(self, property_name: str, limit: int = 100) -> List[Dict[str, Any]]:
|
201
|
-
""" Returns available options for a relation property.
|
202
|
-
"""
|
203
|
-
return await self._relation_manager.get_relation_options(property_name, limit)
|
204
|
-
|
205
|
-
async def add_relations_by_name(self, relation_property_name: str, page_titles: Union[str, List[str]]) -> Optional[Dict[str, Any]]:
|
206
|
-
""" Adds one or more relations.
|
207
|
-
"""
|
208
|
-
return await self._relation_manager.add_relation_by_name(property_name=relation_property_name, page_titles=page_titles)
|
209
|
-
|
210
|
-
async def get_relation_values(self, property_name: str) -> List[str]:
|
211
|
-
"""
|
212
|
-
Returns the current relation values for a property.
|
213
|
-
"""
|
214
|
-
return await self._relation_manager.get_relation_values(property_name)
|
215
|
-
|
216
|
-
async def get_relation_property_ids(self) -> List[str]:
|
217
|
-
""" Returns a list of all relation property names.
|
218
|
-
"""
|
219
|
-
return await self._relation_manager.get_relation_property_ids()
|
220
|
-
|
221
|
-
async def get_all_relations(self) -> Dict[str, List[str]]:
|
222
|
-
""" Returns all relation properties and their values.
|
223
|
-
"""
|
224
|
-
return await self._relation_manager.get_all_relations()
|
225
|
-
|
226
|
-
async def get_status(self) -> Optional[str]:
|
227
|
-
""" Determines the status of the page (e.g., 'Draft', 'Completed', etc.)
|
228
|
-
"""
|
229
|
-
return await self.get_property_value("Status")
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
async def main():
|
234
|
-
"""
|
235
|
-
Demonstriert die Verwendung des refactorierten NotionPageManager.
|
236
|
-
"""
|
237
|
-
print("=== NotionPageManager Demo ===")
|
238
|
-
|
239
|
-
page_manager = NotionPageManager(page_id="https://notion.so/1d0389d57bd3805cb34ccaf5804b43ce")
|
240
|
-
|
241
|
-
await page_manager.add_relations_by_name("Projekte", ["Fetzen mit Stine"])
|
242
|
-
|
243
|
-
|
244
|
-
input("Drücke Enter, um fortzufahren...")
|
245
|
-
|
246
|
-
|
247
|
-
is_database_page = await page_manager.is_database_page()
|
248
|
-
|
249
|
-
if not is_database_page:
|
250
|
-
print("Diese Seite gehört zu keiner Datenbank. Demo wird beendet.")
|
251
|
-
return
|
252
|
-
|
253
|
-
db_id = await page_manager.get_parent_database_id()
|
254
|
-
print(f"\n2. Datenbank-ID: {db_id}")
|
255
|
-
|
256
|
-
properties = await page_manager.get_properties()
|
257
|
-
print("\n3. Aktuelle Eigenschaften der Seite:")
|
258
|
-
for prop_name, prop_data in properties.items():
|
259
|
-
prop_type = prop_data.get("type", "unbekannt")
|
260
|
-
|
261
|
-
value = await page_manager.get_property_value(prop_name)
|
262
|
-
print(f" - {prop_name} ({prop_type}): {value}")
|
263
|
-
|
264
|
-
status_options = await page_manager.get_available_options_for_property("Status")
|
265
|
-
print(f"\n4. Verfügbare Status-Optionen: {status_options}")
|
266
|
-
|
267
|
-
tags_options = await page_manager.get_available_options_for_property("Tags")
|
268
|
-
print(f"\n5. Verfügbare Tags-Optionen: {tags_options}")
|
269
|
-
|
270
|
-
print("\n6. Relation-Eigenschaften und deren Optionen:")
|
271
|
-
for prop_name, prop_data in properties.items():
|
272
|
-
if prop_data.get("type") == "relation":
|
273
|
-
relation_options = await page_manager.get_relation_options(prop_name, limit=5)
|
274
|
-
option_names = [option.get("name", "Unbenannt") for option in relation_options]
|
275
|
-
print(f" - {prop_name} Relation-Optionen (max. 5): {option_names}")
|
276
|
-
|
277
|
-
print("\n7. Typen aller Eigenschaften:")
|
278
|
-
for prop_name in properties.keys():
|
279
|
-
prop_type = await page_manager.get_property_type(prop_name)
|
280
|
-
print(f" - {prop_name}: {prop_type}")
|
281
|
-
|
282
|
-
if status_options:
|
283
|
-
valid_status = status_options[0]
|
284
|
-
print(f"\n8. Setze Status auf '{valid_status}'...")
|
285
|
-
result = await page_manager.set_property_by_name("Status", valid_status)
|
286
|
-
print(f" Ergebnis: {'Erfolgreich' if result else 'Fehlgeschlagen'}")
|
287
|
-
|
288
|
-
current_status = await page_manager.get_status()
|
289
|
-
print(f" Aktueller Status: {current_status}")
|
290
|
-
|
291
|
-
# 9. Versuch, einen ungültigen Status zu setzen
|
292
|
-
invalid_status = "Bin King"
|
293
|
-
print(f"\n9. Versuche ungültigen Status '{invalid_status}' zu setzen...")
|
294
|
-
await page_manager.set_property_by_name("Status", invalid_status)
|
295
|
-
|
296
|
-
# 10. Komplette Datenbank-Metadaten für select-ähnliche Properties abrufen
|
297
|
-
print("\n10. Datenbank-Metadaten für select, multi_select und status Properties:")
|
298
|
-
metadata = await page_manager.get_database_metadata(
|
299
|
-
include_types=["select", "multi_select", "status"]
|
300
|
-
)
|
301
|
-
|
302
|
-
for prop_name, prop_info in metadata.get("properties", {}).items():
|
303
|
-
option_names = [opt.get("name", "") for opt in prop_info.get("options", [])]
|
304
|
-
print(f" - {prop_name} ({prop_info.get('type')}): {option_names}")
|
305
|
-
|
306
|
-
print("\nDemonstration abgeschlossen.")
|
307
|
-
|
308
|
-
|
309
|
-
async def demo2():
|
310
|
-
url = "https://www.notion.so/Jarvis-Clipboard-1a3389d57bd380d7a507e67d1b25822c"
|
311
|
-
|
312
|
-
page_manager = NotionPageManager(url=url)
|
313
|
-
|
314
|
-
markdown = """
|
315
|
-
$[Podcast Zusammenfassung](https://storage.googleapis.com/audio_summaries/ep_ai_summary_127d02ec-ca12-4312-a5ed-cb14b185480c.mp3)
|
316
|
-
"""
|
317
|
-
|
318
|
-
await page_manager.append_markdown(markdown=markdown)
|
319
|
-
|
320
|
-
if __name__ == "__main__":
|
321
|
-
asyncio.run(demo2())
|
322
|
-
print("\nDemonstration completed.")
|
@@ -1,54 +0,0 @@
|
|
1
|
-
notionary/__init__.py,sha256=5T16clJlSHFsopcPUnkGrEo8spNDUQ0i-O00UEF7nR8,320
|
2
|
-
notionary/core/notion_client.py,sha256=9o9-Ki1homkSbM1C51nsaAzVPMt2d4r8cPzoX3NK_HQ,4495
|
3
|
-
notionary/core/converters/__init__.py,sha256=GOUehJbe4BKHtec1MqL1YGu3AX8zFtkwSZfhYkY5-P0,1798
|
4
|
-
notionary/core/converters/markdown_to_notion_converter.py,sha256=PGtg4v5lUvkXXl1Y8E6a3Mf8hEfxfhBrslPs_H_Lq_E,16564
|
5
|
-
notionary/core/converters/notion_to_markdown_converter.py,sha256=c8GyWX8-UrNfRDk7OOBKbSEb5qOwljUCwI6g5risO2c,1287
|
6
|
-
notionary/core/converters/elements/audio_element.py,sha256=qTYxpErHw327JdESr4Biv-H89iZRXzBcllamrFu8P_k,5587
|
7
|
-
notionary/core/converters/elements/bookmark_element.py,sha256=bpHobkGnyBGDAJK5vY9R3Ntl4GiRSF-EyyA31aq2O3E,8593
|
8
|
-
notionary/core/converters/elements/callout_element.py,sha256=rkDoXikjIl-zU3GLawSXgRunBJGLnEvin9zIlCgW4TY,5964
|
9
|
-
notionary/core/converters/elements/code_block_element.py,sha256=G1iGMsGSK5KPSk-tA8TsPs9XNU9ydjYfOVnjIvdZG74,5189
|
10
|
-
notionary/core/converters/elements/column_element.py,sha256=ZwQsLBEownVJnzyv-GfNjvzJhAfKz9ncggqZUmZHF5A,10722
|
11
|
-
notionary/core/converters/elements/divider_element.py,sha256=Ul0wXHY96qWL72iAvttRQMOoAGuASgwFwPraGnpUkX0,2792
|
12
|
-
notionary/core/converters/elements/embed_element.py,sha256=vEqY7VBOAvtI4uwys6_E1FT9j4bkHJM21OYaT51ahe8,4800
|
13
|
-
notionary/core/converters/elements/heading_element.py,sha256=BCBcpEO_UX92nzCclVHAjlOLFJ5zu9wDlAGbphesaOQ,2788
|
14
|
-
notionary/core/converters/elements/image_element.py,sha256=uU3bY26LvJwD_CAXN11tqYt5Ed84gjUeHWnJmxvH07Y,4861
|
15
|
-
notionary/core/converters/elements/list_element.py,sha256=lM9nVGVG3VtmjMkqxrBj71wiJITuRypwxORu4zghqAM,4878
|
16
|
-
notionary/core/converters/elements/notion_block_element.py,sha256=lLRBDXhBeRaRzkbvdpYpr-U9nbkd62oVtqdSe-svT4c,1746
|
17
|
-
notionary/core/converters/elements/paragraph_element.py,sha256=5YGZjcgs0QCvQZ2kF8WCtImbyq5BeMywmME1m3-NDdo,2766
|
18
|
-
notionary/core/converters/elements/qoute_element.py,sha256=CZD1Fe_Lhxsv4mdAM_dr4tlWDjmZCU_5aSpLOFrxDcc,9057
|
19
|
-
notionary/core/converters/elements/table_element.py,sha256=3V9bnNBdsslXZivQ0vpF4_rzrdyI3SWt3aYR814mOzA,11254
|
20
|
-
notionary/core/converters/elements/text_inline_formatter.py,sha256=FE_Sq2cozpu5RVtMbnPq21gD06UjH3LMRYr3s16JKYo,10606
|
21
|
-
notionary/core/converters/elements/todo_lists.py,sha256=wgY6YejURBQ5ESdVLZVIy9QKchS-x8odrmS8X4cC5Kc,4265
|
22
|
-
notionary/core/converters/elements/toggle_element.py,sha256=Xv4MuuOyoamvT3IEJX4mynvLEycgtZ9LWt6Nm764KXE,6980
|
23
|
-
notionary/core/converters/elements/video_element.py,sha256=xrBLY3e_SgKNamItZkfPNMbNEh37Ftp4jWIV6nwV-ds,6047
|
24
|
-
notionary/core/converters/registry/block_element_registry.py,sha256=SRIsPr6xb6xX7GHyrYYNBbt9-l6os29rQndmoXnr5W0,8707
|
25
|
-
notionary/core/converters/registry/block_element_registry_builder.py,sha256=D4GmIAdMoP7K1P78qlgN-GoDwtB_4dZTws049gtXQ5c,9457
|
26
|
-
notionary/core/database/database_info_service.py,sha256=58k7om0UXP8w0jCJHewccG5UbOvELMBAbQvXOm7F1OM,1341
|
27
|
-
notionary/core/database/notion_database_manager.py,sha256=cEQHf8bTcgA3hLMgsbMGSXhCmccmxWLQ6oOJiINR3ac,8257
|
28
|
-
notionary/core/database/notion_database_manager_factory.py,sha256=SoWUiM5zdajmR1ppYHTdPgHrdZbwuTMdoXW3_tBffyU,6831
|
29
|
-
notionary/core/database/notion_database_schema.py,sha256=WUIjG7I5kusk4GOOdmVSHIKc2Z8SeOgJ1FuGpTn4avQ,3304
|
30
|
-
notionary/core/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
|
31
|
-
notionary/core/page/notion_page_manager.py,sha256=O5GBa2KzjAiqH_NDg4JpJbkNcfh3AD5uzTkhqHMr8XE,13635
|
32
|
-
notionary/core/page/content/page_content_manager.py,sha256=GjgxVwi5NOMsvGwBNj-woq940ZupzALCQegDyIcsgMg,3358
|
33
|
-
notionary/core/page/metadata/metadata_editor.py,sha256=U3Ff9GRk28dqT9M1xsl6Q3Cj47-hB1n2pNJzeDXy4ks,4938
|
34
|
-
notionary/core/page/metadata/notion_icon_manager.py,sha256=v9pUG61TOT8x9UzDqBtQW6S5XQzWostq7IwrURnWvF4,1499
|
35
|
-
notionary/core/page/metadata/notion_page_cover_manager.py,sha256=nDWXeEztKyPscq5dRxIZ6d6IqV7E3vR-Qg1N8KzP_fo,1831
|
36
|
-
notionary/core/page/properites/database_property_service.py,sha256=z_HTt_HdB75ffYW5XNwfthZrjLEBXYqKrrK-iGHblek,12073
|
37
|
-
notionary/core/page/properites/page_property_manager.py,sha256=jMiSt9uzr9bKXYhZMg60LVLewp03OFYCeD_qQhKmFT0,6806
|
38
|
-
notionary/core/page/properites/property_formatter.py,sha256=N7GGf-ecUuMLvgt5T_KxabjmvUN7uJrMYFCL7438AZo,3665
|
39
|
-
notionary/core/page/properites/property_operation_result.py,sha256=BVje4SnWf2EdWQYH8sv_6rGd2dL0Owsixfn9SuJY0bk,3961
|
40
|
-
notionary/core/page/properites/property_value_extractor.py,sha256=IG8hKon83CZJ0zYJ-EtgHd2wbjoKOHdA3jB2vmR50Mw,2035
|
41
|
-
notionary/core/page/relations/notion_page_relation_manager.py,sha256=EHavK75Semzh8d7edI1ubh0SJyD8E0loNWVIsfxGAY4,12685
|
42
|
-
notionary/core/page/relations/notion_page_title_resolver.py,sha256=bV0ecP2dikr3vbTEXXsx_4jEtQtpQAHvG-wulASqj3o,1679
|
43
|
-
notionary/core/page/relations/page_database_relation.py,sha256=2WO1HFyIMQwgYoxvxBDUa_iTnJu-Y3Wkzy4JGJ4loME,2420
|
44
|
-
notionary/core/page/relations/relation_operation_result.py,sha256=XkO4rK0ha_FRsfq_Vlwp4a2cE-dGVPBrVxCXOlWqfwk,5258
|
45
|
-
notionary/exceptions/database_exceptions.py,sha256=I-Tx6bYRLpi5pjGPtbT-Mqxvz3BFgYTiuZxknJeLxtI,2638
|
46
|
-
notionary/exceptions/page_creation_exception.py,sha256=4v7IuZD6GsQLrqhDLriGjuG3ML638gAO53zDCrLePuU,281
|
47
|
-
notionary/util/logging_mixin.py,sha256=fKsx9t90bwvL74ZX3dU-sXdC4TZCQyO6qU9I8txkw_U,1369
|
48
|
-
notionary/util/page_id_utils.py,sha256=9XexVGy8jY5iOlueS1MXFWHtRRmZ8js-EO3hT0_wg2E,1381
|
49
|
-
notionary/util/singleton_decorator.py,sha256=GTNMfIlVNRUVMw_c88xqd12-DcqZJjmyidN54yqiNVw,472
|
50
|
-
notionary-0.1.11.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
|
51
|
-
notionary-0.1.11.dist-info/METADATA,sha256=3mCAD1Q1IlhUkPaf8NJAfDENEeZlZWjAmp1tN3e8F28,6154
|
52
|
-
notionary-0.1.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
53
|
-
notionary-0.1.11.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
|
54
|
-
notionary-0.1.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|