notionary 0.1.1__py3-none-any.whl → 0.1.3__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.
Files changed (51) hide show
  1. notionary/__init__.py +9 -0
  2. notionary/core/__init__.py +0 -0
  3. notionary/core/converters/__init__.py +50 -0
  4. notionary/core/converters/elements/__init__.py +0 -0
  5. notionary/core/converters/elements/bookmark_element.py +224 -0
  6. notionary/core/converters/elements/callout_element.py +179 -0
  7. notionary/core/converters/elements/code_block_element.py +153 -0
  8. notionary/core/converters/elements/column_element.py +294 -0
  9. notionary/core/converters/elements/divider_element.py +73 -0
  10. notionary/core/converters/elements/heading_element.py +84 -0
  11. notionary/core/converters/elements/image_element.py +130 -0
  12. notionary/core/converters/elements/list_element.py +130 -0
  13. notionary/core/converters/elements/notion_block_element.py +51 -0
  14. notionary/core/converters/elements/paragraph_element.py +73 -0
  15. notionary/core/converters/elements/qoute_element.py +242 -0
  16. notionary/core/converters/elements/table_element.py +306 -0
  17. notionary/core/converters/elements/text_inline_formatter.py +294 -0
  18. notionary/core/converters/elements/todo_lists.py +114 -0
  19. notionary/core/converters/elements/toggle_element.py +205 -0
  20. notionary/core/converters/elements/video_element.py +159 -0
  21. notionary/core/converters/markdown_to_notion_converter.py +482 -0
  22. notionary/core/converters/notion_to_markdown_converter.py +45 -0
  23. notionary/core/converters/registry/__init__.py +0 -0
  24. notionary/core/converters/registry/block_element_registry.py +234 -0
  25. notionary/core/converters/registry/block_element_registry_builder.py +280 -0
  26. notionary/core/database/database_info_service.py +43 -0
  27. notionary/core/database/database_query_service.py +73 -0
  28. notionary/core/database/database_schema_service.py +57 -0
  29. notionary/core/database/models/page_result.py +10 -0
  30. notionary/core/database/notion_database_manager.py +332 -0
  31. notionary/core/database/notion_database_manager_factory.py +233 -0
  32. notionary/core/database/notion_database_schema.py +415 -0
  33. notionary/core/database/notion_database_writer.py +390 -0
  34. notionary/core/database/page_service.py +161 -0
  35. notionary/core/notion_client.py +134 -0
  36. notionary/core/page/meta_data/metadata_editor.py +37 -0
  37. notionary/core/page/notion_page_manager.py +110 -0
  38. notionary/core/page/page_content_manager.py +85 -0
  39. notionary/core/page/property_formatter.py +97 -0
  40. notionary/exceptions/database_exceptions.py +76 -0
  41. notionary/exceptions/page_creation_exception.py +9 -0
  42. notionary/util/logging_mixin.py +47 -0
  43. notionary/util/singleton_decorator.py +20 -0
  44. notionary/util/uuid_utils.py +24 -0
  45. {notionary-0.1.1.dist-info → notionary-0.1.3.dist-info}/METADATA +1 -1
  46. notionary-0.1.3.dist-info/RECORD +49 -0
  47. notionary-0.1.3.dist-info/top_level.txt +1 -0
  48. notionary-0.1.1.dist-info/RECORD +0 -5
  49. notionary-0.1.1.dist-info/top_level.txt +0 -1
  50. {notionary-0.1.1.dist-info → notionary-0.1.3.dist-info}/WHEEL +0 -0
  51. {notionary-0.1.1.dist-info → notionary-0.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,37 @@
1
+ from typing import Any, Dict, Optional
2
+ from notionary.core.notion_client import NotionClient
3
+ from notionary.util.logging_mixin import LoggingMixin
4
+
5
+
6
+ class MetadataEditor(LoggingMixin):
7
+ def __init__(self, page_id: str, client: NotionClient):
8
+ self.page_id = page_id
9
+ self._client = client
10
+
11
+ async def set_title(self, title: str) -> Optional[Dict[str, Any]]:
12
+ return await self._client.patch(
13
+ f"pages/{self.page_id}",
14
+ {
15
+ "properties": {
16
+ "title": {"title": [{"type": "text", "text": {"content": title}}]}
17
+ }
18
+ },
19
+ )
20
+
21
+ async def set_icon(
22
+ self, emoji: Optional[str] = None, external_url: Optional[str] = None
23
+ ) -> Optional[Dict[str, Any]]:
24
+ if emoji:
25
+ icon = {"type": "emoji", "emoji": emoji}
26
+ elif external_url:
27
+ icon = {"type": "external", "external": {"url": external_url}}
28
+ else:
29
+ return None
30
+
31
+ return await self._client.patch(f"pages/{self.page_id}", {"icon": icon})
32
+
33
+ async def set_cover(self, external_url: str) -> Optional[Dict[str, Any]]:
34
+ return await self._client.patch(
35
+ f"pages/{self.page_id}",
36
+ {"cover": {"type": "external", "external": {"url": external_url}}},
37
+ )
@@ -0,0 +1,110 @@
1
+ from typing import Any, Dict, List, Optional
2
+ from notionary.core.converters.registry.block_element_registry import (
3
+ BlockElementRegistry,
4
+ )
5
+ from notionary.core.converters.registry.block_element_registry_builder import (
6
+ BlockElementRegistryBuilder,
7
+ )
8
+ from notionary.core.notion_client import NotionClient
9
+ from notionary.core.page.page_content_manager import PageContentManager
10
+ from notionary.util.logging_mixin import LoggingMixin
11
+ from notionary.core.page.meta_data.metadata_editor import MetadataEditor
12
+ from notionary.util.uuid_utils import extract_uuid, format_uuid, is_valid_uuid
13
+
14
+
15
+ class NotionPageManager(LoggingMixin):
16
+ """
17
+ High-Level Fassade zur Verwaltung von Inhalten und Metadaten einer Notion-Seite.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ page_id: Optional[str] = None,
23
+ title: Optional[str] = None,
24
+ url: Optional[str] = None,
25
+ token: Optional[str] = None,
26
+ ):
27
+ if not page_id and not url:
28
+ raise ValueError("Either page_id or url must be provided")
29
+
30
+ if not page_id and url:
31
+ page_id = extract_uuid(url)
32
+ if not page_id:
33
+ raise ValueError(f"Could not extract a valid UUID from the URL: {url}")
34
+
35
+ page_id = format_uuid(page_id)
36
+ if not page_id or not is_valid_uuid(page_id):
37
+ raise ValueError(f"Invalid UUID format: {page_id}")
38
+
39
+ self._page_id = page_id
40
+ self.url = url
41
+ self._title = title
42
+
43
+ self._client = NotionClient(token=token)
44
+
45
+ self._block_element_registry = (
46
+ BlockElementRegistryBuilder.create_standard_registry()
47
+ )
48
+
49
+ self._page_content_manager = PageContentManager(
50
+ page_id=page_id,
51
+ client=self._client,
52
+ block_registry=self._block_element_registry,
53
+ )
54
+ self._metadata = MetadataEditor(page_id, self._client)
55
+
56
+ @property
57
+ def page_id(self) -> Optional[str]:
58
+ """Get the title of the page."""
59
+ return self._page_id
60
+
61
+ @property
62
+ def title(self) -> Optional[str]:
63
+ return self._title
64
+
65
+ @property
66
+ def block_registry(self) -> BlockElementRegistry:
67
+ return self._block_element_registry
68
+
69
+ @block_registry.setter
70
+ def block_registry(self, block_registry: BlockElementRegistry) -> None:
71
+ """Set the block element registry for the page content manager."""
72
+
73
+ self._block_element_registry = block_registry
74
+
75
+ self._page_content_manager = PageContentManager(
76
+ page_id=self._page_id, client=self._client, block_registry=block_registry
77
+ )
78
+
79
+ async def append_markdown(self, markdown: str) -> str:
80
+ return await self._page_content_manager.append_markdown(markdown)
81
+
82
+ async def clear(self) -> str:
83
+ return await self._page_content_manager.clear()
84
+
85
+ async def replace_content(self, markdown: str) -> str:
86
+ await self._page_content_manager.clear()
87
+ return await self._page_content_manager.append_markdown(markdown)
88
+
89
+ async def get_blocks(self) -> List[Dict[str, Any]]:
90
+ return await self._page_content_manager.get_blocks()
91
+
92
+ async def get_block_children(self, block_id: str) -> List[Dict[str, Any]]:
93
+ return await self._page_content_manager.get_block_children(block_id)
94
+
95
+ async def get_page_blocks_with_children(self) -> List[Dict[str, Any]]:
96
+ return await self._page_content_manager.get_page_blocks_with_children()
97
+
98
+ async def get_text(self) -> str:
99
+ return await self._page_content_manager.get_text()
100
+
101
+ async def set_title(self, title: str) -> Optional[Dict[str, Any]]:
102
+ return await self._metadata.set_title(title)
103
+
104
+ async def set_page_icon(
105
+ self, emoji: Optional[str] = None, external_url: Optional[str] = None
106
+ ) -> Optional[Dict[str, Any]]:
107
+ return await self._metadata.set_icon(emoji, external_url)
108
+
109
+ async def set_page_cover(self, external_url: str) -> Optional[Dict[str, Any]]:
110
+ return await self._metadata.set_cover(external_url)
@@ -0,0 +1,85 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from notionary.core.converters.markdown_to_notion_converter import (
4
+ MarkdownToNotionConverter,
5
+ )
6
+ from notionary.core.converters.notion_to_markdown_converter import (
7
+ NotionToMarkdownConverter,
8
+ )
9
+ from notionary.core.converters.registry.block_element_registry import (
10
+ BlockElementRegistry,
11
+ )
12
+ from notionary.core.notion_client import NotionClient
13
+ from notionary.util.logging_mixin import LoggingMixin
14
+
15
+
16
+ class PageContentManager(LoggingMixin):
17
+ def __init__(
18
+ self,
19
+ page_id: str,
20
+ client: NotionClient,
21
+ block_registry: Optional[BlockElementRegistry] = None,
22
+ ):
23
+ self.page_id = page_id
24
+ self._client = client
25
+ self._markdown_to_notion_converter = MarkdownToNotionConverter(
26
+ block_registry=block_registry
27
+ )
28
+ self._notion_to_markdown_converter = NotionToMarkdownConverter(
29
+ block_registry=block_registry
30
+ )
31
+
32
+ async def append_markdown(self, markdown_text: str) -> str:
33
+ blocks = self._markdown_to_notion_converter.convert(markdown_text)
34
+ result = await self._client.patch(
35
+ f"blocks/{self.page_id}/children", {"children": blocks}
36
+ )
37
+ return (
38
+ "Successfully added text to the page." if result else "Failed to add text."
39
+ )
40
+
41
+ async def clear(self) -> str:
42
+ blocks = await self._client.get(f"blocks/{self.page_id}/children")
43
+ if not blocks:
44
+ return "No content to delete."
45
+
46
+ results = blocks.get("results", [])
47
+ if not results:
48
+ return "No content to delete."
49
+
50
+ deleted = 0
51
+ for b in results:
52
+ if await self._client.delete(f"blocks/{b['id']}"):
53
+ deleted += 1
54
+
55
+ return f"Deleted {deleted}/{len(results)} blocks."
56
+
57
+ # Methods from PageContentReader
58
+ async def get_blocks(self) -> List[Dict[str, Any]]:
59
+ result = await self._client.get(f"blocks/{self.page_id}/children")
60
+ if not result:
61
+ self.logger.error("Error retrieving page content: %s", result.error)
62
+ return []
63
+ return result.data.get("results", [])
64
+
65
+ async def get_block_children(self, block_id: str) -> List[Dict[str, Any]]:
66
+ result = await self._client.get(f"blocks/{block_id}/children")
67
+ if not result:
68
+ self.logger.error("Error retrieving block children: %s", result.error)
69
+ return []
70
+ return result.data.get("results", [])
71
+
72
+ async def get_page_blocks_with_children(self) -> List[Dict[str, Any]]:
73
+ blocks = await self.get_blocks()
74
+ for block in blocks:
75
+ if block.get("has_children"):
76
+ block_id = block.get("id")
77
+ if block_id:
78
+ children = await self.get_block_children(block_id)
79
+ if children:
80
+ block["children"] = children
81
+ return blocks
82
+
83
+ async def get_text(self) -> str:
84
+ blocks = await self.get_page_blocks_with_children()
85
+ return self._notion_to_markdown_converter.convert(blocks)
@@ -0,0 +1,97 @@
1
+ from typing import Any, Dict, Optional
2
+
3
+ from notionary.util.logging_mixin import LoggingMixin
4
+
5
+
6
+ class NotionPropertyFormatter(LoggingMixin):
7
+ """Klasse zur Formatierung von Notion-Eigenschaften nach Typ."""
8
+
9
+ def __init__(self):
10
+ # Mapping von Typen zu Formatierungsmethoden
11
+ self._formatters = {
12
+ "title": self.format_title,
13
+ "rich_text": self.format_rich_text,
14
+ "url": self.format_url,
15
+ "email": self.format_email,
16
+ "phone_number": self.format_phone_number,
17
+ "number": self.format_number,
18
+ "checkbox": self.format_checkbox,
19
+ "select": self.format_select,
20
+ "multi_select": self.format_multi_select,
21
+ "date": self.format_date,
22
+ "status": self.format_status,
23
+ "relation": self.format_relation,
24
+ }
25
+
26
+ def format_title(self, value: Any) -> Dict[str, Any]:
27
+ """Formatiert einen Titel-Wert."""
28
+ return {"title": [{"type": "text", "text": {"content": str(value)}}]}
29
+
30
+ def format_rich_text(self, value: Any) -> Dict[str, Any]:
31
+ """Formatiert einen Rich-Text-Wert."""
32
+ return {"rich_text": [{"type": "text", "text": {"content": str(value)}}]}
33
+
34
+ def format_url(self, value: str) -> Dict[str, Any]:
35
+ """Formatiert eine URL."""
36
+ return {"url": value}
37
+
38
+ def format_email(self, value: str) -> Dict[str, Any]:
39
+ """Formatiert eine E-Mail-Adresse."""
40
+ return {"email": value}
41
+
42
+ def format_phone_number(self, value: str) -> Dict[str, Any]:
43
+ """Formatiert eine Telefonnummer."""
44
+ return {"phone_number": value}
45
+
46
+ def format_number(self, value: Any) -> Dict[str, Any]:
47
+ """Formatiert eine Zahl."""
48
+ return {"number": float(value)}
49
+
50
+ def format_checkbox(self, value: Any) -> Dict[str, Any]:
51
+ """Formatiert einen Checkbox-Wert."""
52
+ return {"checkbox": bool(value)}
53
+
54
+ def format_select(self, value: str) -> Dict[str, Any]:
55
+ """Formatiert einen Select-Wert."""
56
+ return {"select": {"name": str(value)}}
57
+
58
+ def format_multi_select(self, value: Any) -> Dict[str, Any]:
59
+ """Formatiert einen Multi-Select-Wert."""
60
+ if isinstance(value, list):
61
+ return {"multi_select": [{"name": item} for item in value]}
62
+ return {"multi_select": [{"name": str(value)}]}
63
+
64
+ def format_date(self, value: Any) -> Dict[str, Any]:
65
+ """Formatiert ein Datum."""
66
+ if isinstance(value, dict) and "start" in value:
67
+ return {"date": value}
68
+ return {"date": {"start": str(value)}}
69
+
70
+ def format_status(self, value: str) -> Dict[str, Any]:
71
+ """Formatiert einen Status-Wert."""
72
+ return {"status": {"name": str(value)}}
73
+
74
+ def format_relation(self, value: Any) -> Dict[str, Any]:
75
+ """Formatiert einen Relations-Wert."""
76
+ if isinstance(value, list):
77
+ return {"relation": [{"id": item} for item in value]}
78
+ return {"relation": [{"id": str(value)}]}
79
+
80
+ def format_value(self, property_type: str, value: Any) -> Optional[Dict[str, Any]]:
81
+ """
82
+ Formatiert einen Wert entsprechend des angegebenen Eigenschaftstyps.
83
+
84
+ Args:
85
+ property_type: Notion-Eigenschaftstyp (z.B. "title", "rich_text", "status")
86
+ value: Der zu formatierende Wert
87
+
88
+ Returns:
89
+ Formatierter Wert als Dictionary oder None bei unbekanntem Typ
90
+ """
91
+ formatter = self._formatters.get(property_type)
92
+ if not formatter:
93
+ if self.logger:
94
+ self.logger.warning("Unbekannter Eigenschaftstyp: %s", property_type)
95
+ return None
96
+
97
+ return formatter(value)
@@ -0,0 +1,76 @@
1
+ from typing import Optional
2
+
3
+
4
+ class NotionDatabaseException(Exception):
5
+ """Base exception for all Notion database operations."""
6
+
7
+ pass
8
+
9
+
10
+ class DatabaseNotFoundException(NotionDatabaseException):
11
+ """Exception raised when a database is not found."""
12
+
13
+ def __init__(self, identifier: str, message: str = None):
14
+ self.identifier = identifier
15
+ self.message = message or f"Database not found: {identifier}"
16
+ super().__init__(self.message)
17
+
18
+
19
+ class DatabaseInitializationError(NotionDatabaseException):
20
+ """Exception raised when a database manager fails to initialize."""
21
+
22
+ def __init__(self, database_id: str, message: str = None):
23
+ self.database_id = database_id
24
+ self.message = (
25
+ message or f"Failed to initialize database manager for ID: {database_id}"
26
+ )
27
+ super().__init__(self.message)
28
+
29
+
30
+ class DatabaseConnectionError(NotionDatabaseException):
31
+ """Exception raised when there's an error connecting to Notion API."""
32
+
33
+ def __init__(self, message: str = None):
34
+ self.message = message or "Error connecting to Notion API"
35
+ super().__init__(self.message)
36
+
37
+
38
+ class DatabaseParsingError(NotionDatabaseException):
39
+ """Exception raised when there's an error parsing database data."""
40
+
41
+ def __init__(self, message: str = None):
42
+ self.message = message or "Error parsing database data"
43
+ super().__init__(self.message)
44
+
45
+
46
+ class PageNotFoundException(NotionDatabaseException):
47
+ """Raised when a page is not found or cannot be accessed."""
48
+
49
+ def __init__(self, page_id: str, message: Optional[str] = None):
50
+ self.page_id = page_id
51
+ self.message = message or f"Page not found: {page_id}"
52
+ super().__init__(self.message)
53
+
54
+
55
+ class PageOperationError(NotionDatabaseException):
56
+ """Raised when an operation on a page fails."""
57
+
58
+ def __init__(self, page_id: str, operation: str, message: Optional[str] = None):
59
+ self.page_id = page_id
60
+ self.operation = operation
61
+ self.message = message or f"Failed to {operation} page {page_id}"
62
+ super().__init__(self.message)
63
+
64
+
65
+ class PropertyError(NotionDatabaseException):
66
+ """Raised when there's an error with database properties."""
67
+
68
+ def __init__(
69
+ self, property_name: Optional[str] = None, message: Optional[str] = None
70
+ ):
71
+ self.property_name = property_name
72
+ self.message = (
73
+ message
74
+ or f"Error with property{' ' + property_name if property_name else ''}"
75
+ )
76
+ super().__init__(self.message)
@@ -0,0 +1,9 @@
1
+ from typing import Optional
2
+
3
+
4
+ class PageCreationException(Exception):
5
+ """Exception raised when page creation in Notion fails."""
6
+
7
+ def __init__(self, message: str, response: Optional[dict] = None):
8
+ super().__init__(message)
9
+ self.response = response
@@ -0,0 +1,47 @@
1
+ import logging
2
+ import inspect
3
+
4
+
5
+ def setup_logging():
6
+ logging.basicConfig(
7
+ level=logging.INFO,
8
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
9
+ )
10
+
11
+
12
+ class LoggingMixin:
13
+ @property
14
+ def logger(self):
15
+ if not hasattr(self, "_logger"):
16
+ self._logger = logging.getLogger(self.__class__.__name__)
17
+ return self._logger
18
+
19
+ @classmethod
20
+ def class_logger(cls):
21
+ """Class logger - für Klassenmethoden"""
22
+ return logging.getLogger(cls.__name__)
23
+
24
+ @staticmethod
25
+ def static_logger():
26
+ stack = inspect.stack()
27
+ for frame_info in stack[1:]:
28
+ class_name = LoggingMixin._get_class_name_from_frame(frame_info.frame)
29
+ if class_name:
30
+ return logging.getLogger(class_name)
31
+ return logging.getLogger("UnknownStaticContext")
32
+
33
+ @staticmethod
34
+ def _get_class_name_from_frame(frame):
35
+ local_vars = frame.f_locals
36
+ if "self" in local_vars:
37
+ return local_vars["self"].__class__.__name__
38
+
39
+ if "cls" in local_vars:
40
+ return local_vars["cls"].__name__
41
+
42
+ if "__qualname__" in frame.f_code.co_names:
43
+ qualname = frame.f_code.co_qualname
44
+ if "." in qualname:
45
+ return qualname.split(".")[0]
46
+
47
+ return None
@@ -0,0 +1,20 @@
1
+ from typing import TypeVar
2
+ from functools import wraps
3
+
4
+ T = TypeVar("T")
5
+
6
+
7
+ def singleton(cls: T) -> T:
8
+ """
9
+ Decorator zur Implementierung des Singleton-Musters.
10
+ Stellt sicher, dass nur eine Instanz der Klasse existiert.
11
+ """
12
+ instances = {}
13
+
14
+ @wraps(cls)
15
+ def get_instance(*args, **kwargs):
16
+ if cls not in instances:
17
+ instances[cls] = cls(*args, **kwargs)
18
+ return instances[cls]
19
+
20
+ return get_instance
@@ -0,0 +1,24 @@
1
+ import re
2
+ from typing import Optional
3
+
4
+ UUID_PATTERN = r"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"
5
+ UUID_RAW_PATTERN = r"([a-f0-9]{32})"
6
+
7
+
8
+ def extract_uuid(source: str) -> Optional[str]:
9
+ match = re.search(UUID_RAW_PATTERN, source.lower())
10
+ if not match:
11
+ return None
12
+
13
+ uuid_raw = match.group(1)
14
+ return f"{uuid_raw[0:8]}-{uuid_raw[8:12]}-{uuid_raw[12:16]}-{uuid_raw[16:20]}-{uuid_raw[20:32]}"
15
+
16
+
17
+ def is_valid_uuid(uuid: str) -> bool:
18
+ return bool(re.match(UUID_PATTERN, uuid.lower()))
19
+
20
+
21
+ def format_uuid(value: str) -> Optional[str]:
22
+ if is_valid_uuid(value):
23
+ return value
24
+ return extract_uuid(value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: notionary
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: A toolkit to convert between Markdown and Notion blocks
5
5
  Home-page: https://github.com/mathisarends/notionary
6
6
  Author: Mathis Arends
@@ -0,0 +1,49 @@
1
+ notionary/__init__.py,sha256=5T16clJlSHFsopcPUnkGrEo8spNDUQ0i-O00UEF7nR8,320
2
+ notionary/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ notionary/core/notion_client.py,sha256=AKxQcXkQ9OsvFBBJEvMYfXipos8ttOMf_LtT09aR41M,4646
4
+ notionary/core/converters/__init__.py,sha256=GOUehJbe4BKHtec1MqL1YGu3AX8zFtkwSZfhYkY5-P0,1798
5
+ notionary/core/converters/markdown_to_notion_converter.py,sha256=PGtg4v5lUvkXXl1Y8E6a3Mf8hEfxfhBrslPs_H_Lq_E,16564
6
+ notionary/core/converters/notion_to_markdown_converter.py,sha256=c8GyWX8-UrNfRDk7OOBKbSEb5qOwljUCwI6g5risO2c,1287
7
+ notionary/core/converters/elements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ notionary/core/converters/elements/bookmark_element.py,sha256=bpHobkGnyBGDAJK5vY9R3Ntl4GiRSF-EyyA31aq2O3E,8593
9
+ notionary/core/converters/elements/callout_element.py,sha256=rkDoXikjIl-zU3GLawSXgRunBJGLnEvin9zIlCgW4TY,5964
10
+ notionary/core/converters/elements/code_block_element.py,sha256=G1iGMsGSK5KPSk-tA8TsPs9XNU9ydjYfOVnjIvdZG74,5189
11
+ notionary/core/converters/elements/column_element.py,sha256=ZwQsLBEownVJnzyv-GfNjvzJhAfKz9ncggqZUmZHF5A,10722
12
+ notionary/core/converters/elements/divider_element.py,sha256=Ul0wXHY96qWL72iAvttRQMOoAGuASgwFwPraGnpUkX0,2792
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/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ notionary/core/converters/registry/block_element_registry.py,sha256=0dpRFMM67UVmXRMP4-Ubc_uCZCVVmRKgxPpueCeknjw,8619
26
+ notionary/core/converters/registry/block_element_registry_builder.py,sha256=yTV1GPKAN7o65r9jHIqPeBCw0ICdaUZnRC5JKNwpRq4,9227
27
+ notionary/core/database/database_info_service.py,sha256=58k7om0UXP8w0jCJHewccG5UbOvELMBAbQvXOm7F1OM,1341
28
+ notionary/core/database/database_query_service.py,sha256=ggD-Sx9GdRTeKn9ytGBxijQw6euYgV__iTpObT24ebo,2442
29
+ notionary/core/database/database_schema_service.py,sha256=aVyguzw8YjgQ632TDyRCDfWWCsIok3vJ4Sx3dnG9pss,1869
30
+ notionary/core/database/notion_database_manager.py,sha256=E3qUxPYEJ1drurmtZaqepskH84Iw-4RN3MyXv8cb8zQ,11443
31
+ notionary/core/database/notion_database_manager_factory.py,sha256=jYQeoWV4VKyfCkbxCMVf0aeShfXDvE2EVTs3Jr--Ro8,8285
32
+ notionary/core/database/notion_database_schema.py,sha256=DpZPkrR15u24PGd8jhTrqngu__5LviEsU-VBZgRzrHM,12486
33
+ notionary/core/database/notion_database_writer.py,sha256=qpKOSDLI89GWL1kDnzLKSY5GVIzQHVYAWUl12_n-nwU,13651
34
+ notionary/core/database/page_service.py,sha256=NzKCU2G-mnmqOitNWCJ6jOr0HSv1vPi1-ScSruvFdqg,5190
35
+ notionary/core/database/models/page_result.py,sha256=Vmm5_oYpYAkIIJVoTd1ZZGloeC3cmFLMYP255mAmtaw,233
36
+ notionary/core/page/notion_page_manager.py,sha256=iatr-ERpjdpdRRYH0w097YGVKbtor7GWWFqa421wOO8,4109
37
+ notionary/core/page/page_content_manager.py,sha256=wx-2bW4znIaBVZeFwtoVrmlGUwHMLBPOLkQCZDIV3sA,3180
38
+ notionary/core/page/property_formatter.py,sha256=X70Yfg0Y8HYLrFH7Y_BZVhhc_6b369jjn02bc5IZBBI,3780
39
+ notionary/core/page/meta_data/metadata_editor.py,sha256=FpB7BA5cicWmEictwdn7EuRBMX7bGvSxbdM5Grs-jLI,1347
40
+ notionary/exceptions/database_exceptions.py,sha256=I-Tx6bYRLpi5pjGPtbT-Mqxvz3BFgYTiuZxknJeLxtI,2638
41
+ notionary/exceptions/page_creation_exception.py,sha256=4v7IuZD6GsQLrqhDLriGjuG3ML638gAO53zDCrLePuU,281
42
+ notionary/util/logging_mixin.py,sha256=fKsx9t90bwvL74ZX3dU-sXdC4TZCQyO6qU9I8txkw_U,1369
43
+ notionary/util/singleton_decorator.py,sha256=GTNMfIlVNRUVMw_c88xqd12-DcqZJjmyidN54yqiNVw,472
44
+ notionary/util/uuid_utils.py,sha256=qS2tdJSqw_gLyQxVIqlIdmkzGa7b9bJ-vw88RiQ-oGc,680
45
+ notionary-0.1.3.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
46
+ notionary-0.1.3.dist-info/METADATA,sha256=CCgL4-_K2WKIjzW5CFeOpDvcHxqe92xjTc1YeWJ_hbM,6153
47
+ notionary-0.1.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
48
+ notionary-0.1.3.dist-info/top_level.txt,sha256=fhONa6BMHQXqthx5PanWGbPL0b8rdFqhrJKVLf_adSs,10
49
+ notionary-0.1.3.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ notionary
@@ -1,5 +0,0 @@
1
- notionary-0.1.1.dist-info/licenses/LICENSE,sha256=zOm3cRT1qD49eg7vgw95MI79rpUAZa1kRBFwL2FkAr8,1120
2
- notionary-0.1.1.dist-info/METADATA,sha256=dfNzwMTI_-JHQAIOgKb-NOM2nbC_u2zzBukjiTzQTAg,6153
3
- notionary-0.1.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
4
- notionary-0.1.1.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
- notionary-0.1.1.dist-info/RECORD,,
@@ -1 +0,0 @@
1
-