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.
Files changed (395) hide show
  1. notionary/__init__.py +5 -20
  2. notionary/blocks/__init__.py +4 -4
  3. notionary/blocks/client.py +90 -216
  4. notionary/blocks/enums.py +167 -0
  5. notionary/blocks/rich_text/markdown_rich_text_converter.py +280 -0
  6. notionary/blocks/rich_text/models.py +178 -0
  7. notionary/blocks/rich_text/name_id_resolver/__init__.py +13 -0
  8. notionary/blocks/rich_text/name_id_resolver/data_source.py +32 -0
  9. notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  10. notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  11. notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  12. notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  13. notionary/blocks/rich_text/rich_text_markdown_converter.py +144 -0
  14. notionary/blocks/rich_text/rich_text_patterns.py +42 -0
  15. notionary/blocks/schemas.py +778 -0
  16. notionary/comments/__init__.py +1 -22
  17. notionary/comments/client.py +52 -187
  18. notionary/comments/factory.py +38 -0
  19. notionary/comments/models.py +5 -127
  20. notionary/comments/schemas.py +240 -0
  21. notionary/comments/service.py +34 -0
  22. notionary/data_source/http/client.py +11 -0
  23. notionary/data_source/http/data_source_instance_client.py +104 -0
  24. notionary/data_source/properties/schemas.py +402 -0
  25. notionary/data_source/query/builder.py +448 -0
  26. notionary/data_source/query/resolver.py +114 -0
  27. notionary/data_source/query/schema.py +302 -0
  28. notionary/data_source/query/validator.py +73 -0
  29. notionary/data_source/schema/registry.py +104 -0
  30. notionary/data_source/schema/service.py +136 -0
  31. notionary/data_source/schemas.py +27 -0
  32. notionary/data_source/service.py +377 -0
  33. notionary/database/client.py +30 -135
  34. notionary/database/database_metadata_update_client.py +19 -0
  35. notionary/database/schemas.py +29 -0
  36. notionary/database/service.py +168 -0
  37. notionary/exceptions/__init__.py +33 -0
  38. notionary/exceptions/api.py +41 -0
  39. notionary/exceptions/base.py +2 -0
  40. notionary/exceptions/block_parsing.py +16 -0
  41. notionary/exceptions/data_source/__init__.py +6 -0
  42. notionary/exceptions/data_source/builder.py +182 -0
  43. notionary/exceptions/data_source/properties.py +34 -0
  44. notionary/exceptions/properties.py +58 -0
  45. notionary/exceptions/search.py +57 -0
  46. notionary/file_upload/client.py +18 -30
  47. notionary/file_upload/models.py +7 -8
  48. notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
  49. notionary/http/client.py +204 -0
  50. notionary/http/models.py +50 -0
  51. notionary/page/blocks/client.py +1 -0
  52. notionary/page/content/factory.py +73 -0
  53. notionary/page/content/markdown/__init__.py +5 -0
  54. notionary/page/content/markdown/builder.py +226 -0
  55. notionary/page/content/markdown/nodes/__init__.py +52 -0
  56. notionary/page/content/markdown/nodes/audio.py +23 -0
  57. notionary/page/content/markdown/nodes/base.py +12 -0
  58. notionary/page/content/markdown/nodes/bookmark.py +25 -0
  59. notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  60. notionary/page/content/markdown/nodes/bulleted_list.py +41 -0
  61. notionary/page/content/markdown/nodes/callout.py +34 -0
  62. notionary/page/content/markdown/nodes/code.py +28 -0
  63. notionary/page/content/markdown/nodes/columns.py +69 -0
  64. notionary/page/content/markdown/nodes/container.py +64 -0
  65. notionary/page/content/markdown/nodes/divider.py +14 -0
  66. notionary/page/content/markdown/nodes/embed.py +23 -0
  67. notionary/page/content/markdown/nodes/equation.py +19 -0
  68. notionary/page/content/markdown/nodes/file.py +23 -0
  69. notionary/page/content/markdown/nodes/heading.py +36 -0
  70. notionary/page/content/markdown/nodes/image.py +23 -0
  71. notionary/page/content/markdown/nodes/mixins/__init__.py +5 -0
  72. notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  73. notionary/page/content/markdown/nodes/numbered_list.py +38 -0
  74. notionary/page/content/markdown/nodes/paragraph.py +14 -0
  75. notionary/page/content/markdown/nodes/pdf.py +23 -0
  76. notionary/page/content/markdown/nodes/quote.py +27 -0
  77. notionary/page/content/markdown/nodes/space.py +14 -0
  78. notionary/page/content/markdown/nodes/table.py +45 -0
  79. notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  80. notionary/page/content/markdown/nodes/todo.py +38 -0
  81. notionary/page/content/markdown/nodes/toggle.py +27 -0
  82. notionary/page/content/markdown/nodes/video.py +23 -0
  83. notionary/page/content/parser/context.py +126 -0
  84. notionary/page/content/parser/factory.py +210 -0
  85. notionary/page/content/parser/parsers/__init__.py +58 -0
  86. notionary/page/content/parser/parsers/audio.py +40 -0
  87. notionary/page/content/parser/parsers/base.py +30 -0
  88. notionary/page/content/parser/parsers/bookmark.py +33 -0
  89. notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  90. notionary/page/content/parser/parsers/bulleted_list.py +85 -0
  91. notionary/page/content/parser/parsers/callout.py +100 -0
  92. notionary/page/content/parser/parsers/caption.py +55 -0
  93. notionary/page/content/parser/parsers/code.py +81 -0
  94. notionary/page/content/parser/parsers/column.py +76 -0
  95. notionary/page/content/parser/parsers/column_list.py +81 -0
  96. notionary/page/content/parser/parsers/divider.py +33 -0
  97. notionary/page/content/parser/parsers/embed.py +33 -0
  98. notionary/page/content/parser/parsers/equation.py +65 -0
  99. notionary/page/content/parser/parsers/file.py +42 -0
  100. notionary/page/content/parser/parsers/heading.py +115 -0
  101. notionary/page/content/parser/parsers/image.py +42 -0
  102. notionary/page/content/parser/parsers/numbered_list.py +89 -0
  103. notionary/page/content/parser/parsers/paragraph.py +37 -0
  104. notionary/page/content/parser/parsers/pdf.py +42 -0
  105. notionary/page/content/parser/parsers/quote.py +125 -0
  106. notionary/page/content/parser/parsers/space.py +41 -0
  107. notionary/page/content/parser/parsers/table.py +144 -0
  108. notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  109. notionary/page/content/parser/parsers/todo.py +96 -0
  110. notionary/page/content/parser/parsers/toggle.py +70 -0
  111. notionary/page/content/parser/parsers/video.py +42 -0
  112. notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  113. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +95 -0
  114. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +114 -0
  115. notionary/page/content/parser/post_processing/port.py +9 -0
  116. notionary/page/content/parser/post_processing/service.py +16 -0
  117. notionary/page/content/parser/pre_processsing/handlers/__init__.py +11 -0
  118. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +130 -0
  119. notionary/page/content/parser/pre_processsing/handlers/indentation.py +84 -0
  120. notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  121. notionary/page/content/parser/pre_processsing/handlers/whitespace.py +73 -0
  122. notionary/page/content/parser/pre_processsing/service.py +15 -0
  123. notionary/page/content/parser/service.py +78 -0
  124. notionary/page/content/renderer/context.py +51 -0
  125. notionary/page/content/renderer/factory.py +231 -0
  126. notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  127. notionary/page/content/renderer/post_processing/handlers/numbered_list.py +156 -0
  128. notionary/page/content/renderer/post_processing/port.py +7 -0
  129. notionary/page/content/renderer/post_processing/service.py +15 -0
  130. notionary/page/content/renderer/renderers/__init__.py +55 -0
  131. notionary/page/content/renderer/renderers/audio.py +31 -0
  132. notionary/page/content/renderer/renderers/base.py +31 -0
  133. notionary/page/content/renderer/renderers/bookmark.py +25 -0
  134. notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  135. notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  136. notionary/page/content/renderer/renderers/callout.py +50 -0
  137. notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  138. notionary/page/content/renderer/renderers/code.py +34 -0
  139. notionary/page/content/renderer/renderers/column.py +53 -0
  140. notionary/page/content/renderer/renderers/column_list.py +44 -0
  141. notionary/page/content/renderer/renderers/divider.py +22 -0
  142. notionary/page/content/renderer/renderers/embed.py +25 -0
  143. notionary/page/content/renderer/renderers/equation.py +37 -0
  144. notionary/page/content/renderer/renderers/fallback.py +24 -0
  145. notionary/page/content/renderer/renderers/file.py +40 -0
  146. notionary/page/content/renderer/renderers/heading.py +95 -0
  147. notionary/page/content/renderer/renderers/image.py +31 -0
  148. notionary/page/content/renderer/renderers/numbered_list.py +42 -0
  149. notionary/page/content/renderer/renderers/paragraph.py +40 -0
  150. notionary/page/content/renderer/renderers/pdf.py +31 -0
  151. notionary/page/content/renderer/renderers/quote.py +49 -0
  152. notionary/page/content/renderer/renderers/table.py +115 -0
  153. notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  154. notionary/page/content/renderer/renderers/table_row.py +17 -0
  155. notionary/page/content/renderer/renderers/todo.py +56 -0
  156. notionary/page/content/renderer/renderers/toggle.py +52 -0
  157. notionary/page/content/renderer/renderers/video.py +31 -0
  158. notionary/page/content/renderer/service.py +50 -0
  159. notionary/page/content/service.py +68 -0
  160. notionary/page/content/syntax/__init__.py +4 -0
  161. notionary/page/content/syntax/grammar.py +10 -0
  162. notionary/page/content/syntax/models.py +66 -0
  163. notionary/page/content/syntax/registry.py +393 -0
  164. notionary/page/page_context.py +7 -16
  165. notionary/page/page_http_client.py +15 -0
  166. notionary/page/page_metadata_update_client.py +19 -0
  167. notionary/page/properties/client.py +144 -0
  168. notionary/page/properties/factory.py +26 -0
  169. notionary/page/properties/models.py +308 -0
  170. notionary/page/properties/service.py +261 -0
  171. notionary/page/schemas.py +13 -0
  172. notionary/page/service.py +225 -0
  173. notionary/shared/entity/client.py +29 -0
  174. notionary/shared/entity/dto_parsers.py +53 -0
  175. notionary/shared/entity/entity_metadata_update_client.py +41 -0
  176. notionary/shared/entity/schemas.py +45 -0
  177. notionary/shared/entity/service.py +171 -0
  178. notionary/shared/models/cover.py +20 -0
  179. notionary/shared/models/file.py +21 -0
  180. notionary/shared/models/icon.py +28 -0
  181. notionary/shared/models/parent.py +41 -0
  182. notionary/shared/properties/type.py +30 -0
  183. notionary/shared/typings.py +3 -0
  184. notionary/user/__init__.py +4 -8
  185. notionary/user/base.py +138 -0
  186. notionary/user/bot.py +70 -0
  187. notionary/user/client.py +22 -111
  188. notionary/user/person.py +41 -0
  189. notionary/user/schemas.py +67 -0
  190. notionary/user/service.py +65 -0
  191. notionary/utils/date.py +51 -0
  192. notionary/utils/decorators.py +122 -0
  193. notionary/utils/fuzzy.py +68 -0
  194. notionary/utils/mixins/logging.py +58 -0
  195. notionary/utils/pagination.py +100 -0
  196. notionary/utils/uuid_utils.py +20 -0
  197. notionary/workspace/__init__.py +4 -0
  198. notionary/workspace/client.py +62 -0
  199. notionary/workspace/query/__init__.py +3 -0
  200. notionary/workspace/query/builder.py +60 -0
  201. notionary/workspace/query/models.py +61 -0
  202. notionary/workspace/query/service.py +100 -0
  203. notionary/workspace/schemas.py +21 -0
  204. notionary/workspace/service.py +116 -0
  205. notionary-0.3.0.dist-info/METADATA +201 -0
  206. notionary-0.3.0.dist-info/RECORD +209 -0
  207. {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info}/WHEEL +1 -1
  208. {notionary-0.2.27.dist-info → notionary-0.3.0.dist-info/licenses}/LICENSE +9 -9
  209. notionary/base_notion_client.py +0 -219
  210. notionary/blocks/_bootstrap.py +0 -271
  211. notionary/blocks/audio/__init__.py +0 -11
  212. notionary/blocks/audio/audio_element.py +0 -158
  213. notionary/blocks/audio/audio_markdown_node.py +0 -24
  214. notionary/blocks/audio/audio_models.py +0 -10
  215. notionary/blocks/base_block_element.py +0 -42
  216. notionary/blocks/bookmark/__init__.py +0 -12
  217. notionary/blocks/bookmark/bookmark_element.py +0 -83
  218. notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  219. notionary/blocks/bookmark/bookmark_models.py +0 -15
  220. notionary/blocks/breadcrumbs/__init__.py +0 -15
  221. notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  222. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  223. notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  224. notionary/blocks/bulleted_list/__init__.py +0 -15
  225. notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  226. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  227. notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  228. notionary/blocks/callout/__init__.py +0 -12
  229. notionary/blocks/callout/callout_element.py +0 -99
  230. notionary/blocks/callout/callout_markdown_node.py +0 -19
  231. notionary/blocks/callout/callout_models.py +0 -33
  232. notionary/blocks/child_database/__init__.py +0 -14
  233. notionary/blocks/child_database/child_database_element.py +0 -59
  234. notionary/blocks/child_database/child_database_models.py +0 -12
  235. notionary/blocks/child_page/__init__.py +0 -9
  236. notionary/blocks/child_page/child_page_element.py +0 -94
  237. notionary/blocks/child_page/child_page_models.py +0 -12
  238. notionary/blocks/code/__init__.py +0 -11
  239. notionary/blocks/code/code_element.py +0 -149
  240. notionary/blocks/code/code_markdown_node.py +0 -80
  241. notionary/blocks/code/code_models.py +0 -94
  242. notionary/blocks/column/__init__.py +0 -25
  243. notionary/blocks/column/column_element.py +0 -65
  244. notionary/blocks/column/column_list_element.py +0 -52
  245. notionary/blocks/column/column_list_markdown_node.py +0 -34
  246. notionary/blocks/column/column_markdown_node.py +0 -42
  247. notionary/blocks/column/column_models.py +0 -26
  248. notionary/blocks/divider/__init__.py +0 -12
  249. notionary/blocks/divider/divider_element.py +0 -41
  250. notionary/blocks/divider/divider_markdown_node.py +0 -11
  251. notionary/blocks/divider/divider_models.py +0 -12
  252. notionary/blocks/embed/__init__.py +0 -12
  253. notionary/blocks/embed/embed_element.py +0 -98
  254. notionary/blocks/embed/embed_markdown_node.py +0 -19
  255. notionary/blocks/embed/embed_models.py +0 -14
  256. notionary/blocks/equation/__init__.py +0 -13
  257. notionary/blocks/equation/equation_element.py +0 -133
  258. notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  259. notionary/blocks/equation/equation_models.py +0 -11
  260. notionary/blocks/file/__init__.py +0 -23
  261. notionary/blocks/file/file_element.py +0 -133
  262. notionary/blocks/file/file_element_markdown_node.py +0 -24
  263. notionary/blocks/file/file_element_models.py +0 -39
  264. notionary/blocks/heading/__init__.py +0 -19
  265. notionary/blocks/heading/heading_element.py +0 -112
  266. notionary/blocks/heading/heading_markdown_node.py +0 -16
  267. notionary/blocks/heading/heading_models.py +0 -29
  268. notionary/blocks/image_block/__init__.py +0 -11
  269. notionary/blocks/image_block/image_element.py +0 -130
  270. notionary/blocks/image_block/image_markdown_node.py +0 -25
  271. notionary/blocks/image_block/image_models.py +0 -10
  272. notionary/blocks/markdown/markdown_builder.py +0 -525
  273. notionary/blocks/markdown/markdown_document_model.py +0 -0
  274. notionary/blocks/markdown/markdown_node.py +0 -25
  275. notionary/blocks/mixins/captions/__init__.py +0 -4
  276. notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  277. notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  278. notionary/blocks/mixins/file_upload/__init__.py +0 -3
  279. notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  280. notionary/blocks/models.py +0 -174
  281. notionary/blocks/numbered_list/__init__.py +0 -16
  282. notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  283. notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  284. notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  285. notionary/blocks/paragraph/__init__.py +0 -15
  286. notionary/blocks/paragraph/paragraph_element.py +0 -58
  287. notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  288. notionary/blocks/paragraph/paragraph_models.py +0 -16
  289. notionary/blocks/pdf/__init__.py +0 -11
  290. notionary/blocks/pdf/pdf_element.py +0 -146
  291. notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  292. notionary/blocks/pdf/pdf_models.py +0 -11
  293. notionary/blocks/quote/__init__.py +0 -14
  294. notionary/blocks/quote/quote_element.py +0 -75
  295. notionary/blocks/quote/quote_markdown_node.py +0 -16
  296. notionary/blocks/quote/quote_models.py +0 -18
  297. notionary/blocks/registry/__init__.py +0 -3
  298. notionary/blocks/registry/block_registry.py +0 -150
  299. notionary/blocks/rich_text/__init__.py +0 -33
  300. notionary/blocks/rich_text/rich_text_models.py +0 -221
  301. notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  302. notionary/blocks/syntax_prompt_builder.py +0 -137
  303. notionary/blocks/table/__init__.py +0 -19
  304. notionary/blocks/table/table_element.py +0 -225
  305. notionary/blocks/table/table_markdown_node.py +0 -42
  306. notionary/blocks/table/table_models.py +0 -28
  307. notionary/blocks/table_of_contents/__init__.py +0 -17
  308. notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  309. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  310. notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  311. notionary/blocks/todo/__init__.py +0 -12
  312. notionary/blocks/todo/todo_element.py +0 -81
  313. notionary/blocks/todo/todo_markdown_node.py +0 -21
  314. notionary/blocks/todo/todo_models.py +0 -18
  315. notionary/blocks/toggle/__init__.py +0 -12
  316. notionary/blocks/toggle/toggle_element.py +0 -112
  317. notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  318. notionary/blocks/toggle/toggle_models.py +0 -17
  319. notionary/blocks/toggleable_heading/__init__.py +0 -11
  320. notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  321. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  322. notionary/blocks/types.py +0 -130
  323. notionary/blocks/video/__init__.py +0 -11
  324. notionary/blocks/video/video_element.py +0 -187
  325. notionary/blocks/video/video_element_models.py +0 -10
  326. notionary/blocks/video/video_markdown_node.py +0 -26
  327. notionary/database/__init__.py +0 -4
  328. notionary/database/database.py +0 -480
  329. notionary/database/database_filter_builder.py +0 -173
  330. notionary/database/database_provider.py +0 -227
  331. notionary/database/exceptions.py +0 -13
  332. notionary/database/models.py +0 -337
  333. notionary/database/notion_database.py +0 -487
  334. notionary/file_upload/__init__.py +0 -7
  335. notionary/page/client.py +0 -124
  336. notionary/page/markdown_whitespace_processor.py +0 -129
  337. notionary/page/models.py +0 -322
  338. notionary/page/notion_page.py +0 -712
  339. notionary/page/page_content_deleting_service.py +0 -117
  340. notionary/page/page_content_writer.py +0 -80
  341. notionary/page/property_formatter.py +0 -99
  342. notionary/page/reader/handler/__init__.py +0 -19
  343. notionary/page/reader/handler/base_block_renderer.py +0 -44
  344. notionary/page/reader/handler/block_processing_context.py +0 -35
  345. notionary/page/reader/handler/block_rendering_context.py +0 -48
  346. notionary/page/reader/handler/column_list_renderer.py +0 -51
  347. notionary/page/reader/handler/column_renderer.py +0 -60
  348. notionary/page/reader/handler/equation_renderer.py +0 -0
  349. notionary/page/reader/handler/line_renderer.py +0 -73
  350. notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  351. notionary/page/reader/handler/toggle_renderer.py +0 -69
  352. notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  353. notionary/page/reader/page_content_retriever.py +0 -81
  354. notionary/page/search_filter_builder.py +0 -132
  355. notionary/page/utils.py +0 -60
  356. notionary/page/writer/handler/__init__.py +0 -24
  357. notionary/page/writer/handler/code_handler.py +0 -72
  358. notionary/page/writer/handler/column_handler.py +0 -141
  359. notionary/page/writer/handler/column_list_handler.py +0 -139
  360. notionary/page/writer/handler/equation_handler.py +0 -74
  361. notionary/page/writer/handler/line_handler.py +0 -35
  362. notionary/page/writer/handler/line_processing_context.py +0 -54
  363. notionary/page/writer/handler/regular_line_handler.py +0 -86
  364. notionary/page/writer/handler/table_handler.py +0 -66
  365. notionary/page/writer/handler/toggle_handler.py +0 -159
  366. notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  367. notionary/page/writer/markdown_to_notion_converter.py +0 -139
  368. notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  369. notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  370. notionary/page/writer/notion_text_length_processor.py +0 -150
  371. notionary/schemas/__init__.py +0 -3
  372. notionary/schemas/base.py +0 -73
  373. notionary/shared/__init__.py +0 -3
  374. notionary/shared/name_to_id_resolver.py +0 -203
  375. notionary/telemetry/__init__.py +0 -19
  376. notionary/telemetry/service.py +0 -136
  377. notionary/telemetry/views.py +0 -73
  378. notionary/user/base_notion_user.py +0 -53
  379. notionary/user/models.py +0 -84
  380. notionary/user/notion_bot_user.py +0 -226
  381. notionary/user/notion_user.py +0 -255
  382. notionary/user/notion_user_manager.py +0 -101
  383. notionary/util/__init__.py +0 -15
  384. notionary/util/concurrency_limiter.py +0 -0
  385. notionary/util/factory_decorator.py +0 -0
  386. notionary/util/factory_only.py +0 -37
  387. notionary/util/fuzzy.py +0 -75
  388. notionary/util/logging_mixin.py +0 -59
  389. notionary/util/page_id_utils.py +0 -27
  390. notionary/util/singleton.py +0 -18
  391. notionary/util/singleton_metaclass.py +0 -22
  392. notionary/workspace.py +0 -105
  393. notionary-0.2.27.dist-info/METADATA +0 -270
  394. notionary-0.2.27.dist-info/RECORD +0 -202
  395. /notionary/{database → user}/factory.py +0 -0
@@ -0,0 +1,14 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class DividerMarkdownNode(MarkdownNode):
8
+ def __init__(self, syntax_registry: SyntaxRegistry | None = None) -> None:
9
+ super().__init__(syntax_registry=syntax_registry)
10
+
11
+ @override
12
+ def to_markdown(self) -> str:
13
+ divider_syntax = self._syntax_registry.get_divider_syntax()
14
+ return divider_syntax.start_delimiter
@@ -0,0 +1,23 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.mixins.caption import CaptionMarkdownNodeMixin
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class EmbedMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
9
+ def __init__(
10
+ self,
11
+ url: str,
12
+ caption: str | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.url = url
17
+ self.caption = caption
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ embed_syntax = self._syntax_registry.get_embed_syntax()
22
+ base_markdown = f"{embed_syntax.start_delimiter}{self.url}{embed_syntax.end_delimiter}"
23
+ return self._append_caption_to_markdown(base_markdown, self.caption)
@@ -0,0 +1,19 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class EquationMarkdownNode(MarkdownNode):
8
+ def __init__(self, expression: str, syntax_registry: SyntaxRegistry | None = None) -> None:
9
+ super().__init__(syntax_registry=syntax_registry)
10
+ self.expression = expression
11
+
12
+ @override
13
+ def to_markdown(self) -> str:
14
+ expr = self.expression.strip()
15
+ equation_syntax = self._syntax_registry.get_equation_syntax()
16
+ if not expr:
17
+ return f"{equation_syntax.start_delimiter}{equation_syntax.end_delimiter}"
18
+
19
+ return f"{equation_syntax.start_delimiter}{expr}{equation_syntax.end_delimiter}"
@@ -0,0 +1,23 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.mixins.caption import CaptionMarkdownNodeMixin
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class FileMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
9
+ def __init__(
10
+ self,
11
+ url: str,
12
+ caption: str | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.url = url
17
+ self.caption = caption
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ file_syntax = self._syntax_registry.get_file_syntax()
22
+ base_markdown = f"{file_syntax.start_delimiter}{self.url}{file_syntax.end_delimiter}"
23
+ return self._append_caption_to_markdown(base_markdown, self.caption)
@@ -0,0 +1,36 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.container import ContainerNode
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class HeadingMarkdownNode(ContainerNode):
9
+ MIN_LEVEL = 1
10
+ MAX_LEVEL = 3
11
+
12
+ def __init__(
13
+ self,
14
+ text: str,
15
+ level: int = 1,
16
+ children: list[MarkdownNode] | None = None,
17
+ syntax_registry: SyntaxRegistry | None = None,
18
+ ) -> None:
19
+ super().__init__(syntax_registry=syntax_registry)
20
+ self.text = text
21
+ self.level = self._validate_level(level)
22
+ self.children = children or []
23
+
24
+ @override
25
+ def to_markdown(self) -> str:
26
+ heading_prefix = self._get_heading_prefix()
27
+ result = f"{heading_prefix} {self.text}"
28
+ result += self.render_children()
29
+ return result
30
+
31
+ def _validate_level(self, level: int) -> int:
32
+ return max(self.MIN_LEVEL, min(self.MAX_LEVEL, level))
33
+
34
+ def _get_heading_prefix(self) -> str:
35
+ delimiter = self._syntax_registry.get_heading_syntax().start_delimiter
36
+ return delimiter * self.level
@@ -0,0 +1,23 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.mixins.caption import CaptionMarkdownNodeMixin
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class ImageMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
9
+ def __init__(
10
+ self,
11
+ url: str,
12
+ caption: str | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.url = url
17
+ self.caption = caption
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ image_syntax = self._syntax_registry.get_image_syntax()
22
+ base_markdown = f"{image_syntax.start_delimiter}{self.url}{image_syntax.end_delimiter}"
23
+ return self._append_caption_to_markdown(base_markdown, self.caption)
@@ -0,0 +1,5 @@
1
+ from .caption import CaptionMarkdownNodeMixin
2
+
3
+ __all__ = [
4
+ "CaptionMarkdownNodeMixin",
5
+ ]
@@ -0,0 +1,12 @@
1
+ from notionary.page.content.syntax import SyntaxRegistry
2
+
3
+
4
+ class CaptionMarkdownNodeMixin:
5
+ _syntax_registry: SyntaxRegistry
6
+
7
+ def _append_caption_to_markdown(self, base_markdown: str, caption: str | None) -> str:
8
+ if not caption:
9
+ return base_markdown
10
+
11
+ caption_syntax = self._syntax_registry.get_caption_syntax()
12
+ return f"{base_markdown}\n{caption_syntax.start_delimiter} {caption}"
@@ -0,0 +1,38 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.container import ContainerNode
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class NumberedListMarkdownNode(ContainerNode):
9
+ def __init__(
10
+ self,
11
+ texts: list[str],
12
+ children: list[MarkdownNode | None] | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ):
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.texts = texts
17
+ self.children = children or []
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ list_items = [self._render_list_item(index, text) for index, text in enumerate(self.texts)]
22
+ return "\n".join(list_items)
23
+
24
+ def _render_list_item(self, index: int, text: str) -> str:
25
+ item_number = index + 1
26
+ item_line = f"{item_number}. {text}"
27
+
28
+ child = self._get_child_for_item(index)
29
+ if child:
30
+ child_content = self.render_child(child)
31
+ return f"{item_line}\n{child_content}"
32
+
33
+ return item_line
34
+
35
+ def _get_child_for_item(self, index: int) -> MarkdownNode | None:
36
+ if not self.children or index >= len(self.children):
37
+ return None
38
+ return self.children[index]
@@ -0,0 +1,14 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class ParagraphMarkdownNode(MarkdownNode):
8
+ def __init__(self, text: str, syntax_registry: SyntaxRegistry | None = None):
9
+ super().__init__(syntax_registry=syntax_registry)
10
+ self.text = text
11
+
12
+ @override
13
+ def to_markdown(self) -> str:
14
+ return self.text
@@ -0,0 +1,23 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.mixins.caption import CaptionMarkdownNodeMixin
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class PdfMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
9
+ def __init__(
10
+ self,
11
+ url: str,
12
+ caption: str | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.url = url
17
+ self.caption = caption
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ pdf_syntax = self._syntax_registry.get_pdf_syntax()
22
+ base_markdown = f"{pdf_syntax.start_delimiter}{self.url}{pdf_syntax.end_delimiter}"
23
+ return self._append_caption_to_markdown(base_markdown, self.caption)
@@ -0,0 +1,27 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.container import ContainerNode
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class QuoteMarkdownNode(ContainerNode):
9
+ def __init__(
10
+ self,
11
+ text: str,
12
+ children: list[MarkdownNode] | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.text = text
17
+ self.children = children or []
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ quote_delimiter = self._get_quote_delimiter()
22
+ result = f"{quote_delimiter}{self.text}"
23
+ result += self.render_children()
24
+ return result
25
+
26
+ def _get_quote_delimiter(self) -> str:
27
+ return self._syntax_registry.get_quote_syntax().start_delimiter
@@ -0,0 +1,14 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class SpaceMarkdownNode(MarkdownNode):
8
+ def __init__(self, syntax_registry: SyntaxRegistry | None = None) -> None:
9
+ super().__init__(syntax_registry=syntax_registry)
10
+
11
+ @override
12
+ def to_markdown(self) -> str:
13
+ space_syntax = self._syntax_registry.get_space_syntax()
14
+ return space_syntax.start_delimiter
@@ -0,0 +1,45 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class TableMarkdownNode(MarkdownNode):
8
+ def __init__(
9
+ self, headers: list[str], rows: list[list[str]], syntax_registry: SyntaxRegistry | None = None
10
+ ) -> None:
11
+ super().__init__(syntax_registry=syntax_registry)
12
+ self._validate_input(headers, rows)
13
+ self.headers = headers
14
+ self.rows = rows
15
+
16
+ def _validate_input(self, headers: list[str], rows: list[list[str]]) -> None:
17
+ if not headers:
18
+ raise ValueError("headers must not be empty")
19
+ if not all(isinstance(row, list) for row in rows):
20
+ raise ValueError("rows must be a list of lists")
21
+
22
+ @override
23
+ def to_markdown(self) -> str:
24
+ header = self._build_header_row()
25
+ separator = self._build_separator_row()
26
+ data_rows = self._build_data_rows()
27
+ return "\n".join([header, separator, *data_rows])
28
+
29
+ def _build_header_row(self) -> str:
30
+ return self._format_row(self.headers)
31
+
32
+ def _format_row(self, cells: list[str]) -> str:
33
+ table_syntax = self._syntax_registry.get_table_syntax()
34
+ delimiter = table_syntax.start_delimiter
35
+ joined_cells = f" {delimiter} ".join(cells)
36
+ return f"{delimiter} {joined_cells} {delimiter}"
37
+
38
+ def _build_separator_row(self) -> str:
39
+ table_syntax = self._syntax_registry.get_table_syntax()
40
+ col_count = len(self.headers)
41
+ separators = [table_syntax.end_delimiter] * col_count
42
+ return self._format_row(separators)
43
+
44
+ def _build_data_rows(self) -> list[str]:
45
+ return [self._format_row(row) for row in self.rows]
@@ -0,0 +1,14 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.syntax import SyntaxRegistry
5
+
6
+
7
+ class TableOfContentsMarkdownNode(MarkdownNode):
8
+ def __init__(self, syntax_registry: SyntaxRegistry | None = None) -> None:
9
+ super().__init__(syntax_registry=syntax_registry)
10
+
11
+ @override
12
+ def to_markdown(self) -> str:
13
+ toc_syntax = self._syntax_registry.get_table_of_contents_syntax()
14
+ return toc_syntax.start_delimiter
@@ -0,0 +1,38 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.container import ContainerNode
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class TodoMarkdownNode(ContainerNode):
9
+ VALID_MARKER = "-"
10
+
11
+ def __init__(
12
+ self,
13
+ text: str,
14
+ checked: bool = False,
15
+ marker: str = "-",
16
+ children: list[MarkdownNode] | None = None,
17
+ syntax_registry: SyntaxRegistry | None = None,
18
+ ):
19
+ super().__init__(syntax_registry=syntax_registry)
20
+ self.text = text
21
+ self.checked = checked
22
+ self.marker = marker
23
+ self.children = children or []
24
+
25
+ @override
26
+ def to_markdown(self) -> str:
27
+ validated_marker = self._get_validated_marker()
28
+ checkbox_state = self._get_checkbox_state()
29
+ result = f"{validated_marker}{checkbox_state} {self.text}"
30
+ result += self.render_children()
31
+ return result
32
+
33
+ def _get_validated_marker(self) -> str:
34
+ return self.marker if self.marker == self.VALID_MARKER else self.VALID_MARKER
35
+
36
+ def _get_checkbox_state(self) -> str:
37
+ todo_syntax = self._syntax_registry.get_todo_syntax()
38
+ return todo_syntax.end_delimiter if self.checked else todo_syntax.start_delimiter
@@ -0,0 +1,27 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.container import ContainerNode
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class ToggleMarkdownNode(ContainerNode):
9
+ def __init__(
10
+ self,
11
+ title: str,
12
+ children: list[MarkdownNode] | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ):
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.title = title
17
+ self.children = children or []
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ toggle_delimiter = self._get_toggle_delimiter()
22
+ result = f"{toggle_delimiter} {self.title}"
23
+ result += self.render_children()
24
+ return result
25
+
26
+ def _get_toggle_delimiter(self) -> str:
27
+ return self._syntax_registry.get_toggle_syntax().start_delimiter
@@ -0,0 +1,23 @@
1
+ from typing import override
2
+
3
+ from notionary.page.content.markdown.nodes.base import MarkdownNode
4
+ from notionary.page.content.markdown.nodes.mixins.caption import CaptionMarkdownNodeMixin
5
+ from notionary.page.content.syntax import SyntaxRegistry
6
+
7
+
8
+ class VideoMarkdownNode(MarkdownNode, CaptionMarkdownNodeMixin):
9
+ def __init__(
10
+ self,
11
+ url: str,
12
+ caption: str | None = None,
13
+ syntax_registry: SyntaxRegistry | None = None,
14
+ ) -> None:
15
+ super().__init__(syntax_registry=syntax_registry)
16
+ self.url = url
17
+ self.caption = caption
18
+
19
+ @override
20
+ def to_markdown(self) -> str:
21
+ video_syntax = self._syntax_registry.get_video_syntax()
22
+ base_markdown = f"{video_syntax.start_delimiter}{self.url}{video_syntax.end_delimiter}"
23
+ return self._append_caption_to_markdown(base_markdown, self.caption)
@@ -0,0 +1,126 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Awaitable, Callable
4
+
5
+ from notionary.blocks.schemas import BlockCreatePayload
6
+ from notionary.page.content.syntax.grammar import MarkdownGrammar
7
+
8
+
9
+ class ParentBlockContext:
10
+ def __init__(
11
+ self,
12
+ block: BlockCreatePayload,
13
+ child_lines: list[str],
14
+ child_blocks: list[BlockCreatePayload] | None = None,
15
+ ) -> None:
16
+ self.block = block
17
+ self.child_lines = child_lines
18
+ self.child_blocks = child_blocks if child_blocks is not None else []
19
+
20
+ def add_child_line(self, content: str) -> None:
21
+ self.child_lines.append(content)
22
+
23
+ def add_child_block(self, block: BlockCreatePayload) -> None:
24
+ self.child_blocks.append(block)
25
+
26
+
27
+ _ParseChildrenCallback = Callable[[str], Awaitable[list[BlockCreatePayload]]]
28
+
29
+
30
+ class BlockParsingContext:
31
+ def __init__(
32
+ self,
33
+ line: str,
34
+ result_blocks: list[BlockCreatePayload],
35
+ parent_stack: list[ParentBlockContext],
36
+ parse_children_callback: _ParseChildrenCallback | None = None,
37
+ all_lines: list[str] | None = None,
38
+ current_line_index: int | None = None,
39
+ lines_consumed: int = 0,
40
+ is_previous_line_empty: bool = False,
41
+ markdown_grammar: MarkdownGrammar | None = None,
42
+ ) -> None:
43
+ self.line = line
44
+ self.result_blocks = result_blocks
45
+ self.parent_stack = parent_stack
46
+ self.parse_children_callback = parse_children_callback
47
+ self.all_lines = all_lines
48
+ self.current_line_index = current_line_index
49
+ self.lines_consumed = lines_consumed
50
+ self.is_previous_line_empty = is_previous_line_empty
51
+ markdown_grammar = markdown_grammar or MarkdownGrammar()
52
+ self._spaces_per_nesting_level = markdown_grammar.spaces_per_nesting_level
53
+
54
+ async def parse_nested_markdown(self, text: str) -> list[BlockCreatePayload]:
55
+ if not self._can_parse_children(text):
56
+ return []
57
+
58
+ return await self.parse_children_callback(text)
59
+
60
+ def _can_parse_children(self, text: str) -> bool:
61
+ return self.parse_children_callback is not None and bool(text)
62
+
63
+ def get_remaining_lines(self) -> list[str]:
64
+ if not self._has_remaining_lines():
65
+ return []
66
+ return self.all_lines[self.current_line_index + 1 :]
67
+
68
+ def _has_remaining_lines(self) -> bool:
69
+ return self.all_lines is not None and self.current_line_index is not None
70
+
71
+ def is_inside_parent_context(self) -> bool:
72
+ return len(self.parent_stack) > 0
73
+
74
+ def get_line_indentation_level(self, line: str | None = None) -> int:
75
+ target_line = self._get_target_line(line)
76
+ leading_spaces = self._count_leading_spaces(target_line)
77
+ return self._calculate_indentation_level(leading_spaces)
78
+
79
+ def _get_target_line(self, line: str | None) -> str:
80
+ return line if line is not None else self.line
81
+
82
+ def _count_leading_spaces(self, line: str) -> int:
83
+ return len(line) - len(line.lstrip())
84
+
85
+ def _calculate_indentation_level(self, leading_spaces: int) -> int:
86
+ return leading_spaces // self._spaces_per_nesting_level
87
+
88
+ def collect_indented_child_lines(self, parent_indent_level: int) -> list[str]:
89
+ child_lines = []
90
+ expected_child_indent = parent_indent_level + 1
91
+
92
+ for line in self.get_remaining_lines():
93
+ if self._should_include_line_as_child(line, expected_child_indent):
94
+ child_lines.append(line)
95
+ else:
96
+ break
97
+
98
+ return child_lines
99
+
100
+ def _should_include_line_as_child(self, line: str, expected_indent: int) -> bool:
101
+ if self._is_empty_line(line):
102
+ return True
103
+
104
+ line_indent = self.get_line_indentation_level(line)
105
+ return line_indent >= expected_indent
106
+
107
+ def _is_empty_line(self, line: str) -> bool:
108
+ return not line.strip()
109
+
110
+ def strip_indentation_level(self, lines: list[str], levels: int = 1) -> list[str]:
111
+ return [self._strip_line_indentation(line, levels) for line in lines]
112
+
113
+ def _strip_line_indentation(self, line: str, levels: int) -> str:
114
+ if self._is_empty_line(line):
115
+ return line
116
+
117
+ spaces_to_remove = self._calculate_spaces_to_remove(levels)
118
+ return self._remove_leading_spaces(line, spaces_to_remove)
119
+
120
+ def _calculate_spaces_to_remove(self, levels: int) -> int:
121
+ return self._spaces_per_nesting_level * levels
122
+
123
+ def _remove_leading_spaces(self, line: str, spaces: int) -> str:
124
+ if len(line) < spaces:
125
+ return line
126
+ return line[spaces:]