notionary 0.2.27__py3-none-any.whl → 0.2.28__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 (387) hide show
  1. notionary/__init__.py +5 -20
  2. notionary/blocks/client.py +87 -215
  3. notionary/blocks/enums.py +167 -0
  4. notionary/blocks/rich_text/markdown_rich_text_converter.py +266 -0
  5. notionary/blocks/rich_text/models.py +164 -0
  6. notionary/blocks/rich_text/name_id_resolver/__init__.py +11 -0
  7. notionary/blocks/rich_text/name_id_resolver/database.py +31 -0
  8. notionary/blocks/rich_text/name_id_resolver/page.py +34 -0
  9. notionary/blocks/rich_text/name_id_resolver/person.py +37 -0
  10. notionary/blocks/rich_text/name_id_resolver/port.py +11 -0
  11. notionary/blocks/rich_text/rich_text_markdown_converter.py +132 -0
  12. notionary/blocks/rich_text/rich_text_patterns.py +39 -0
  13. notionary/blocks/schemas.py +746 -0
  14. notionary/comments/client.py +52 -187
  15. notionary/comments/factory.py +40 -0
  16. notionary/comments/models.py +5 -127
  17. notionary/comments/schemas.py +240 -0
  18. notionary/comments/service.py +34 -0
  19. notionary/data_source/http/client.py +11 -0
  20. notionary/data_source/http/data_source_instance_client.py +94 -0
  21. notionary/data_source/properties/models.py +406 -0
  22. notionary/data_source/query/builder.py +429 -0
  23. notionary/data_source/query/resolver.py +114 -0
  24. notionary/data_source/query/schema.py +304 -0
  25. notionary/data_source/query/validator.py +73 -0
  26. notionary/data_source/schemas.py +27 -0
  27. notionary/data_source/service.py +353 -0
  28. notionary/database/client.py +30 -135
  29. notionary/database/database_metadata_update_client.py +19 -0
  30. notionary/database/schemas.py +29 -0
  31. notionary/database/service.py +169 -0
  32. notionary/exceptions/__init__.py +33 -0
  33. notionary/exceptions/api.py +41 -0
  34. notionary/exceptions/base.py +2 -0
  35. notionary/exceptions/block_parsing.py +16 -0
  36. notionary/exceptions/data_source/__init__.py +6 -0
  37. notionary/exceptions/data_source/builder.py +182 -0
  38. notionary/exceptions/data_source/properties.py +34 -0
  39. notionary/exceptions/properties.py +58 -0
  40. notionary/exceptions/search.py +33 -0
  41. notionary/file_upload/client.py +18 -30
  42. notionary/file_upload/models.py +7 -8
  43. notionary/file_upload/{notion_file_upload.py → service.py} +29 -64
  44. notionary/http/client.py +205 -0
  45. notionary/http/models.py +49 -0
  46. notionary/page/blocks/client.py +1 -0
  47. notionary/page/content/factory.py +68 -0
  48. notionary/page/content/markdown/__init__.py +5 -0
  49. notionary/page/content/markdown/builder.py +304 -0
  50. notionary/page/content/markdown/nodes/__init__.py +54 -0
  51. notionary/page/content/markdown/nodes/audio.py +23 -0
  52. notionary/page/content/markdown/nodes/base.py +12 -0
  53. notionary/page/content/markdown/nodes/bookmark.py +25 -0
  54. notionary/page/content/markdown/nodes/breadcrumb.py +14 -0
  55. notionary/page/content/markdown/nodes/bulleted_list.py +18 -0
  56. notionary/page/content/markdown/nodes/callout.py +32 -0
  57. notionary/page/content/markdown/nodes/code.py +30 -0
  58. notionary/page/content/markdown/nodes/columns.py +51 -0
  59. notionary/page/content/markdown/nodes/divider.py +14 -0
  60. notionary/page/content/markdown/nodes/embed.py +23 -0
  61. notionary/page/content/markdown/nodes/equation.py +19 -0
  62. notionary/page/content/markdown/nodes/file.py +23 -0
  63. notionary/page/content/markdown/nodes/heading.py +16 -0
  64. notionary/page/content/markdown/nodes/image.py +23 -0
  65. notionary/page/content/markdown/nodes/mixins/caption.py +12 -0
  66. notionary/page/content/markdown/nodes/numbered_list.py +15 -0
  67. notionary/page/content/markdown/nodes/paragraph.py +14 -0
  68. notionary/page/content/markdown/nodes/pdf.py +23 -0
  69. notionary/page/content/markdown/nodes/quote.py +15 -0
  70. notionary/page/content/markdown/nodes/space.py +14 -0
  71. notionary/page/content/markdown/nodes/table.py +45 -0
  72. notionary/page/content/markdown/nodes/table_of_contents.py +14 -0
  73. notionary/page/content/markdown/nodes/todo.py +22 -0
  74. notionary/page/content/markdown/nodes/toggle.py +28 -0
  75. notionary/page/content/markdown/nodes/toggleable_heading.py +35 -0
  76. notionary/page/content/markdown/nodes/video.py +23 -0
  77. notionary/page/content/parser/context.py +49 -0
  78. notionary/page/content/parser/factory.py +219 -0
  79. notionary/page/content/parser/parsers/__init__.py +60 -0
  80. notionary/page/content/parser/parsers/audio.py +40 -0
  81. notionary/page/content/parser/parsers/base.py +30 -0
  82. notionary/page/content/parser/parsers/bookmark.py +33 -0
  83. notionary/page/content/parser/parsers/breadcrumb.py +33 -0
  84. notionary/page/content/parser/parsers/bulleted_list.py +41 -0
  85. notionary/page/content/parser/parsers/callout.py +129 -0
  86. notionary/page/content/parser/parsers/caption.py +55 -0
  87. notionary/page/content/parser/parsers/code.py +81 -0
  88. notionary/page/content/parser/parsers/column.py +117 -0
  89. notionary/page/content/parser/parsers/column_list.py +81 -0
  90. notionary/page/content/parser/parsers/divider.py +33 -0
  91. notionary/page/content/parser/parsers/embed.py +33 -0
  92. notionary/page/content/parser/parsers/equation.py +65 -0
  93. notionary/page/content/parser/parsers/file.py +42 -0
  94. notionary/page/content/parser/parsers/heading.py +58 -0
  95. notionary/page/content/parser/parsers/image.py +42 -0
  96. notionary/page/content/parser/parsers/numbered_list.py +45 -0
  97. notionary/page/content/parser/parsers/paragraph.py +36 -0
  98. notionary/page/content/parser/parsers/pdf.py +42 -0
  99. notionary/page/content/parser/parsers/quote.py +65 -0
  100. notionary/page/content/parser/parsers/space.py +35 -0
  101. notionary/page/content/parser/parsers/table.py +144 -0
  102. notionary/page/content/parser/parsers/table_of_contents.py +32 -0
  103. notionary/page/content/parser/parsers/todo.py +58 -0
  104. notionary/page/content/parser/parsers/toggle.py +127 -0
  105. notionary/page/content/parser/parsers/toggleable_heading.py +150 -0
  106. notionary/page/content/parser/parsers/video.py +42 -0
  107. notionary/page/content/parser/post_processing/handlers/__init__.py +5 -0
  108. notionary/page/content/parser/post_processing/handlers/rich_text_length.py +93 -0
  109. notionary/page/content/parser/post_processing/handlers/rich_text_length_truncation.py +93 -0
  110. notionary/page/content/parser/post_processing/port.py +9 -0
  111. notionary/page/content/parser/post_processing/service.py +16 -0
  112. notionary/page/content/parser/pre_processsing/handlers/__init__.py +9 -0
  113. notionary/page/content/parser/pre_processsing/handlers/column_syntax.py +80 -0
  114. notionary/page/content/parser/pre_processsing/handlers/port.py +7 -0
  115. notionary/page/content/parser/pre_processsing/handlers/whitespace.py +68 -0
  116. notionary/page/content/parser/pre_processsing/service.py +15 -0
  117. notionary/page/content/parser/service.py +69 -0
  118. notionary/page/content/renderer/context.py +48 -0
  119. notionary/page/content/renderer/factory.py +240 -0
  120. notionary/page/content/renderer/post_processing/handlers/__init__.py +5 -0
  121. notionary/page/content/renderer/post_processing/handlers/numbered_list_placeholdere.py +62 -0
  122. notionary/page/content/renderer/post_processing/port.py +7 -0
  123. notionary/page/content/renderer/post_processing/service.py +15 -0
  124. notionary/page/content/renderer/renderers/__init__.py +57 -0
  125. notionary/page/content/renderer/renderers/audio.py +31 -0
  126. notionary/page/content/renderer/renderers/base.py +31 -0
  127. notionary/page/content/renderer/renderers/bookmark.py +25 -0
  128. notionary/page/content/renderer/renderers/breadcrumb.py +21 -0
  129. notionary/page/content/renderer/renderers/bulleted_list.py +48 -0
  130. notionary/page/content/renderer/renderers/callout.py +65 -0
  131. notionary/page/content/renderer/renderers/captioned_block.py +58 -0
  132. notionary/page/content/renderer/renderers/code.py +34 -0
  133. notionary/page/content/renderer/renderers/column.py +44 -0
  134. notionary/page/content/renderer/renderers/column_list.py +31 -0
  135. notionary/page/content/renderer/renderers/divider.py +22 -0
  136. notionary/page/content/renderer/renderers/embed.py +25 -0
  137. notionary/page/content/renderer/renderers/equation.py +37 -0
  138. notionary/page/content/renderer/renderers/fallback.py +24 -0
  139. notionary/page/content/renderer/renderers/file.py +40 -0
  140. notionary/page/content/renderer/renderers/heading.py +69 -0
  141. notionary/page/content/renderer/renderers/image.py +31 -0
  142. notionary/page/content/renderer/renderers/numbered_list.py +41 -0
  143. notionary/page/content/renderer/renderers/paragraph.py +40 -0
  144. notionary/page/content/renderer/renderers/pdf.py +31 -0
  145. notionary/page/content/renderer/renderers/quote.py +49 -0
  146. notionary/page/content/renderer/renderers/table.py +115 -0
  147. notionary/page/content/renderer/renderers/table_of_contents.py +26 -0
  148. notionary/page/content/renderer/renderers/table_row.py +17 -0
  149. notionary/page/content/renderer/renderers/todo.py +56 -0
  150. notionary/page/content/renderer/renderers/toggle.py +53 -0
  151. notionary/page/content/renderer/renderers/toggleable_heading.py +78 -0
  152. notionary/page/content/renderer/renderers/video.py +31 -0
  153. notionary/page/content/renderer/service.py +50 -0
  154. notionary/page/content/service.py +65 -0
  155. notionary/page/content/syntax/models.py +68 -0
  156. notionary/page/content/syntax/service.py +453 -0
  157. notionary/page/page_context.py +7 -16
  158. notionary/page/page_http_client.py +15 -0
  159. notionary/page/page_metadata_update_client.py +19 -0
  160. notionary/page/properties/client.py +144 -0
  161. notionary/page/properties/factory.py +26 -0
  162. notionary/page/properties/models.py +307 -0
  163. notionary/page/properties/service.py +257 -0
  164. notionary/page/schemas.py +13 -0
  165. notionary/page/service.py +222 -0
  166. notionary/shared/entity/client.py +29 -0
  167. notionary/shared/entity/dto_parsers.py +53 -0
  168. notionary/shared/entity/entity_metadata_update_client.py +41 -0
  169. notionary/shared/entity/schemas.py +45 -0
  170. notionary/shared/entity/service.py +171 -0
  171. notionary/shared/models/cover.py +20 -0
  172. notionary/shared/models/file.py +21 -0
  173. notionary/shared/models/icon.py +28 -0
  174. notionary/shared/models/parent.py +41 -0
  175. notionary/shared/properties/type.py +30 -0
  176. notionary/user/__init__.py +4 -8
  177. notionary/user/base.py +89 -0
  178. notionary/user/bot.py +70 -0
  179. notionary/user/client.py +22 -111
  180. notionary/user/person.py +41 -0
  181. notionary/user/schemas.py +67 -0
  182. notionary/user/service.py +65 -0
  183. notionary/utils/async_retry.py +39 -0
  184. notionary/utils/date.py +51 -0
  185. notionary/utils/fuzzy.py +56 -0
  186. notionary/{util/logging_mixin.py → utils/mixins/logging.py} +4 -16
  187. notionary/utils/pagination.py +50 -0
  188. notionary/utils/singleton.py +13 -0
  189. notionary/utils/uuid_utils.py +20 -0
  190. notionary/workspace/__init__.py +3 -0
  191. notionary/workspace/client.py +62 -0
  192. notionary/workspace/query/builder.py +60 -0
  193. notionary/workspace/query/models.py +60 -0
  194. notionary/workspace/query/service.py +93 -0
  195. notionary/workspace/schemas.py +21 -0
  196. notionary/workspace/service.py +116 -0
  197. {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info}/METADATA +54 -49
  198. notionary-0.2.28.dist-info/RECORD +200 -0
  199. {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info}/WHEEL +1 -1
  200. {notionary-0.2.27.dist-info → notionary-0.2.28.dist-info/licenses}/LICENSE +9 -9
  201. notionary/base_notion_client.py +0 -219
  202. notionary/blocks/__init__.py +0 -5
  203. notionary/blocks/_bootstrap.py +0 -271
  204. notionary/blocks/audio/__init__.py +0 -11
  205. notionary/blocks/audio/audio_element.py +0 -158
  206. notionary/blocks/audio/audio_markdown_node.py +0 -24
  207. notionary/blocks/audio/audio_models.py +0 -10
  208. notionary/blocks/base_block_element.py +0 -42
  209. notionary/blocks/bookmark/__init__.py +0 -12
  210. notionary/blocks/bookmark/bookmark_element.py +0 -83
  211. notionary/blocks/bookmark/bookmark_markdown_node.py +0 -28
  212. notionary/blocks/bookmark/bookmark_models.py +0 -15
  213. notionary/blocks/breadcrumbs/__init__.py +0 -15
  214. notionary/blocks/breadcrumbs/breadcrumb_element.py +0 -39
  215. notionary/blocks/breadcrumbs/breadcrumb_markdown_node.py +0 -13
  216. notionary/blocks/breadcrumbs/breadcrumb_models.py +0 -12
  217. notionary/blocks/bulleted_list/__init__.py +0 -15
  218. notionary/blocks/bulleted_list/bulleted_list_element.py +0 -74
  219. notionary/blocks/bulleted_list/bulleted_list_markdown_node.py +0 -20
  220. notionary/blocks/bulleted_list/bulleted_list_models.py +0 -17
  221. notionary/blocks/callout/__init__.py +0 -12
  222. notionary/blocks/callout/callout_element.py +0 -99
  223. notionary/blocks/callout/callout_markdown_node.py +0 -19
  224. notionary/blocks/callout/callout_models.py +0 -33
  225. notionary/blocks/child_database/__init__.py +0 -14
  226. notionary/blocks/child_database/child_database_element.py +0 -59
  227. notionary/blocks/child_database/child_database_models.py +0 -12
  228. notionary/blocks/child_page/__init__.py +0 -9
  229. notionary/blocks/child_page/child_page_element.py +0 -94
  230. notionary/blocks/child_page/child_page_models.py +0 -12
  231. notionary/blocks/code/__init__.py +0 -11
  232. notionary/blocks/code/code_element.py +0 -149
  233. notionary/blocks/code/code_markdown_node.py +0 -80
  234. notionary/blocks/code/code_models.py +0 -94
  235. notionary/blocks/column/__init__.py +0 -25
  236. notionary/blocks/column/column_element.py +0 -65
  237. notionary/blocks/column/column_list_element.py +0 -52
  238. notionary/blocks/column/column_list_markdown_node.py +0 -34
  239. notionary/blocks/column/column_markdown_node.py +0 -42
  240. notionary/blocks/column/column_models.py +0 -26
  241. notionary/blocks/divider/__init__.py +0 -12
  242. notionary/blocks/divider/divider_element.py +0 -41
  243. notionary/blocks/divider/divider_markdown_node.py +0 -11
  244. notionary/blocks/divider/divider_models.py +0 -12
  245. notionary/blocks/embed/__init__.py +0 -12
  246. notionary/blocks/embed/embed_element.py +0 -98
  247. notionary/blocks/embed/embed_markdown_node.py +0 -19
  248. notionary/blocks/embed/embed_models.py +0 -14
  249. notionary/blocks/equation/__init__.py +0 -13
  250. notionary/blocks/equation/equation_element.py +0 -133
  251. notionary/blocks/equation/equation_element_markdown_node.py +0 -23
  252. notionary/blocks/equation/equation_models.py +0 -11
  253. notionary/blocks/file/__init__.py +0 -23
  254. notionary/blocks/file/file_element.py +0 -133
  255. notionary/blocks/file/file_element_markdown_node.py +0 -24
  256. notionary/blocks/file/file_element_models.py +0 -39
  257. notionary/blocks/heading/__init__.py +0 -19
  258. notionary/blocks/heading/heading_element.py +0 -112
  259. notionary/blocks/heading/heading_markdown_node.py +0 -16
  260. notionary/blocks/heading/heading_models.py +0 -29
  261. notionary/blocks/image_block/__init__.py +0 -11
  262. notionary/blocks/image_block/image_element.py +0 -130
  263. notionary/blocks/image_block/image_markdown_node.py +0 -25
  264. notionary/blocks/image_block/image_models.py +0 -10
  265. notionary/blocks/markdown/markdown_builder.py +0 -525
  266. notionary/blocks/markdown/markdown_document_model.py +0 -0
  267. notionary/blocks/markdown/markdown_node.py +0 -25
  268. notionary/blocks/mixins/captions/__init__.py +0 -4
  269. notionary/blocks/mixins/captions/caption_markdown_node_mixin.py +0 -31
  270. notionary/blocks/mixins/captions/caption_mixin.py +0 -92
  271. notionary/blocks/mixins/file_upload/__init__.py +0 -3
  272. notionary/blocks/mixins/file_upload/file_upload_mixin.py +0 -320
  273. notionary/blocks/models.py +0 -174
  274. notionary/blocks/numbered_list/__init__.py +0 -16
  275. notionary/blocks/numbered_list/numbered_list_element.py +0 -65
  276. notionary/blocks/numbered_list/numbered_list_markdown_node.py +0 -17
  277. notionary/blocks/numbered_list/numbered_list_models.py +0 -17
  278. notionary/blocks/paragraph/__init__.py +0 -15
  279. notionary/blocks/paragraph/paragraph_element.py +0 -58
  280. notionary/blocks/paragraph/paragraph_markdown_node.py +0 -16
  281. notionary/blocks/paragraph/paragraph_models.py +0 -16
  282. notionary/blocks/pdf/__init__.py +0 -11
  283. notionary/blocks/pdf/pdf_element.py +0 -146
  284. notionary/blocks/pdf/pdf_markdown_node.py +0 -24
  285. notionary/blocks/pdf/pdf_models.py +0 -11
  286. notionary/blocks/quote/__init__.py +0 -14
  287. notionary/blocks/quote/quote_element.py +0 -75
  288. notionary/blocks/quote/quote_markdown_node.py +0 -16
  289. notionary/blocks/quote/quote_models.py +0 -18
  290. notionary/blocks/registry/__init__.py +0 -3
  291. notionary/blocks/registry/block_registry.py +0 -150
  292. notionary/blocks/rich_text/__init__.py +0 -33
  293. notionary/blocks/rich_text/rich_text_models.py +0 -221
  294. notionary/blocks/rich_text/text_inline_formatter.py +0 -456
  295. notionary/blocks/syntax_prompt_builder.py +0 -137
  296. notionary/blocks/table/__init__.py +0 -19
  297. notionary/blocks/table/table_element.py +0 -225
  298. notionary/blocks/table/table_markdown_node.py +0 -42
  299. notionary/blocks/table/table_models.py +0 -28
  300. notionary/blocks/table_of_contents/__init__.py +0 -17
  301. notionary/blocks/table_of_contents/table_of_contents_element.py +0 -80
  302. notionary/blocks/table_of_contents/table_of_contents_markdown_node.py +0 -21
  303. notionary/blocks/table_of_contents/table_of_contents_models.py +0 -18
  304. notionary/blocks/todo/__init__.py +0 -12
  305. notionary/blocks/todo/todo_element.py +0 -81
  306. notionary/blocks/todo/todo_markdown_node.py +0 -21
  307. notionary/blocks/todo/todo_models.py +0 -18
  308. notionary/blocks/toggle/__init__.py +0 -12
  309. notionary/blocks/toggle/toggle_element.py +0 -112
  310. notionary/blocks/toggle/toggle_markdown_node.py +0 -31
  311. notionary/blocks/toggle/toggle_models.py +0 -17
  312. notionary/blocks/toggleable_heading/__init__.py +0 -11
  313. notionary/blocks/toggleable_heading/toggleable_heading_element.py +0 -115
  314. notionary/blocks/toggleable_heading/toggleable_heading_markdown_node.py +0 -34
  315. notionary/blocks/types.py +0 -130
  316. notionary/blocks/video/__init__.py +0 -11
  317. notionary/blocks/video/video_element.py +0 -187
  318. notionary/blocks/video/video_element_models.py +0 -10
  319. notionary/blocks/video/video_markdown_node.py +0 -26
  320. notionary/comments/__init__.py +0 -26
  321. notionary/database/__init__.py +0 -4
  322. notionary/database/database.py +0 -480
  323. notionary/database/database_filter_builder.py +0 -173
  324. notionary/database/database_provider.py +0 -227
  325. notionary/database/exceptions.py +0 -13
  326. notionary/database/factory.py +0 -0
  327. notionary/database/models.py +0 -337
  328. notionary/database/notion_database.py +0 -487
  329. notionary/file_upload/__init__.py +0 -7
  330. notionary/page/client.py +0 -124
  331. notionary/page/markdown_whitespace_processor.py +0 -129
  332. notionary/page/models.py +0 -322
  333. notionary/page/notion_page.py +0 -712
  334. notionary/page/page_content_deleting_service.py +0 -117
  335. notionary/page/page_content_writer.py +0 -80
  336. notionary/page/property_formatter.py +0 -99
  337. notionary/page/reader/handler/__init__.py +0 -19
  338. notionary/page/reader/handler/base_block_renderer.py +0 -44
  339. notionary/page/reader/handler/block_processing_context.py +0 -35
  340. notionary/page/reader/handler/block_rendering_context.py +0 -48
  341. notionary/page/reader/handler/column_list_renderer.py +0 -51
  342. notionary/page/reader/handler/column_renderer.py +0 -60
  343. notionary/page/reader/handler/equation_renderer.py +0 -0
  344. notionary/page/reader/handler/line_renderer.py +0 -73
  345. notionary/page/reader/handler/numbered_list_renderer.py +0 -85
  346. notionary/page/reader/handler/toggle_renderer.py +0 -69
  347. notionary/page/reader/handler/toggleable_heading_renderer.py +0 -89
  348. notionary/page/reader/page_content_retriever.py +0 -81
  349. notionary/page/search_filter_builder.py +0 -132
  350. notionary/page/utils.py +0 -60
  351. notionary/page/writer/handler/__init__.py +0 -24
  352. notionary/page/writer/handler/code_handler.py +0 -72
  353. notionary/page/writer/handler/column_handler.py +0 -141
  354. notionary/page/writer/handler/column_list_handler.py +0 -139
  355. notionary/page/writer/handler/equation_handler.py +0 -74
  356. notionary/page/writer/handler/line_handler.py +0 -35
  357. notionary/page/writer/handler/line_processing_context.py +0 -54
  358. notionary/page/writer/handler/regular_line_handler.py +0 -86
  359. notionary/page/writer/handler/table_handler.py +0 -66
  360. notionary/page/writer/handler/toggle_handler.py +0 -159
  361. notionary/page/writer/handler/toggleable_heading_handler.py +0 -174
  362. notionary/page/writer/markdown_to_notion_converter.py +0 -139
  363. notionary/page/writer/markdown_to_notion_converter_context.py +0 -30
  364. notionary/page/writer/markdown_to_notion_text_length_post_processor.py +0 -0
  365. notionary/page/writer/notion_text_length_processor.py +0 -150
  366. notionary/schemas/__init__.py +0 -3
  367. notionary/schemas/base.py +0 -73
  368. notionary/shared/__init__.py +0 -3
  369. notionary/shared/name_to_id_resolver.py +0 -203
  370. notionary/telemetry/__init__.py +0 -19
  371. notionary/telemetry/service.py +0 -136
  372. notionary/telemetry/views.py +0 -73
  373. notionary/user/base_notion_user.py +0 -53
  374. notionary/user/models.py +0 -84
  375. notionary/user/notion_bot_user.py +0 -226
  376. notionary/user/notion_user.py +0 -255
  377. notionary/user/notion_user_manager.py +0 -101
  378. notionary/util/__init__.py +0 -15
  379. notionary/util/concurrency_limiter.py +0 -0
  380. notionary/util/factory_decorator.py +0 -0
  381. notionary/util/factory_only.py +0 -37
  382. notionary/util/fuzzy.py +0 -75
  383. notionary/util/page_id_utils.py +0 -27
  384. notionary/util/singleton.py +0 -18
  385. notionary/util/singleton_metaclass.py +0 -22
  386. notionary/workspace.py +0 -105
  387. notionary-0.2.27.dist-info/RECORD +0 -202
@@ -1,141 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
-
5
- from notionary.blocks.column.column_element import ColumnElement
6
- from notionary.page.writer.handler.line_handler import (
7
- LineHandler,
8
- LineProcessingContext,
9
- )
10
- from notionary.page.writer.handler.line_processing_context import ParentBlockContext
11
-
12
-
13
- class ColumnHandler(LineHandler):
14
- """Handles single column elements - both start and end.
15
- Syntax:
16
- ::: column # Start individual column (can have optional parameters)
17
- Content here
18
- ::: # End column
19
- """
20
-
21
- def __init__(self):
22
- super().__init__()
23
- self._start_pattern = re.compile(r"^:::\s*column(\s+.*?)?\s*$", re.IGNORECASE)
24
- self._end_pattern = re.compile(r"^:::\s*$")
25
-
26
- def _can_handle(self, context: LineProcessingContext) -> bool:
27
- return self._is_column_start(context) or self._is_column_end(context)
28
-
29
- async def _process(self, context: LineProcessingContext) -> None:
30
- if self._is_column_start(context):
31
- await self._start_column(context)
32
- self._mark_processed(context)
33
- return
34
-
35
- if self._is_column_end(context):
36
- await self._finalize_column(context)
37
- self._mark_processed(context)
38
-
39
- def _is_column_start(self, context: LineProcessingContext) -> bool:
40
- """Check if line starts a column (::: column)."""
41
- return self._start_pattern.match(context.line.strip()) is not None
42
-
43
- def _is_column_end(self, context: LineProcessingContext) -> bool:
44
- """Check if we need to end a single column (:::)."""
45
- if not self._end_pattern.match(context.line.strip()):
46
- return False
47
-
48
- if not context.parent_stack:
49
- return False
50
-
51
- # Check if top of stack is a Column (not ColumnList)
52
- current_parent = context.parent_stack[-1]
53
- return issubclass(current_parent.element_type, ColumnElement)
54
-
55
- async def _start_column(self, context: LineProcessingContext) -> None:
56
- """Start a new column."""
57
- # Create Column block directly - much more efficient!
58
- column_element = ColumnElement()
59
- result = await column_element.markdown_to_notion(context.line)
60
- if not result:
61
- return
62
-
63
- block = result
64
-
65
- # Push to parent stack
66
- parent_context = ParentBlockContext(
67
- block=block,
68
- element_type=ColumnElement,
69
- child_lines=[],
70
- )
71
- context.parent_stack.append(parent_context)
72
-
73
- async def _finalize_column(self, context: LineProcessingContext) -> None:
74
- """Finalize a single column and add it to the column list or result."""
75
- column_context = context.parent_stack.pop()
76
- await self._assign_column_children_if_any(column_context, context)
77
-
78
- if context.parent_stack:
79
- parent = context.parent_stack[-1]
80
- from notionary.blocks.column.column_list_element import ColumnListElement
81
-
82
- if issubclass(parent.element_type, ColumnListElement):
83
- # Add to parent using the new system
84
- parent.add_child_block(column_context.block)
85
- return
86
-
87
- # Fallback: no parent or parent is not ColumnList
88
- context.result_blocks.append(column_context.block)
89
-
90
- async def _assign_column_children_if_any(
91
- self, column_context: ParentBlockContext, context: LineProcessingContext
92
- ) -> None:
93
- """Collect and assign any children blocks inside this column."""
94
- all_children = []
95
-
96
- # Process text lines
97
- if column_context.child_lines:
98
- children_text = "\n".join(column_context.child_lines)
99
- text_blocks = await self._convert_children_text(
100
- children_text, context.block_registry
101
- )
102
- all_children.extend(text_blocks)
103
-
104
- # Add direct child blocks (like processed toggles)
105
- if column_context.child_blocks:
106
- all_children.extend(column_context.child_blocks)
107
-
108
- column_context.block.column.children = all_children
109
-
110
- def _try_add_to_parent_column_list(
111
- self, column_context: ParentBlockContext, context: LineProcessingContext
112
- ) -> bool:
113
- """If the previous stack element is a ColumnList, append column and return True."""
114
- if not context.parent_stack:
115
- return False
116
-
117
- parent = context.parent_stack[-1]
118
- from notionary.blocks.column.column_list_element import ColumnListElement
119
-
120
- if not issubclass(parent.element_type, ColumnListElement):
121
- return False
122
-
123
- parent.block.column_list.children.append(column_context.block)
124
- return True
125
-
126
- async def _convert_children_text(self, text: str, block_registry) -> list:
127
- """Convert children text to blocks."""
128
- from notionary.page.writer.markdown_to_notion_converter import (
129
- MarkdownToNotionConverter,
130
- )
131
-
132
- if not text.strip():
133
- return []
134
-
135
- child_converter = MarkdownToNotionConverter(block_registry)
136
- return await child_converter.process_lines(text)
137
-
138
- def _mark_processed(self, context: LineProcessingContext) -> None:
139
- """Mark context as processed and signal to continue."""
140
- context.was_processed = True
141
- context.should_continue = True
@@ -1,139 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import re
4
-
5
- from notionary.blocks.column.column_list_element import ColumnListElement
6
- from notionary.page.writer.handler.line_handler import (
7
- LineHandler,
8
- LineProcessingContext,
9
- )
10
- from notionary.page.writer.handler.line_processing_context import ParentBlockContext
11
-
12
-
13
- class ColumnListHandler(LineHandler):
14
- """Handles column list elements - both start and end.
15
- Syntax:
16
- ::: columns # Start column list
17
- ::: column # Individual column
18
- Content here
19
- ::: # End column
20
- ::: column # Another column
21
- More content
22
- ::: # End column
23
- ::: # End column list
24
- """
25
-
26
- def __init__(self):
27
- super().__init__()
28
- self._start_pattern = re.compile(r"^:::\s*columns?\s*$", re.IGNORECASE)
29
- self._end_pattern = re.compile(r"^:::\s*$")
30
-
31
- def _can_handle(self, context: LineProcessingContext) -> bool:
32
- return self._is_column_list_start(context) or self._is_column_list_end(context)
33
-
34
- async def _process(self, context: LineProcessingContext) -> None:
35
- if self._is_column_list_start(context):
36
- await self._start_column_list(context)
37
- context.was_processed = True
38
- context.should_continue = True
39
- return
40
-
41
- if self._is_column_list_end(context):
42
- await self._finalize_column_list(context)
43
- context.was_processed = True
44
- context.should_continue = True
45
-
46
- def _is_column_list_start(self, context: LineProcessingContext) -> bool:
47
- """Check if line starts a column list (::: columns)."""
48
- return self._start_pattern.match(context.line.strip()) is not None
49
-
50
- def _is_column_list_end(self, context: LineProcessingContext) -> bool:
51
- """Check if we need to end a column list (:::)."""
52
- if not self._end_pattern.match(context.line.strip()):
53
- return False
54
-
55
- if not context.parent_stack:
56
- return False
57
-
58
- # Check if top of stack is a ColumnList
59
- current_parent = context.parent_stack[-1]
60
- return issubclass(current_parent.element_type, ColumnListElement)
61
-
62
- async def _start_column_list(self, context: LineProcessingContext) -> None:
63
- """Start a new column list."""
64
- # Create ColumnList block using the element from registry
65
- column_list_element = None
66
- for element in context.block_registry.get_elements():
67
- if issubclass(element, ColumnListElement):
68
- column_list_element = element
69
- break
70
-
71
- if not column_list_element:
72
- return
73
-
74
- # Create the block
75
- result = await column_list_element.markdown_to_notion(context.line)
76
- if not result:
77
- return
78
-
79
- block = result
80
-
81
- # Push to parent stack
82
- parent_context = ParentBlockContext(
83
- block=block,
84
- element_type=column_list_element,
85
- child_lines=[],
86
- )
87
- context.parent_stack.append(parent_context)
88
-
89
- async def _finalize_column_list(self, context: LineProcessingContext) -> None:
90
- """Finalize a column list and add it to result_blocks."""
91
- column_list_context = context.parent_stack.pop()
92
- await self._assign_column_list_children_if_any(column_list_context, context)
93
-
94
- # Check if we have a parent context to add this column_list to
95
- if context.parent_stack:
96
- # Add this column_list as a child block to the parent (like Toggle)
97
- parent_context = context.parent_stack[-1]
98
- parent_context.add_child_block(column_list_context.block)
99
-
100
- else:
101
- # No parent, add to top level
102
- context.result_blocks.append(column_list_context.block)
103
-
104
- async def _assign_column_list_children_if_any(
105
- self, column_list_context: ParentBlockContext, context: LineProcessingContext
106
- ) -> None:
107
- """Collect and assign any column children blocks inside this column list."""
108
- all_children = []
109
-
110
- # Process text lines
111
- if column_list_context.child_lines:
112
- children_text = "\n".join(column_list_context.child_lines)
113
- children_blocks = await self._convert_children_text(
114
- children_text, context.block_registry
115
- )
116
- all_children.extend(children_blocks)
117
-
118
- if column_list_context.child_blocks:
119
- all_children.extend(column_list_context.child_blocks)
120
-
121
- # Filter only column blocks
122
- column_children = [
123
- block
124
- for block in all_children
125
- if hasattr(block, "column") and getattr(block, "type", None) == "column"
126
- ]
127
- column_list_context.block.column_list.children = column_children
128
-
129
- async def _convert_children_text(self, text: str, block_registry) -> list:
130
- """Convert children text to blocks."""
131
- from notionary.page.writer.markdown_to_notion_converter import (
132
- MarkdownToNotionConverter,
133
- )
134
-
135
- if not text.strip():
136
- return []
137
-
138
- child_converter = MarkdownToNotionConverter(block_registry)
139
- return await child_converter.process_lines(text)
@@ -1,74 +0,0 @@
1
- import re
2
-
3
- from notionary.blocks.equation.equation_element import EquationElement
4
- from notionary.page.writer.handler.line_handler import (
5
- LineHandler,
6
- LineProcessingContext,
7
- )
8
-
9
-
10
- class EquationHandler(LineHandler):
11
- r"""Handles equation block specific logic with batching.
12
-
13
- Markdown syntax:
14
- $$
15
- \sum_{i=1}^n i = \frac{n(n+1)}{2} \\
16
- \sum_{i=1}^n i^2 = \frac{n(n+1)(2n+1)}{6} \\
17
- \sum_{i=1}^n i^3 = \left(\frac{n(n+1)}{2}\right)^2
18
- $$
19
- """
20
-
21
- def __init__(self):
22
- super().__init__()
23
- self._equation_start_pattern = re.compile(r"^\$\$\s*$")
24
- self._equation_end_pattern = re.compile(r"^\$\$\s*$")
25
-
26
- def _can_handle(self, context: LineProcessingContext) -> bool:
27
- if self._is_inside_parent_context(context):
28
- return False
29
- return self._is_equation_start(context)
30
-
31
- async def _process(self, context: LineProcessingContext) -> None:
32
- if self._is_equation_start(context):
33
- await self._process_complete_equation_block(context)
34
- self._mark_processed(context)
35
-
36
- def _is_equation_start(self, context: LineProcessingContext) -> bool:
37
- """Check if this line starts an equation block."""
38
- return self._equation_start_pattern.match(context.line.strip()) is not None
39
-
40
- def _is_inside_parent_context(self, context: LineProcessingContext) -> bool:
41
- """Check if we're currently inside any parent context (toggle, heading, etc.)."""
42
- return len(context.parent_stack) > 0
43
-
44
- async def _process_complete_equation_block(
45
- self, context: LineProcessingContext
46
- ) -> None:
47
- """Process the entire equation block in one go using EquationElement."""
48
- equation_lines, lines_to_consume = self._collect_equation_lines(context)
49
-
50
- block = EquationElement.create_from_markdown_block(
51
- opening_line=context.line, equation_lines=equation_lines
52
- )
53
-
54
- if block:
55
- context.lines_consumed = lines_to_consume
56
- context.result_blocks.append(block)
57
-
58
- def _collect_equation_lines(
59
- self, context: LineProcessingContext
60
- ) -> tuple[list[str], int]:
61
- """Collect lines until closing $$ fence and return (lines, count_to_consume)."""
62
- lines = []
63
- for idx, ln in enumerate(context.get_remaining_lines()):
64
- if self._equation_end_pattern.match(ln.strip()):
65
- return lines, idx + 1
66
- lines.append(ln)
67
- # No closing fence: consume all remaining
68
- rem = context.get_remaining_lines()
69
- return rem, len(rem)
70
-
71
- def _mark_processed(self, context: LineProcessingContext) -> None:
72
- """Mark context as processed and continue."""
73
- context.was_processed = True
74
- context.should_continue = True
@@ -1,35 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from abc import ABC, abstractmethod
4
- from typing import Optional
5
-
6
- from notionary.page.writer.handler.line_processing_context import LineProcessingContext
7
-
8
-
9
- class LineHandler(ABC):
10
- """Abstract base class for line handlers."""
11
-
12
- def __init__(self):
13
- self._next_handler: Optional[LineHandler] = None
14
-
15
- def set_next(self, handler: LineHandler) -> LineHandler:
16
- """Set the next handler in the chain."""
17
- self._next_handler = handler
18
- return handler
19
-
20
- async def handle(self, context: LineProcessingContext) -> None:
21
- """Handle the line or pass to next handler."""
22
- if self._can_handle(context):
23
- await self._process(context)
24
- elif self._next_handler:
25
- await self._next_handler.handle(context)
26
-
27
- @abstractmethod
28
- def _can_handle(self, context: LineProcessingContext) -> bool:
29
- """Check if this handler can process the current line."""
30
- pass
31
-
32
- @abstractmethod
33
- async def _process(self, context: LineProcessingContext) -> None:
34
- """Process the line and update context."""
35
- pass
@@ -1,54 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass, field
4
- from typing import Optional
5
-
6
- from notionary.blocks.base_block_element import BaseBlockElement
7
- from notionary.blocks.models import BlockCreateRequest
8
- from notionary.blocks.registry.block_registry import BlockRegistry
9
-
10
-
11
- @dataclass
12
- class ParentBlockContext:
13
- """Context for a block that expects children."""
14
-
15
- block: BlockCreateRequest
16
- element_type: BaseBlockElement
17
- child_lines: list[str]
18
- child_blocks: list[BlockCreateRequest] = field(default_factory=list)
19
-
20
- def add_child_line(self, content: str):
21
- """Adds a child line."""
22
- self.child_lines.append(content)
23
-
24
- def add_child_block(self, block: BlockCreateRequest):
25
- """Adds a processed child block."""
26
- self.child_blocks.append(block)
27
-
28
- def has_children(self) -> bool:
29
- """Checks if children have been collected."""
30
- return len(self.child_lines) > 0 or len(self.child_blocks) > 0
31
-
32
-
33
- @dataclass
34
- class LineProcessingContext:
35
- """Context that gets passed through the handler chain."""
36
-
37
- line: str
38
- result_blocks: list[BlockCreateRequest]
39
- parent_stack: list[ParentBlockContext]
40
- block_registry: BlockRegistry
41
-
42
- all_lines: Optional[list[str]] = None
43
- current_line_index: Optional[int] = None
44
- lines_consumed: int = 0
45
-
46
- # Result indicators
47
- was_processed: bool = False
48
- should_continue: bool = False
49
-
50
- def get_remaining_lines(self) -> list[str]:
51
- """Get all remaining lines from current position."""
52
- if self.all_lines is None or self.current_line_index is None:
53
- return []
54
- return self.all_lines[self.current_line_index + 1 :]
@@ -1,86 +0,0 @@
1
- from notionary.blocks.column.column_element import ColumnElement
2
- from notionary.blocks.column.column_list_element import ColumnListElement
3
- from notionary.page.writer.handler import LineHandler, LineProcessingContext
4
-
5
-
6
- class RegularLineHandler(LineHandler):
7
- """Handles regular lines - respects parent contexts like columns."""
8
-
9
- def _can_handle(self, context: LineProcessingContext) -> bool:
10
- return context.line.strip()
11
-
12
- async def _process(self, context: LineProcessingContext) -> None:
13
- if self._is_in_column_context(context):
14
- self._add_to_column_context(context)
15
- context.was_processed = True
16
- context.should_continue = True
17
- return
18
-
19
- block_created = await self._process_single_line_content(context)
20
- if not block_created:
21
- await self._process_as_paragraph(context)
22
-
23
- context.was_processed = True
24
-
25
- def _is_in_column_context(self, context: LineProcessingContext) -> bool:
26
- """Check if we're inside a Column/ColumnList context."""
27
- if not context.parent_stack:
28
- return False
29
-
30
- current_parent = context.parent_stack[-1]
31
- return issubclass(
32
- current_parent.element_type, (ColumnListElement, ColumnElement)
33
- )
34
-
35
- def _add_to_column_context(self, context: LineProcessingContext) -> None:
36
- """Add line as child to the current Column context."""
37
- context.parent_stack[-1].add_child_line(context.line)
38
-
39
- async def _process_single_line_content(
40
- self, context: LineProcessingContext
41
- ) -> bool:
42
- """Process a regular line for simple elements (lists, etc.)."""
43
- specialized_elements = self._get_specialized_elements()
44
-
45
- for element in context.block_registry.get_elements():
46
-
47
- if issubclass(element, specialized_elements):
48
- continue
49
-
50
- result = await element.markdown_to_notion(context.line)
51
- if not result:
52
- continue
53
-
54
- context.result_blocks.append(result)
55
-
56
- return True
57
-
58
- return False
59
-
60
- async def _process_as_paragraph(self, context: LineProcessingContext) -> None:
61
- """Process a line as a paragraph."""
62
- from notionary.blocks.paragraph.paragraph_element import ParagraphElement
63
-
64
- paragraph_element = ParagraphElement()
65
- result = await paragraph_element.markdown_to_notion(context.line)
66
-
67
- if result:
68
- context.result_blocks.append(result)
69
-
70
- def _get_specialized_elements(self):
71
- """Get tuple of elements that have specialized handlers."""
72
- from notionary.blocks.code import CodeElement
73
- from notionary.blocks.paragraph import ParagraphElement
74
- from notionary.blocks.table import TableElement
75
- from notionary.blocks.toggle import ToggleElement
76
- from notionary.blocks.toggleable_heading import ToggleableHeadingElement
77
-
78
- return (
79
- ColumnListElement,
80
- ColumnElement,
81
- ToggleElement,
82
- ToggleableHeadingElement,
83
- TableElement,
84
- CodeElement,
85
- ParagraphElement,
86
- )
@@ -1,66 +0,0 @@
1
- import re
2
-
3
- from notionary.blocks.table.table_element import TableElement
4
- from notionary.page.writer.handler import LineHandler, LineProcessingContext
5
-
6
-
7
- class TableHandler(LineHandler):
8
- """Handles table specific logic with batching."""
9
-
10
- def __init__(self):
11
- super().__init__()
12
- self._table_row_pattern = re.compile(r"^\s*\|(.+)\|\s*$")
13
- self._separator_pattern = re.compile(r"^\s*\|([\s\-:|]+)\|\s*$")
14
-
15
- def _can_handle(self, context: LineProcessingContext) -> bool:
16
- if self._is_inside_parent_context(context):
17
- return False
18
- return self._is_table_start(context)
19
-
20
- async def _process(self, context: LineProcessingContext) -> None:
21
- if not self._is_table_start(context):
22
- return
23
-
24
- await self._process_complete_table(context)
25
- context.was_processed = True
26
- context.should_continue = True
27
-
28
- def _is_inside_parent_context(self, context: LineProcessingContext) -> bool:
29
- """Check if we're currently inside any parent context (toggle, heading, etc.)."""
30
- return len(context.parent_stack) > 0
31
-
32
- def _is_table_start(self, context: LineProcessingContext) -> bool:
33
- """Check if this line starts a table."""
34
- return self._table_row_pattern.match(context.line.strip()) is not None
35
-
36
- async def _process_complete_table(self, context: LineProcessingContext) -> None:
37
- """Process the entire table in one go using TableElement."""
38
- # Collect all table lines (including the current one)
39
- table_lines = [context.line]
40
- remaining_lines = context.get_remaining_lines()
41
- lines_to_consume = 0
42
-
43
- # Find all consecutive table rows
44
- for i, line in enumerate(remaining_lines):
45
- line_stripped = line.strip()
46
- if not line_stripped:
47
- # Empty line - continue to allow for spacing in tables
48
- table_lines.append(line)
49
- continue
50
-
51
- if self._table_row_pattern.match(
52
- line_stripped
53
- ) or self._separator_pattern.match(line_stripped):
54
- table_lines.append(line)
55
- else:
56
- # Not a table line - stop here
57
- lines_to_consume = i
58
- break
59
- else:
60
- lines_to_consume = len(remaining_lines)
61
-
62
- block = await TableElement.create_from_markdown_table(table_lines)
63
-
64
- if block:
65
- context.lines_consumed = lines_to_consume
66
- context.result_blocks.append(block)