dmart 1.4.40.post8__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 (489) hide show
  1. dmart/__init__.py +7 -0
  2. dmart/alembic/README +1 -0
  3. dmart/alembic/__init__.py +0 -0
  4. dmart/alembic/env.py +91 -0
  5. dmart/alembic/notes.txt +11 -0
  6. dmart/alembic/script.py.mako +28 -0
  7. dmart/alembic/scripts/__init__.py +0 -0
  8. dmart/alembic/scripts/calculate_checksums.py +77 -0
  9. dmart/alembic/scripts/migration_f7a4949eed19.py +28 -0
  10. dmart/alembic/versions/0f3d2b1a7c21_add_authz_materialized_views.py +87 -0
  11. dmart/alembic/versions/10d2041b94d4_last_checksum_history.py +62 -0
  12. dmart/alembic/versions/1cf4e1ee3cb8_ext_permission_with_filter_fields_values.py +33 -0
  13. dmart/alembic/versions/26bfe19b49d4_rm_failedloginattempts.py +42 -0
  14. dmart/alembic/versions/3c8bca2219cc_add_otp_table.py +38 -0
  15. dmart/alembic/versions/6675fd9dfe42_remove_unique_from_sessions_table.py +36 -0
  16. dmart/alembic/versions/71bc1df82e6a_adding_user_last_login_at.py +43 -0
  17. dmart/alembic/versions/74288ccbd3b5_initial.py +264 -0
  18. dmart/alembic/versions/7520a89a8467_rm_activesession_table.py +39 -0
  19. dmart/alembic/versions/848b623755a4_make_created_nd_updated_at_required.py +138 -0
  20. dmart/alembic/versions/8640dcbebf85_add_notes_to_users.py +32 -0
  21. dmart/alembic/versions/91c94250232a_adding_fk_on_owner_shortname.py +104 -0
  22. dmart/alembic/versions/98ecd6f56f9a_ext_meta_with_owner_group_shortname.py +66 -0
  23. dmart/alembic/versions/9aae9138c4ef_indexing_created_at_updated_at.py +80 -0
  24. dmart/alembic/versions/__init__.py +0 -0
  25. dmart/alembic/versions/b53f916b3f6d_json_to_jsonb.py +492 -0
  26. dmart/alembic/versions/eb5f1ec65156_adding_user_locked_to_device.py +36 -0
  27. dmart/alembic/versions/f7a4949eed19_adding_query_policies_to_meta.py +60 -0
  28. dmart/alembic.ini +117 -0
  29. dmart/api/__init__.py +0 -0
  30. dmart/api/info/__init__.py +0 -0
  31. dmart/api/info/router.py +109 -0
  32. dmart/api/managed/__init__.py +0 -0
  33. dmart/api/managed/router.py +1541 -0
  34. dmart/api/managed/utils.py +1879 -0
  35. dmart/api/public/__init__.py +0 -0
  36. dmart/api/public/router.py +758 -0
  37. dmart/api/qr/__init__.py +0 -0
  38. dmart/api/qr/router.py +108 -0
  39. dmart/api/user/__init__.py +0 -0
  40. dmart/api/user/model/__init__.py +0 -0
  41. dmart/api/user/model/errors.py +14 -0
  42. dmart/api/user/model/requests.py +165 -0
  43. dmart/api/user/model/responses.py +11 -0
  44. dmart/api/user/router.py +1413 -0
  45. dmart/api/user/service.py +270 -0
  46. dmart/bundler.py +52 -0
  47. dmart/cli.py +1133 -0
  48. dmart/config/__init__.py +0 -0
  49. dmart/config/channels.json +11 -0
  50. dmart/config/notification.json +17 -0
  51. dmart/config.env.sample +27 -0
  52. dmart/config.ini.sample +7 -0
  53. dmart/conftest.py +13 -0
  54. dmart/curl.sh +196 -0
  55. dmart/cxb/__init__.py +0 -0
  56. dmart/cxb/assets/@codemirror-Rn7_6DkE.js +10 -0
  57. dmart/cxb/assets/@edraj-CS4NwVbD.js +1 -0
  58. dmart/cxb/assets/@floating-ui-BwwcF-xh.js +1 -0
  59. dmart/cxb/assets/@formatjs-yKEsAtjs.js +1 -0
  60. dmart/cxb/assets/@fortawesome-DRW1UCdr.js +9 -0
  61. dmart/cxb/assets/@jsonquerylang-laKNoFFq.js +12 -0
  62. dmart/cxb/assets/@lezer-za4Q-8Ew.js +1 -0
  63. dmart/cxb/assets/@marijn-DXwl3gUT.js +1 -0
  64. dmart/cxb/assets/@popperjs-l0sNRNKZ.js +1 -0
  65. dmart/cxb/assets/@replit--ERk53eB.js +1 -0
  66. dmart/cxb/assets/@roxi-CGMFK4i8.js +6 -0
  67. dmart/cxb/assets/@typewriter-cCzskkIv.js +17 -0
  68. dmart/cxb/assets/@zerodevx-BlBZjKxu.js +1 -0
  69. dmart/cxb/assets/@zerodevx-CVEpe6WZ.css +1 -0
  70. dmart/cxb/assets/BreadCrumbLite-DAhOx38v.js +1 -0
  71. dmart/cxb/assets/EntryRenderer-CCqV8Rkg.js +32 -0
  72. dmart/cxb/assets/EntryRenderer-DXytdFp9.css +1 -0
  73. dmart/cxb/assets/ListView-BQelo7vZ.js +16 -0
  74. dmart/cxb/assets/ListView-U8of-_c-.css +1 -0
  75. dmart/cxb/assets/Prism--hMplq-p.js +3 -0
  76. dmart/cxb/assets/Prism-Uh6uStUw.css +1 -0
  77. dmart/cxb/assets/Table2Cols-BsbwicQm.js +1 -0
  78. dmart/cxb/assets/_..-BvT6vdHa.css +1 -0
  79. dmart/cxb/assets/_...404_-fuLH_rX9.js +2 -0
  80. dmart/cxb/assets/_...fallback_-Ba_NLmAE.js +1 -0
  81. dmart/cxb/assets/_module-3HrtKAWo.js +3 -0
  82. dmart/cxb/assets/_module-DFKFq0AM.js +4 -0
  83. dmart/cxb/assets/_module-Dgq0ZVtz.js +1 -0
  84. dmart/cxb/assets/ajv-Cpj98o6Y.js +1 -0
  85. dmart/cxb/assets/axios-CG2WSiiR.js +6 -0
  86. dmart/cxb/assets/clsx-B-dksMZM.js +1 -0
  87. dmart/cxb/assets/codemirror-wrapped-line-indent-DPhKvljI.js +1 -0
  88. dmart/cxb/assets/compare-C3AjiGFR.js +1 -0
  89. dmart/cxb/assets/compute-scroll-into-view-Bl8rNFhg.js +1 -0
  90. dmart/cxb/assets/consolite-DlCuI0F9.js +1 -0
  91. dmart/cxb/assets/crelt-C8TCjufn.js +1 -0
  92. dmart/cxb/assets/date-fns-l0sNRNKZ.js +1 -0
  93. dmart/cxb/assets/deepmerge-rn4rBaHU.js +1 -0
  94. dmart/cxb/assets/dmart_services-AL6-IdDE.js +1 -0
  95. dmart/cxb/assets/downloadFile-D08i0YDh.js +1 -0
  96. dmart/cxb/assets/easy-signal-BiPFIK3O.js +1 -0
  97. dmart/cxb/assets/esm-env-rsSWfq8L.js +1 -0
  98. dmart/cxb/assets/export-OF_rTiXu.js +1 -0
  99. dmart/cxb/assets/fast-deep-equal-l0sNRNKZ.js +1 -0
  100. dmart/cxb/assets/fast-diff-C-IidNf4.js +1 -0
  101. dmart/cxb/assets/fast-uri-l0sNRNKZ.js +1 -0
  102. dmart/cxb/assets/flowbite-svelte-BLvjb-sa.js +1 -0
  103. dmart/cxb/assets/flowbite-svelte-CD54FDqW.css +1 -0
  104. dmart/cxb/assets/flowbite-svelte-icons-BI8GVhw_.js +1 -0
  105. dmart/cxb/assets/github-slugger-CQ4oX9Ud.js +1 -0
  106. dmart/cxb/assets/global-igKv-1g9.js +1 -0
  107. dmart/cxb/assets/hookar-BMRD9G9H.js +1 -0
  108. dmart/cxb/assets/immutable-json-patch-DtRO2E_S.js +1 -0
  109. dmart/cxb/assets/import-1vE3gBat.js +1 -0
  110. dmart/cxb/assets/index-B-eTh-ZX.js +1 -0
  111. dmart/cxb/assets/index-BSsK-X71.js +1 -0
  112. dmart/cxb/assets/index-BVyxzKtH.js +1 -0
  113. dmart/cxb/assets/index-BdeNM69f.js +1 -0
  114. dmart/cxb/assets/index-CC-A1ipE.js +1 -0
  115. dmart/cxb/assets/index-CQohGiYB.js +1 -0
  116. dmart/cxb/assets/index-ChjnkpdZ.js +4 -0
  117. dmart/cxb/assets/index-DLP7csA4.js +1 -0
  118. dmart/cxb/assets/index-DTfhnhwd.js +1 -0
  119. dmart/cxb/assets/index-DdXRK7n9.js +2 -0
  120. dmart/cxb/assets/index-DtiCmB4o.js +1 -0
  121. dmart/cxb/assets/index-NBrXBlLA.css +2 -0
  122. dmart/cxb/assets/index-X1uNehO7.js +1 -0
  123. dmart/cxb/assets/index-nrQW6Nrr.js +1 -0
  124. dmart/cxb/assets/info-B986lRiM.js +1 -0
  125. dmart/cxb/assets/intl-messageformat-Dc5UU-HB.js +3 -0
  126. dmart/cxb/assets/jmespath-l0sNRNKZ.js +1 -0
  127. dmart/cxb/assets/json-schema-traverse-l0sNRNKZ.js +1 -0
  128. dmart/cxb/assets/json-source-map-DRgZidqy.js +5 -0
  129. dmart/cxb/assets/jsonpath-plus-l0sNRNKZ.js +1 -0
  130. dmart/cxb/assets/jsonrepair-B30Dx381.js +8 -0
  131. dmart/cxb/assets/lodash-es-DZVAA2ox.js +1 -0
  132. dmart/cxb/assets/marked-DKjyhwJX.js +56 -0
  133. dmart/cxb/assets/marked-gfm-heading-id-U5zO829x.js +2 -0
  134. dmart/cxb/assets/marked-mangle-CDMeiHC6.js +1 -0
  135. dmart/cxb/assets/memoize-one-BdPwpGay.js +1 -0
  136. dmart/cxb/assets/natural-compare-lite-Bg2Xcf-o.js +7 -0
  137. dmart/cxb/assets/pagination-svelte-D5CyoiE_.js +13 -0
  138. dmart/cxb/assets/pagination-svelte-v10nAbbM.css +1 -0
  139. dmart/cxb/assets/plantuml-encoder-C47mzt9T.js +1 -0
  140. dmart/cxb/assets/prismjs-DTUiLGJu.js +9 -0
  141. dmart/cxb/assets/profile-BUf-tKMe.js +1 -0
  142. dmart/cxb/assets/query-CNmXTsgf.js +1 -0
  143. dmart/cxb/assets/queryHelpers-C9iBWwqe.js +1 -0
  144. dmart/cxb/assets/scroll-into-view-if-needed-KR58zyjF.js +1 -0
  145. dmart/cxb/assets/spaces-0oyGvpii.js +1 -0
  146. dmart/cxb/assets/style-mod-Bs6eFhZE.js +3 -0
  147. dmart/cxb/assets/svelte-B2XmcTi_.js +4 -0
  148. dmart/cxb/assets/svelte-awesome-COLlx0DN.css +1 -0
  149. dmart/cxb/assets/svelte-awesome-DhnMA6Q_.js +1 -0
  150. dmart/cxb/assets/svelte-datatables-net-CY7LBj6I.js +1 -0
  151. dmart/cxb/assets/svelte-floating-ui-BlS3sOAQ.js +1 -0
  152. dmart/cxb/assets/svelte-i18n-CT2KkQaN.js +3 -0
  153. dmart/cxb/assets/svelte-jsoneditor-BzfX6Usi.css +1 -0
  154. dmart/cxb/assets/svelte-jsoneditor-CUGSvWId.js +25 -0
  155. dmart/cxb/assets/svelte-select-CegQKzqH.css +1 -0
  156. dmart/cxb/assets/svelte-select-CjHAt_85.js +6 -0
  157. dmart/cxb/assets/tailwind-merge-CJvxXMcu.js +1 -0
  158. dmart/cxb/assets/tailwind-variants-Cj20BoQ3.js +1 -0
  159. dmart/cxb/assets/toast-B9WDyfyI.js +1 -0
  160. dmart/cxb/assets/tslib-pJfR_DrR.js +1 -0
  161. dmart/cxb/assets/typewriter-editor-DkTVIJdm.js +25 -0
  162. dmart/cxb/assets/user-DeK_NB5v.js +1 -0
  163. dmart/cxb/assets/vanilla-picker-l5rcX3cq.js +8 -0
  164. dmart/cxb/assets/w3c-keyname-Vcq4gwWv.js +1 -0
  165. dmart/cxb/config.json +11 -0
  166. dmart/cxb/config.sample.json +11 -0
  167. dmart/cxb/favicon.ico +0 -0
  168. dmart/cxb/favicon.png +0 -0
  169. dmart/cxb/index.html +28 -0
  170. dmart/data_adapters/__init__.py +0 -0
  171. dmart/data_adapters/adapter.py +16 -0
  172. dmart/data_adapters/base_data_adapter.py +467 -0
  173. dmart/data_adapters/file/__init__.py +0 -0
  174. dmart/data_adapters/file/adapter.py +2043 -0
  175. dmart/data_adapters/file/adapter_helpers.py +1013 -0
  176. dmart/data_adapters/file/archive.py +150 -0
  177. dmart/data_adapters/file/create_index.py +331 -0
  178. dmart/data_adapters/file/create_users_folders.py +52 -0
  179. dmart/data_adapters/file/custom_validations.py +68 -0
  180. dmart/data_adapters/file/drop_index.py +40 -0
  181. dmart/data_adapters/file/health_check.py +560 -0
  182. dmart/data_adapters/file/redis_services.py +1110 -0
  183. dmart/data_adapters/helpers.py +27 -0
  184. dmart/data_adapters/sql/__init__.py +0 -0
  185. dmart/data_adapters/sql/adapter.py +3218 -0
  186. dmart/data_adapters/sql/adapter_helpers.py +491 -0
  187. dmart/data_adapters/sql/create_tables.py +451 -0
  188. dmart/data_adapters/sql/create_users_folders.py +53 -0
  189. dmart/data_adapters/sql/db_to_json_migration.py +485 -0
  190. dmart/data_adapters/sql/health_check_sql.py +232 -0
  191. dmart/data_adapters/sql/json_to_db_migration.py +454 -0
  192. dmart/data_adapters/sql/update_query_policies.py +101 -0
  193. dmart/data_generator.py +81 -0
  194. dmart/dmart.py +761 -0
  195. dmart/get_settings.py +7 -0
  196. dmart/hypercorn_config.toml +3 -0
  197. dmart/info.json +1 -0
  198. dmart/languages/__init__.py +0 -0
  199. dmart/languages/arabic.json +15 -0
  200. dmart/languages/english.json +16 -0
  201. dmart/languages/kurdish.json +14 -0
  202. dmart/languages/loader.py +12 -0
  203. dmart/login_creds.sh +7 -0
  204. dmart/login_creds.sh.sample +7 -0
  205. dmart/main.py +563 -0
  206. dmart/manifest.sh +12 -0
  207. dmart/migrate.py +24 -0
  208. dmart/models/__init__.py +0 -0
  209. dmart/models/api.py +203 -0
  210. dmart/models/core.py +597 -0
  211. dmart/models/enums.py +255 -0
  212. dmart/password_gen.py +8 -0
  213. dmart/plugins/__init__.py +0 -0
  214. dmart/plugins/action_log/__init__.py +0 -0
  215. dmart/plugins/action_log/config.json +13 -0
  216. dmart/plugins/action_log/plugin.py +121 -0
  217. dmart/plugins/admin_notification_sender/__init__.py +0 -0
  218. dmart/plugins/admin_notification_sender/config.json +13 -0
  219. dmart/plugins/admin_notification_sender/plugin.py +124 -0
  220. dmart/plugins/ldap_manager/__init__.py +0 -0
  221. dmart/plugins/ldap_manager/config.json +12 -0
  222. dmart/plugins/ldap_manager/dmart.schema +146 -0
  223. dmart/plugins/ldap_manager/plugin.py +100 -0
  224. dmart/plugins/ldap_manager/slapd.conf +53 -0
  225. dmart/plugins/local_notification/__init__.py +0 -0
  226. dmart/plugins/local_notification/config.json +13 -0
  227. dmart/plugins/local_notification/plugin.py +123 -0
  228. dmart/plugins/realtime_updates_notifier/__init__.py +0 -0
  229. dmart/plugins/realtime_updates_notifier/config.json +12 -0
  230. dmart/plugins/realtime_updates_notifier/plugin.py +58 -0
  231. dmart/plugins/redis_db_update/__init__.py +0 -0
  232. dmart/plugins/redis_db_update/config.json +13 -0
  233. dmart/plugins/redis_db_update/plugin.py +188 -0
  234. dmart/plugins/resource_folders_creation/__init__.py +0 -0
  235. dmart/plugins/resource_folders_creation/config.json +12 -0
  236. dmart/plugins/resource_folders_creation/plugin.py +81 -0
  237. dmart/plugins/system_notification_sender/__init__.py +0 -0
  238. dmart/plugins/system_notification_sender/config.json +13 -0
  239. dmart/plugins/system_notification_sender/plugin.py +188 -0
  240. dmart/plugins/update_access_controls/__init__.py +0 -0
  241. dmart/plugins/update_access_controls/config.json +12 -0
  242. dmart/plugins/update_access_controls/plugin.py +9 -0
  243. dmart/publish.sh +57 -0
  244. dmart/pylint.sh +16 -0
  245. dmart/pyrightconfig.json +7 -0
  246. dmart/redis_connections.sh +13 -0
  247. dmart/reload.sh +56 -0
  248. dmart/run.sh +3 -0
  249. dmart/run_notification_campaign.py +85 -0
  250. dmart/sample/spaces/applications/.dm/meta.space.json +30 -0
  251. dmart/sample/spaces/applications/api/.dm/meta.folder.json +1 -0
  252. dmart/sample/spaces/applications/api/.dm/query_all_applications/meta.content.json +1 -0
  253. dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/meta.warframe.json +1 -0
  254. dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/warframe.png +0 -0
  255. dmart/sample/spaces/applications/api/.dm/test_by_saad/meta.content.json +1 -0
  256. dmart/sample/spaces/applications/api/.dm/user_profile/meta.content.json +1 -0
  257. dmart/sample/spaces/applications/api/applications/.dm/create_log/meta.content.json +1 -0
  258. dmart/sample/spaces/applications/api/applications/.dm/create_public_logs/meta.content.json +1 -0
  259. dmart/sample/spaces/applications/api/applications/.dm/meta.folder.json +1 -0
  260. dmart/sample/spaces/applications/api/applications/.dm/query_all_translated_data/meta.content.json +1 -0
  261. dmart/sample/spaces/applications/api/applications/.dm/query_logs/meta.content.json +1 -0
  262. dmart/sample/spaces/applications/api/applications/.dm/query_translated_enums/meta.content.json +1 -0
  263. dmart/sample/spaces/applications/api/applications/.dm/query_translated_others/meta.content.json +1 -0
  264. dmart/sample/spaces/applications/api/applications/.dm/query_translated_resolution/meta.content.json +1 -0
  265. dmart/sample/spaces/applications/api/applications/create_log.json +1 -0
  266. dmart/sample/spaces/applications/api/applications/create_public_logs.json +1 -0
  267. dmart/sample/spaces/applications/api/applications/query_all_translated_data.json +1 -0
  268. dmart/sample/spaces/applications/api/applications/query_logs.json +1 -0
  269. dmart/sample/spaces/applications/api/applications/query_translated_enums.json +1 -0
  270. dmart/sample/spaces/applications/api/applications/query_translated_others.json +1 -0
  271. dmart/sample/spaces/applications/api/applications/query_translated_resolution.json +1 -0
  272. dmart/sample/spaces/applications/api/applications.json +1 -0
  273. dmart/sample/spaces/applications/api/management/.dm/create_subaccount/meta.content.json +1 -0
  274. dmart/sample/spaces/applications/api/management/.dm/meta.folder.json +1 -0
  275. dmart/sample/spaces/applications/api/management/.dm/update_password/meta.content.json +1 -0
  276. dmart/sample/spaces/applications/api/management/create_subaccount.json +53 -0
  277. dmart/sample/spaces/applications/api/management/update_password.json +1 -0
  278. dmart/sample/spaces/applications/api/management.json +1 -0
  279. dmart/sample/spaces/applications/api/query_all_applications.json +15 -0
  280. dmart/sample/spaces/applications/api/test_by_saad.json +1 -0
  281. dmart/sample/spaces/applications/api/user/.dm/meta.folder.json +1 -0
  282. dmart/sample/spaces/applications/api/user/.dm/test_by_saad/meta.content.json +1 -0
  283. dmart/sample/spaces/applications/api/user/.dm/user_profile/meta.content.json +1 -0
  284. dmart/sample/spaces/applications/api/user/test_by_saad.json +1 -0
  285. dmart/sample/spaces/applications/api/user/user_profile.json +1 -0
  286. dmart/sample/spaces/applications/api/user_profile.json +1 -0
  287. dmart/sample/spaces/applications/api.json +1 -0
  288. dmart/sample/spaces/applications/collections/.dm/meta.folder.json +19 -0
  289. dmart/sample/spaces/applications/collections.json +1 -0
  290. dmart/sample/spaces/applications/configurations/.dm/meta.folder.json +1 -0
  291. dmart/sample/spaces/applications/configurations/time_out.json +1 -0
  292. dmart/sample/spaces/applications/configurations.json +19 -0
  293. dmart/sample/spaces/applications/errors.json +1 -0
  294. dmart/sample/spaces/applications/logs/.dm/meta.folder.json +1 -0
  295. dmart/sample/spaces/applications/logs.json +1 -0
  296. dmart/sample/spaces/applications/queries/.dm/meta.folder.json +1 -0
  297. dmart/sample/spaces/applications/queries/.dm/order/meta.content.json +1 -0
  298. dmart/sample/spaces/applications/queries/order.json +1 -0
  299. dmart/sample/spaces/applications/queries.json +1 -0
  300. dmart/sample/spaces/applications/schema/.dm/api/meta.schema.json +1 -0
  301. dmart/sample/spaces/applications/schema/.dm/configuration/meta.schema.json +1 -0
  302. dmart/sample/spaces/applications/schema/.dm/error/meta.schema.json +1 -0
  303. dmart/sample/spaces/applications/schema/.dm/log/meta.schema.json +1 -0
  304. dmart/sample/spaces/applications/schema/.dm/meta.folder.json +1 -0
  305. dmart/sample/spaces/applications/schema/.dm/query/meta.schema.json +16 -0
  306. dmart/sample/spaces/applications/schema/.dm/translation/meta.schema.json +1 -0
  307. dmart/sample/spaces/applications/schema/api.json +28 -0
  308. dmart/sample/spaces/applications/schema/configuration.json +1 -0
  309. dmart/sample/spaces/applications/schema/error.json +43 -0
  310. dmart/sample/spaces/applications/schema/log.json +1 -0
  311. dmart/sample/spaces/applications/schema/query.json +118 -0
  312. dmart/sample/spaces/applications/schema/translation.json +26 -0
  313. dmart/sample/spaces/applications/schema.json +1 -0
  314. dmart/sample/spaces/applications/translations/.dm/meta.folder.json +1 -0
  315. dmart/sample/spaces/applications/translations.json +1 -0
  316. dmart/sample/spaces/archive/.dm/meta.space.json +27 -0
  317. dmart/sample/spaces/custom_plugins/dummy/__pycache__/plugin.cpython-314.pyc +0 -0
  318. dmart/sample/spaces/custom_plugins/dummy/config.json +28 -0
  319. dmart/sample/spaces/custom_plugins/dummy/plugin.py +6 -0
  320. dmart/sample/spaces/custom_plugins/missed_entry/config.json +12 -0
  321. dmart/sample/spaces/custom_plugins/missed_entry/plugin.py +119 -0
  322. dmart/sample/spaces/custom_plugins/own_changed_notification/__pycache__/plugin.cpython-314.pyc +0 -0
  323. dmart/sample/spaces/custom_plugins/own_changed_notification/config.json +12 -0
  324. dmart/sample/spaces/custom_plugins/own_changed_notification/plugin.py +65 -0
  325. dmart/sample/spaces/custom_plugins/reports_stats/config.json +14 -0
  326. dmart/sample/spaces/custom_plugins/reports_stats/plugin.py +82 -0
  327. dmart/sample/spaces/custom_plugins/system_notification_sender/config.json +22 -0
  328. dmart/sample/spaces/custom_plugins/system_notification_sender/notification.py +268 -0
  329. dmart/sample/spaces/custom_plugins/system_notification_sender/plugin.py +98 -0
  330. dmart/sample/spaces/management/.dm/events.jsonl +32 -0
  331. dmart/sample/spaces/management/.dm/meta.space.json +48 -0
  332. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/admin.json +36 -0
  333. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.admin.json +1 -0
  334. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.system.json +1 -0
  335. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/system.json +32 -0
  336. dmart/sample/spaces/management/collections/.dm/meta.folder.json +1 -0
  337. dmart/sample/spaces/management/collections.json +1 -0
  338. dmart/sample/spaces/management/groups/.dm/meta.folder.json +1 -0
  339. dmart/sample/spaces/management/groups.json +1 -0
  340. dmart/sample/spaces/management/health_check/.dm/meta.folder.json +1 -0
  341. dmart/sample/spaces/management/health_check.json +1 -0
  342. dmart/sample/spaces/management/notifications/.dm/meta.folder.json +1 -0
  343. dmart/sample/spaces/management/notifications/admin/.dm/meta.folder.json +9 -0
  344. dmart/sample/spaces/management/notifications/system/.dm/meta.folder.json +9 -0
  345. dmart/sample/spaces/management/notifications.json +1 -0
  346. dmart/sample/spaces/management/permissions/.dm/access_applications/meta.permission.json +31 -0
  347. dmart/sample/spaces/management/permissions/.dm/access_applications_world/meta.permission.json +31 -0
  348. dmart/sample/spaces/management/permissions/.dm/access_messages/meta.permission.json +23 -0
  349. dmart/sample/spaces/management/permissions/.dm/access_personal/meta.permission.json +40 -0
  350. dmart/sample/spaces/management/permissions/.dm/access_protected/meta.permission.json +33 -0
  351. dmart/sample/spaces/management/permissions/.dm/access_public/meta.permission.json +24 -0
  352. dmart/sample/spaces/management/permissions/.dm/browse_all_folders/meta.permission.json +23 -0
  353. dmart/sample/spaces/management/permissions/.dm/create_log/meta.permission.json +24 -0
  354. dmart/sample/spaces/management/permissions/.dm/interviewer/meta.permission.json +1 -0
  355. dmart/sample/spaces/management/permissions/.dm/manage_applications/meta.permission.json +1 -0
  356. dmart/sample/spaces/management/permissions/.dm/manage_debug/meta.permission.json +25 -0
  357. dmart/sample/spaces/management/permissions/.dm/manage_spaces/meta.permission.json +24 -0
  358. dmart/sample/spaces/management/permissions/.dm/meta.folder.json +1 -0
  359. dmart/sample/spaces/management/permissions/.dm/rules_management_default/meta.permission.json +32 -0
  360. dmart/sample/spaces/management/permissions/.dm/super_manager/meta.permission.json +52 -0
  361. dmart/sample/spaces/management/permissions/.dm/view_activity_log/meta.permission.json +26 -0
  362. dmart/sample/spaces/management/permissions/.dm/view_collections/meta.permission.json +29 -0
  363. dmart/sample/spaces/management/permissions/.dm/view_logs/meta.permission.json +30 -0
  364. dmart/sample/spaces/management/permissions/.dm/view_roles/meta.permission.json +29 -0
  365. dmart/sample/spaces/management/permissions/.dm/view_users/meta.permission.json +25 -0
  366. dmart/sample/spaces/management/permissions/.dm/view_world/meta.permission.json +31 -0
  367. dmart/sample/spaces/management/permissions/.dm/world/meta.permission.json +35 -0
  368. dmart/sample/spaces/management/permissions.json +1 -0
  369. dmart/sample/spaces/management/requests.json +1 -0
  370. dmart/sample/spaces/management/roles/.dm/dummy/meta.role.json +12 -0
  371. dmart/sample/spaces/management/roles/.dm/logged_in/meta.role.json +18 -0
  372. dmart/sample/spaces/management/roles/.dm/manager/meta.role.json +13 -0
  373. dmart/sample/spaces/management/roles/.dm/meta.folder.json +1 -0
  374. dmart/sample/spaces/management/roles/.dm/moderator/meta.role.json +13 -0
  375. dmart/sample/spaces/management/roles/.dm/super_admin/meta.role.json +14 -0
  376. dmart/sample/spaces/management/roles/.dm/test_role/meta.role.json +13 -0
  377. dmart/sample/spaces/management/roles/.dm/world/meta.role.json +15 -0
  378. dmart/sample/spaces/management/roles.json +1 -0
  379. dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/meta.ui_schema.json +10 -0
  380. dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/ui_schema.json +32 -0
  381. dmart/sample/spaces/management/schema/.dm/admin_notification_request/meta.schema.json +1 -0
  382. dmart/sample/spaces/management/schema/.dm/api/meta.schema.json +1 -0
  383. dmart/sample/spaces/management/schema/.dm/folder_rendering/meta.schema.json +1 -0
  384. dmart/sample/spaces/management/schema/.dm/health_check/meta.schema.json +17 -0
  385. dmart/sample/spaces/management/schema/.dm/meta.folder.json +1 -0
  386. dmart/sample/spaces/management/schema/.dm/meta_schema/meta.schema.json +1 -0
  387. dmart/sample/spaces/management/schema/.dm/metafile/meta.schema.json +14 -0
  388. dmart/sample/spaces/management/schema/.dm/notification/meta.schema.json +1 -0
  389. dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/meta.ui_schema.json +10 -0
  390. dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/ui_schema.json +32 -0
  391. dmart/sample/spaces/management/schema/.dm/system_notification_request/meta.schema.json +1 -0
  392. dmart/sample/spaces/management/schema/.dm/view/meta.schema.json +1 -0
  393. dmart/sample/spaces/management/schema/.dm/workflow/meta.schema.json +1 -0
  394. dmart/sample/spaces/management/schema/admin_notification_request.json +89 -0
  395. dmart/sample/spaces/management/schema/api.json +1 -0
  396. dmart/sample/spaces/management/schema/folder_rendering.json +238 -0
  397. dmart/sample/spaces/management/schema/health_check.json +8 -0
  398. dmart/sample/spaces/management/schema/meta_schema.json +74 -0
  399. dmart/sample/spaces/management/schema/metafile.json +153 -0
  400. dmart/sample/spaces/management/schema/notification.json +28 -0
  401. dmart/sample/spaces/management/schema/system_notification_request.json +57 -0
  402. dmart/sample/spaces/management/schema/view.json +23 -0
  403. dmart/sample/spaces/management/schema/workflow.json +87 -0
  404. dmart/sample/spaces/management/schema.json +1 -0
  405. dmart/sample/spaces/management/users/.dm/alibaba/meta.user.json +23 -0
  406. dmart/sample/spaces/management/users/.dm/anonymous/meta.user.json +18 -0
  407. dmart/sample/spaces/management/users/.dm/dmart/meta.user.json +26 -0
  408. dmart/sample/spaces/management/users/.dm/meta.folder.json +14 -0
  409. dmart/sample/spaces/management/workflows/.dm/channel/meta.content.json +1 -0
  410. dmart/sample/spaces/management/workflows/.dm/meta.folder.json +1 -0
  411. dmart/sample/spaces/management/workflows/channel.json +148 -0
  412. dmart/sample/spaces/management/workflows.json +1 -0
  413. dmart/sample/spaces/maqola/.dm/meta.space.json +33 -0
  414. dmart/sample/spaces/personal/.dm/meta.space.json +24 -0
  415. dmart/sample/spaces/personal/people/.dm/meta.folder.json +1 -0
  416. dmart/sample/spaces/personal/people/dmart/.dm/meta.folder.json +1 -0
  417. dmart/sample/spaces/personal/people/dmart/messages/.dm/0b5f7e7f/meta.content.json +1 -0
  418. dmart/sample/spaces/personal/people/dmart/messages/.dm/meta.folder.json +1 -0
  419. dmart/sample/spaces/personal/people/dmart/messages/.dm/mytest/meta.content.json +1 -0
  420. dmart/sample/spaces/personal/people/dmart/messages/0b5f7e7f.json +1 -0
  421. dmart/sample/spaces/personal/people/dmart/messages/mytest.json +1 -0
  422. dmart/sample/spaces/personal/people/dmart/notifications/.dm/meta.folder.json +1 -0
  423. dmart/sample/spaces/personal/people/dmart/private/.dm/inner/meta.content.json +1 -0
  424. dmart/sample/spaces/personal/people/dmart/private/.dm/meta.folder.json +1 -0
  425. dmart/sample/spaces/personal/people/dmart/private/inner.json +1 -0
  426. dmart/sample/spaces/personal/people/dmart/protected/.dm/avatar/meta.content.json +1 -0
  427. dmart/sample/spaces/personal/people/dmart/protected/.dm/meta.folder.json +1 -0
  428. dmart/sample/spaces/personal/people/dmart/protected/avatar.png +0 -0
  429. dmart/sample/spaces/personal/people/dmart/public/.dm/meta.folder.json +1 -0
  430. dmart/sample/test/.gitignore +2 -0
  431. dmart/sample/test/createcontent.json +9 -0
  432. dmart/sample/test/createmedia.json +9 -0
  433. dmart/sample/test/createmedia_entry.json +6 -0
  434. dmart/sample/test/createschema.json +8 -0
  435. dmart/sample/test/createschemawork.json +11 -0
  436. dmart/sample/test/createticket.json +13 -0
  437. dmart/sample/test/data.json +4 -0
  438. dmart/sample/test/deletecontent.json +12 -0
  439. dmart/sample/test/logo.jpeg +0 -0
  440. dmart/sample/test/my.jpg +0 -0
  441. dmart/sample/test/myticket.json +23 -0
  442. dmart/sample/test/resources.csv +12 -0
  443. dmart/sample/test/schema.json +16 -0
  444. dmart/sample/test/temp.json +1 -0
  445. dmart/sample/test/test.dmart +45 -0
  446. dmart/sample/test/ticket_schema.json +23 -0
  447. dmart/sample/test/ticket_workflow.json +85 -0
  448. dmart/sample/test/ticketbody.json +4 -0
  449. dmart/sample/test/ticketcontent.json +14 -0
  450. dmart/sample/test/updatecontent.json +20 -0
  451. dmart/sample/test/workflow_schema.json +68 -0
  452. dmart/scheduled_notification_handler.py +121 -0
  453. dmart/schema_migration.py +208 -0
  454. dmart/schema_modulate.py +192 -0
  455. dmart/set_admin_passwd.py +75 -0
  456. dmart/sync.py +202 -0
  457. dmart/test_utils.py +34 -0
  458. dmart/utils/__init__.py +0 -0
  459. dmart/utils/access_control.py +306 -0
  460. dmart/utils/async_request.py +8 -0
  461. dmart/utils/exporter.py +309 -0
  462. dmart/utils/firebase_notifier.py +57 -0
  463. dmart/utils/generate_email.py +37 -0
  464. dmart/utils/helpers.py +352 -0
  465. dmart/utils/hypercorn_config.py +12 -0
  466. dmart/utils/internal_error_code.py +60 -0
  467. dmart/utils/jwt.py +124 -0
  468. dmart/utils/logger.py +167 -0
  469. dmart/utils/middleware.py +99 -0
  470. dmart/utils/notification.py +75 -0
  471. dmart/utils/password_hashing.py +16 -0
  472. dmart/utils/plugin_manager.py +202 -0
  473. dmart/utils/query_policies_helper.py +128 -0
  474. dmart/utils/regex.py +44 -0
  475. dmart/utils/repository.py +529 -0
  476. dmart/utils/router_helper.py +19 -0
  477. dmart/utils/settings.py +212 -0
  478. dmart/utils/sms_notifier.py +21 -0
  479. dmart/utils/social_sso.py +67 -0
  480. dmart/utils/templates/activation.html.j2 +26 -0
  481. dmart/utils/templates/reminder.html.j2 +17 -0
  482. dmart/utils/ticket_sys_utils.py +203 -0
  483. dmart/utils/web_notifier.py +29 -0
  484. dmart/websocket.py +231 -0
  485. dmart-1.4.40.post8.dist-info/METADATA +75 -0
  486. dmart-1.4.40.post8.dist-info/RECORD +489 -0
  487. dmart-1.4.40.post8.dist-info/WHEEL +5 -0
  488. dmart-1.4.40.post8.dist-info/entry_points.txt +2 -0
  489. dmart-1.4.40.post8.dist-info/top_level.txt +1 -0
dmart/dmart.py ADDED
@@ -0,0 +1,761 @@
1
+ #!/usr/bin/env -S BACKEND_ENV=config.env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import shutil
9
+ import ssl
10
+ import subprocess
11
+ import sys
12
+ import time
13
+ import warnings
14
+ import webbrowser
15
+ import re
16
+ # from multiprocessing import freeze_support
17
+ from pathlib import Path
18
+
19
+ from hypercorn.config import Config
20
+ from hypercorn.run import run
21
+ from utils.settings import settings
22
+
23
+ # freeze_support()
24
+
25
+ commands = """
26
+ serve
27
+ hyper
28
+ cli
29
+ health-check
30
+ create-index
31
+ export
32
+ settings
33
+ set_password
34
+ archive
35
+ json_to_db
36
+ db_to_json
37
+ help
38
+ version
39
+ info
40
+ init
41
+ migrate
42
+ """
43
+
44
+ sentinel = object()
45
+
46
+
47
+ def hypercorn_main() -> int:
48
+ parser = argparse.ArgumentParser()
49
+ parser.add_argument(
50
+ "application",
51
+ help="The application to dispatch to as path.to.module:instance.path",
52
+ nargs="?",
53
+ default="main:app"
54
+ )
55
+ parser.add_argument("--access-log", help="Deprecated, see access-logfile", default=sentinel)
56
+ parser.add_argument(
57
+ "--access-logfile",
58
+ help="The target location for the access log, use `-` for stdout",
59
+ default=sentinel,
60
+ )
61
+ parser.add_argument(
62
+ "--access-logformat",
63
+ help="The log format for the access log, see help docs",
64
+ default=sentinel,
65
+ )
66
+ parser.add_argument(
67
+ "--backlog", help="The maximum number of pending connections", type=int, default=sentinel
68
+ )
69
+ parser.add_argument(
70
+ "-b",
71
+ "--bind",
72
+ dest="binds",
73
+ help=""" The TCP host/address to bind to. Should be either host:port, host,
74
+ unix:path or fd://num, e.g. 127.0.0.1:5000, 127.0.0.1,
75
+ unix:/tmp/socket or fd://33 respectively. """,
76
+ default=[],
77
+ action="append",
78
+ )
79
+ parser.add_argument("--ca-certs", help="Path to the SSL CA certificate file", default=sentinel)
80
+ parser.add_argument("--certfile", help="Path to the SSL certificate file", default=sentinel)
81
+ parser.add_argument("--cert-reqs", help="See verify mode argument", type=int, default=sentinel)
82
+ parser.add_argument("--ciphers", help="Ciphers to use for the SSL setup", default=sentinel)
83
+ parser.add_argument(
84
+ "-c",
85
+ "--config",
86
+ help="Location of a TOML config file, or when prefixed with `file:` a Python file, or when prefixed with `python:` a Python module.", # noqa: E501
87
+ default="hypercorn_config.toml",
88
+ )
89
+ parser.add_argument(
90
+ "--debug",
91
+ help="Enable debug mode, i.e. extra logging and checks",
92
+ action="store_true",
93
+ default=sentinel,
94
+ )
95
+ parser.add_argument("--error-log", help="Deprecated, see error-logfile", default=sentinel)
96
+ parser.add_argument(
97
+ "--error-logfile",
98
+ "--log-file",
99
+ dest="error_logfile",
100
+ help="The target location for the error log, use `-` for stderr",
101
+ default=sentinel,
102
+ )
103
+ parser.add_argument(
104
+ "--graceful-timeout",
105
+ help="""Time to wait after SIGTERM or Ctrl-C for any remaining requests (tasks)
106
+ to complete.""",
107
+ default=sentinel,
108
+ type=int,
109
+ )
110
+ parser.add_argument(
111
+ "--read-timeout",
112
+ help="""Seconds to wait before timing out reads on TCP sockets""",
113
+ default=sentinel,
114
+ type=int,
115
+ )
116
+ parser.add_argument(
117
+ "--max-requests",
118
+ help="""Maximum number of requests a worker will process before restarting""",
119
+ default=sentinel,
120
+ type=int,
121
+ )
122
+ parser.add_argument(
123
+ "--max-requests-jitter",
124
+ help="This jitter causes the max-requests per worker to be "
125
+ "randomized by randint(0, max_requests_jitter)",
126
+ default=sentinel,
127
+ type=int,
128
+ )
129
+ parser.add_argument(
130
+ "-g", "--group", help="Group to own any unix sockets.", default=sentinel, type=int
131
+ )
132
+ parser.add_argument(
133
+ "-k",
134
+ "--worker-class",
135
+ dest="worker_class",
136
+ help="The type of worker to use. "
137
+ "Options include asyncio, uvloop (pip install hypercorn[uvloop]), "
138
+ "and trio (pip install hypercorn[trio]).",
139
+ default=sentinel,
140
+ )
141
+ parser.add_argument(
142
+ "--keep-alive",
143
+ help="Seconds to keep inactive connections alive for",
144
+ default=sentinel,
145
+ type=int,
146
+ )
147
+ parser.add_argument("--keyfile", help="Path to the SSL key file", default=sentinel)
148
+ parser.add_argument(
149
+ "--keyfile-password", help="Password to decrypt the SSL key file", default=sentinel
150
+ )
151
+ parser.add_argument(
152
+ "--insecure-bind",
153
+ dest="insecure_binds",
154
+ help="""The TCP host/address to bind to. SSL options will not apply to these binds.
155
+ See *bind* for formatting options. Care must be taken! See HTTP -> HTTPS redirection docs.
156
+ """,
157
+ default=[],
158
+ action="append",
159
+ )
160
+ parser.add_argument(
161
+ "--log-config",
162
+ help=""""A Python logging configuration file. This can be prefixed with
163
+ 'json:' or 'toml:' to load the configuration from a file in
164
+ that format. Default is the logging ini format.""",
165
+ default=sentinel,
166
+ )
167
+ parser.add_argument(
168
+ "--log-level", help="The (error) log level, defaults to info", default=sentinel
169
+ )
170
+ parser.add_argument(
171
+ "-p", "--pid", help="Location to write the PID (Program ID) to.", default=sentinel
172
+ )
173
+ parser.add_argument(
174
+ "--quic-bind",
175
+ dest="quic_binds",
176
+ help="""The UDP/QUIC host/address to bind to. See *bind* for formatting
177
+ options.
178
+ """,
179
+ default=[],
180
+ action="append",
181
+ )
182
+ parser.add_argument(
183
+ "--reload",
184
+ help="Enable automatic reloads on code changes",
185
+ action="store_true",
186
+ default=sentinel,
187
+ )
188
+ parser.add_argument(
189
+ "--root-path", help="The setting for the ASGI root_path variable", default=sentinel
190
+ )
191
+ parser.add_argument(
192
+ "--server-name",
193
+ dest="server_names",
194
+ help="""The hostnames that can be served, requests to different hosts
195
+ will be responded to with 404s.
196
+ """,
197
+ default=[],
198
+ action="append",
199
+ )
200
+ parser.add_argument(
201
+ "--statsd-host", help="The host:port of the statsd server", default=sentinel
202
+ )
203
+ parser.add_argument("--statsd-prefix", help="Prefix for all statsd messages", default="")
204
+ parser.add_argument(
205
+ "-m",
206
+ "--umask",
207
+ help="The permissions bit mask to use on any unix sockets.",
208
+ default=sentinel,
209
+ type=int,
210
+ )
211
+ parser.add_argument(
212
+ "-u", "--user", help="User to own any unix sockets.", default=sentinel, type=int
213
+ )
214
+ parser.add_argument(
215
+ "--open-cxb",
216
+ help="Open CXB page in browser after server starts",
217
+ action="store_true",
218
+ default=False,
219
+ )
220
+ parser.add_argument(
221
+ "--cxb-config",
222
+ help="Path to CXB config.json",
223
+ default=sentinel,
224
+ )
225
+
226
+ def _convert_verify_mode(value: str) -> ssl.VerifyMode:
227
+ try:
228
+ return ssl.VerifyMode[value]
229
+ except KeyError:
230
+ raise argparse.ArgumentTypeError(f"'{value}' is not a valid verify mode")
231
+
232
+ parser.add_argument(
233
+ "--verify-mode",
234
+ help="SSL verify mode for peer's certificate, see ssl.VerifyMode enum for possible values.",
235
+ type=_convert_verify_mode,
236
+ default=sentinel,
237
+ )
238
+ parser.add_argument(
239
+ "--websocket-ping-interval",
240
+ help="""If set this is the time in seconds between pings sent to the client.
241
+ This can be used to keep the websocket connection alive.""",
242
+ default=sentinel,
243
+ type=int,
244
+ )
245
+ parser.add_argument(
246
+ "-w",
247
+ "--workers",
248
+ dest="workers",
249
+ help="The number of workers to spawn and use",
250
+ default=sentinel,
251
+ type=int,
252
+ )
253
+ args = parser.parse_args(sys.argv[1:])
254
+
255
+ if args.config == "hypercorn_config.toml" and not os.path.exists(args.config):
256
+ config = Config()
257
+ config.backlog = 2000
258
+ config.workers = 1
259
+ config.bind = ["localhost:8282"]
260
+ else:
261
+ config = Config.from_toml(args.config)
262
+
263
+ config.application_path = args.application
264
+
265
+ if args.log_level is not sentinel:
266
+ config.loglevel = args.log_level
267
+ if args.access_logformat is not sentinel:
268
+ config.access_log_format = args.access_logformat
269
+ if args.access_log is not sentinel:
270
+ warnings.warn(
271
+ "The --access-log argument is deprecated, use `--access-logfile` instead",
272
+ DeprecationWarning,
273
+ )
274
+ config.accesslog = args.access_log
275
+ if args.access_logfile is not sentinel:
276
+ config.accesslog = args.access_logfile
277
+ if args.backlog is not sentinel:
278
+ config.backlog = args.backlog
279
+ if args.ca_certs is not sentinel:
280
+ config.ca_certs = args.ca_certs
281
+ if args.certfile is not sentinel:
282
+ config.certfile = args.certfile
283
+ if args.cert_reqs is not sentinel:
284
+ config.cert_reqs = args.cert_reqs
285
+ if args.ciphers is not sentinel:
286
+ config.ciphers = args.ciphers
287
+ if args.debug is not sentinel:
288
+ config.debug = args.debug
289
+ if args.error_log is not sentinel:
290
+ warnings.warn(
291
+ "The --error-log argument is deprecated, use `--error-logfile` instead",
292
+ DeprecationWarning,
293
+ )
294
+ config.errorlog = args.error_log
295
+ if args.error_logfile is not sentinel:
296
+ config.errorlog = args.error_logfile
297
+ if args.graceful_timeout is not sentinel:
298
+ config.graceful_timeout = args.graceful_timeout
299
+ if args.read_timeout is not sentinel:
300
+ config.read_timeout = args.read_timeout
301
+ if args.group is not sentinel:
302
+ config.group = args.group
303
+ if args.keep_alive is not sentinel:
304
+ config.keep_alive_timeout = args.keep_alive
305
+ if args.keyfile is not sentinel:
306
+ config.keyfile = args.keyfile
307
+ if args.keyfile_password is not sentinel:
308
+ config.keyfile_password = args.keyfile_password
309
+ if args.log_config is not sentinel:
310
+ config.logconfig = args.log_config
311
+ if args.max_requests is not sentinel:
312
+ config.max_requests = args.max_requests
313
+ if args.max_requests_jitter is not sentinel:
314
+ config.max_requests_jitter = args.max_requests
315
+ if args.pid is not sentinel:
316
+ config.pid_path = args.pid
317
+ if args.root_path is not sentinel:
318
+ config.root_path = args.root_path
319
+ if args.reload is not sentinel:
320
+ config.use_reloader = args.reload
321
+ if args.statsd_host is not sentinel:
322
+ config.statsd_host = args.statsd_host
323
+ if args.statsd_prefix is not sentinel:
324
+ config.statsd_prefix = args.statsd_prefix
325
+ if args.umask is not sentinel:
326
+ config.umask = args.umask
327
+ if args.user is not sentinel:
328
+ config.user = args.user
329
+ if args.worker_class is not sentinel:
330
+ config.worker_class = args.worker_class
331
+ if args.verify_mode is not sentinel:
332
+ config.verify_mode = args.verify_mode
333
+ if args.websocket_ping_interval is not sentinel:
334
+ config.websocket_ping_interval = args.websocket_ping_interval
335
+ if args.workers is not sentinel:
336
+ config.workers = args.workers
337
+
338
+ if args.cxb_config is not sentinel:
339
+ os.environ["DMART_CXB_CONFIG"] = args.cxb_config
340
+
341
+ if len(args.binds) > 0:
342
+ config.bind = args.binds
343
+ if len(args.insecure_binds) > 0:
344
+ config.insecure_bind = args.insecure_binds
345
+ if len(args.quic_binds) > 0:
346
+ config.quic_bind = args.quic_binds
347
+ if len(args.server_names) > 0:
348
+ config.server_names = args.server_names
349
+
350
+ if args.open_cxb:
351
+ port = 8282
352
+ host = "127.0.0.1"
353
+
354
+ if len(args.binds) > 0:
355
+ try:
356
+ bind_parts = args.binds[0].split(":")
357
+ if len(bind_parts) == 2:
358
+ host = bind_parts[0]
359
+ port = int(bind_parts[1])
360
+ elif len(bind_parts) == 1:
361
+ host = bind_parts[0]
362
+ except Exception as e:
363
+ print(e)
364
+ pass
365
+
366
+ if host == "0.0.0.0":
367
+ host = "127.0.0.1"
368
+
369
+ url = f"http://{host}:{port}{settings.cxb_url}/"
370
+
371
+ def open_browser():
372
+ time.sleep(2)
373
+ webbrowser.open(url)
374
+
375
+ import threading
376
+ threading.Thread(target=open_browser, daemon=True).start()
377
+
378
+ return run(config)
379
+
380
+
381
+ def print_formatted(data):
382
+ if isinstance(data, str):
383
+ try:
384
+ data = json.loads(data)
385
+ except json.JSONDecodeError:
386
+ pass
387
+
388
+ if isinstance(data, (dict, list)):
389
+ output = json.dumps(data, indent=4)
390
+ lexer_name = "json"
391
+ else:
392
+ output = str(data)
393
+ lexer_name = "text"
394
+
395
+ if sys.stdout.isatty():
396
+ try:
397
+ from pygments import highlight, lexers, formatters
398
+ lexer = lexers.get_lexer_by_name(lexer_name)
399
+ print(highlight(output, lexer, formatters.TerminalFormatter()).strip())
400
+ return
401
+ except ImportError:
402
+ pass
403
+
404
+ print(output)
405
+
406
+
407
+ def main():
408
+ sys.argv = sys.argv[1:]
409
+ if len(sys.argv) == 0:
410
+ print("You must provide a command to run:")
411
+ print(commands)
412
+ sys.exit(1)
413
+
414
+ match sys.argv[0]:
415
+ case "hyper":
416
+ hypercorn_main()
417
+ case "cli":
418
+ config_file = None
419
+ if "--config" in sys.argv:
420
+ idx = sys.argv.index("--config")
421
+ if idx + 1 < len(sys.argv):
422
+ config_file = sys.argv[idx + 1]
423
+ sys.argv.pop(idx + 1)
424
+ sys.argv.pop(idx)
425
+
426
+ if not config_file:
427
+ if os.path.exists("cli.ini"):
428
+ config_file = "cli.ini"
429
+ else:
430
+ home_config = Path.home() / ".dmart" / "cli.ini"
431
+ if home_config.exists():
432
+ config_file = str(home_config)
433
+ else:
434
+ try:
435
+ home_config.parent.mkdir(parents=True, exist_ok=True)
436
+
437
+ default_config = ""
438
+ sample_path = Path(__file__).resolve().parent / "config.ini.sample"
439
+ if sample_path.exists():
440
+ with open(sample_path, "r") as f:
441
+ default_config = f.read()
442
+ else:
443
+ default_config = (
444
+ 'url = "http://localhost:8282"\n'
445
+ 'shortname = "dmart"\n'
446
+ 'password = "xxxx"\n'
447
+ 'query_limit = 50\n'
448
+ 'retrieve_json_payload = True\n'
449
+ 'default_space = "management"\n'
450
+ 'pagination = 50\n'
451
+ )
452
+
453
+ login_creds_path = Path.home() / ".dmart" / "login_creds.sh"
454
+ if login_creds_path.exists():
455
+ try:
456
+ with open(login_creds_path, "r") as f:
457
+ creds_content = f.read()
458
+
459
+ match = re.search(r"export SUPERMAN='(.*?)'", creds_content)
460
+ if match:
461
+ creds_json = match.group(1)
462
+ creds = json.loads(creds_json)
463
+ if "shortname" in creds:
464
+ default_config = re.sub(r'shortname = ".*"', f'shortname = "{creds["shortname"]}"', default_config)
465
+ if "password" in creds:
466
+ default_config = re.sub(r'password = ".*"', f'password = "{creds["password"]}"', default_config)
467
+ except Exception as e:
468
+ print(f"Warning: Failed to parse login_creds.sh: {e}")
469
+
470
+ with open(home_config, "w") as f:
471
+ f.write(default_config)
472
+ print(f"Created default config at {home_config}")
473
+ config_file = str(home_config)
474
+ except Exception as e:
475
+ print(f"Warning: Failed to create default config at {home_config}: {e}")
476
+
477
+ if config_file:
478
+ os.environ["BACKEND_ENV"] = config_file
479
+
480
+ last_import_error = None
481
+ try:
482
+ dmart_dir = Path(__file__).resolve().parent
483
+ if str(dmart_dir) not in sys.path:
484
+ sys.path.append(str(dmart_dir))
485
+ import cli # type: ignore
486
+ cli.main()
487
+ return
488
+ except ImportError as e:
489
+ last_import_error = e
490
+ if e.name and e.name != 'cli':
491
+ print(f"Error: Missing dependency for CLI: {e}")
492
+ sys.exit(1)
493
+ except Exception as e:
494
+ print(f"Error: Failed to start CLI: {e}")
495
+ sys.exit(1)
496
+
497
+ cli_path = Path(__file__).resolve().parent.parent / "cli"
498
+ if cli_path.exists():
499
+ sys.path.append(str(cli_path))
500
+ try:
501
+ import cli # type: ignore
502
+ cli.main()
503
+ return
504
+ except ImportError as e:
505
+ last_import_error = e
506
+ if e.name and e.name != 'cli':
507
+ print(f"Error: Missing dependency for CLI: {e}")
508
+ sys.exit(1)
509
+ except Exception as e:
510
+ print(f"Error: Failed to start CLI: {e}")
511
+ sys.exit(1)
512
+
513
+ if last_import_error:
514
+ print(f"Error: Could not load cli.py: {last_import_error}")
515
+ else:
516
+ print("Error: cli.py not found.")
517
+ sys.exit(1)
518
+ case "serve":
519
+ open_cxb = False
520
+ if "--open-cxb" in sys.argv:
521
+ open_cxb = True
522
+ sys.argv.remove("--open-cxb")
523
+
524
+ if "--cxb-config" in sys.argv:
525
+ idx = sys.argv.index("--cxb-config")
526
+ if idx + 1 < len(sys.argv):
527
+ os.environ["DMART_CXB_CONFIG"] = sys.argv[idx + 1]
528
+ sys.argv.pop(idx + 1)
529
+ sys.argv.pop(idx)
530
+
531
+ if open_cxb:
532
+ host = settings.listening_host
533
+ if host == "0.0.0.0":
534
+ host = "127.0.0.1"
535
+ url = f"http://{host}:{settings.listening_port}{settings.cxb_url}/"
536
+ def open_browser():
537
+ time.sleep(2)
538
+ webbrowser.open(url)
539
+
540
+ import threading
541
+ threading.Thread(target=open_browser, daemon=True).start()
542
+
543
+ from main import main as server
544
+ asyncio.run(server())
545
+ case "health-check":
546
+ from data_adapters.file.health_check import main as health_check
547
+ parser = argparse.ArgumentParser(
548
+ description="This created for doing health check functionality",
549
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
550
+ )
551
+ parser.add_argument("-t", "--type", help="type of health check (soft or hard)")
552
+ parser.add_argument("-s", "--space", help="hit the target space or pass (all) to make the full health check")
553
+ parser.add_argument("-m", "--schemas", nargs="*", help="hit the target schema inside the space")
554
+
555
+ args = parser.parse_args()
556
+ before_time = time.time()
557
+ asyncio.run(health_check(args.type, args.space, args.schemas))
558
+ print(f'total time: {"{:.2f}".format(time.time() - before_time)} sec')
559
+ case "create-index":
560
+ from data_adapters.file.create_index import main as create_index
561
+ parser = argparse.ArgumentParser(
562
+ description="Recreate Redis indices based on the available schema definitions",
563
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
564
+ )
565
+ parser.add_argument("-p", "--space", help="recreate indices for this space only")
566
+ parser.add_argument(
567
+ "-c", "--schemas", nargs="*", help="recreate indices for this schemas only"
568
+ )
569
+ parser.add_argument(
570
+ "-s", "--subpaths", nargs="*", help="upload documents for this subpaths only"
571
+ )
572
+ parser.add_argument(
573
+ "--flushall", action='store_true', help="FLUSHALL data on Redis"
574
+ )
575
+
576
+ args = parser.parse_args()
577
+
578
+ asyncio.run(create_index(args.space, args.schemas, args.subpaths, args.flushall))
579
+ case "export":
580
+ from utils.exporter import main as exporter, exit_with_error, OUTPUT_FOLDER_NAME, validate_config, extract
581
+ parser = argparse.ArgumentParser()
582
+ parser.add_argument(
583
+ "--config", required=True, help="Json config relative path from the script"
584
+ )
585
+ parser.add_argument(
586
+ "--spaces", required=True, help="Spaces relative path from the script"
587
+ )
588
+ parser.add_argument(
589
+ "--output",
590
+ help="Output relative path from the script (the default path is the current script path",
591
+ )
592
+ parser.add_argument(
593
+ "--since",
594
+ help="Export entries created/updated since the provided timestamp",
595
+ )
596
+ args = parser.parse_args()
597
+ since = None
598
+ output_path = ""
599
+ if args.output:
600
+ output_path = args.output
601
+
602
+ if args.since:
603
+ since = int(round(float(args.since) * 1000))
604
+
605
+ if not os.path.isdir(args.spaces):
606
+ exit_with_error(f"The spaces folder {args.spaces} is not found.")
607
+
608
+ out_path = os.path.join(output_path, OUTPUT_FOLDER_NAME)
609
+ if os.path.isdir(out_path):
610
+ shutil.rmtree(out_path)
611
+
612
+ tasks = []
613
+ with open(args.config, "r") as f:
614
+ config_objs = json.load(f)
615
+
616
+ for config_obj in config_objs:
617
+ if not validate_config(config_obj):
618
+ continue
619
+ tasks.append(extract(config_obj.get("space", ""),
620
+ config_obj.get("subpath", ""),
621
+ config_obj.get("resource_type", ""),
622
+ config_obj.get("schema_shortname", ""),
623
+ config_obj.get("included_meta_fields", {}),
624
+ config_obj.get("excluded_payload_fields", {}),
625
+ args.spaces, output_path, since))
626
+
627
+ asyncio.run(exporter(tasks))
628
+
629
+ print(
630
+ f"Output path: {os.path.abspath(os.path.join(output_path, OUTPUT_FOLDER_NAME))}"
631
+ )
632
+ case "settings":
633
+ print_formatted(settings.model_dump_json())
634
+ case "set_password":
635
+ import set_admin_passwd # noqa: F401
636
+ case "archive":
637
+ from data_adapters.file.archive import archive
638
+ parser = argparse.ArgumentParser(
639
+ description="Script for archiving records from different spaces and subpaths."
640
+ )
641
+ parser.add_argument("space", type=str, help="The name of the space")
642
+ parser.add_argument("subpath", type=str, help="The subpath within the space")
643
+ parser.add_argument(
644
+ "schema",
645
+ type=str,
646
+ help="The subpath within the space. Optional, if not provided move everything",
647
+ nargs="?",
648
+ )
649
+ parser.add_argument(
650
+ "olderthan",
651
+ type=int,
652
+ help="The number of day, older than which, the entries will be archived (based on updated_at)",
653
+ )
654
+
655
+ args = parser.parse_args()
656
+ space = args.space
657
+ subpath = args.subpath
658
+ olderthan = args.olderthan
659
+ schema = args.schema or "meta"
660
+
661
+ asyncio.run(archive(space, subpath, schema, olderthan))
662
+ print("Done.")
663
+ case "json_to_db":
664
+ from data_adapters.sql.json_to_db_migration import main as json_to_db_migration
665
+ asyncio.run(json_to_db_migration())
666
+ case "db_to_json":
667
+ from data_adapters.sql.db_to_json_migration import main as db_to_json_migration
668
+ db_to_json_migration()
669
+ case "help":
670
+ print("Available commands:")
671
+ print(commands)
672
+ case "version":
673
+ info_json_path = Path(__file__).resolve().parent / "info.json"
674
+ tag = None
675
+ if info_json_path.exists():
676
+ with open(info_json_path) as info:
677
+ tag = json.load(info).get("tag")
678
+ else:
679
+ tag_cmd = "git describe --tags"
680
+ result, _ = subprocess.Popen(tag_cmd.split(" "), stdout=subprocess.PIPE,
681
+ stderr=subprocess.PIPE).communicate()
682
+ tag = None if result is None or len(result) == 0 else result.decode().strip()
683
+
684
+ print(tag)
685
+ case "info":
686
+ info_json_path = Path(__file__).resolve().parent / "info.json"
687
+ if info_json_path.exists():
688
+ with open(info_json_path) as info:
689
+ data = json.load(info)
690
+ else:
691
+ branch_cmd = "git rev-parse --abbrev-ref HEAD"
692
+ result, _ = subprocess.Popen(branch_cmd.split(" "), stdout=subprocess.PIPE,
693
+ stderr=subprocess.PIPE).communicate()
694
+ branch = None if result is None or len(result) == 0 else result.decode().strip()
695
+
696
+ version_cmd = "git rev-parse --short HEAD"
697
+ result, _ = subprocess.Popen(version_cmd.split(" "), stdout=subprocess.PIPE,
698
+ stderr=subprocess.PIPE).communicate()
699
+ version = None if result is None or len(result) == 0 else result.decode().strip()
700
+
701
+ tag_cmd = "git describe --tags"
702
+ result, _ = subprocess.Popen(tag_cmd.split(" "), stdout=subprocess.PIPE,
703
+ stderr=subprocess.PIPE).communicate()
704
+ tag = None if result is None or len(result) == 0 else result.decode().strip()
705
+
706
+ version_date_cmd = "git show --pretty=format:'%ad'"
707
+ result, _ = subprocess.Popen(version_date_cmd.split(" "), stdout=subprocess.PIPE,
708
+ stderr=subprocess.PIPE).communicate()
709
+ version_date = None if result is None or len(result) == 0 else result.decode().split("\n")[0]
710
+
711
+ data = {
712
+ "commit_hash": version,
713
+ "date": version_date,
714
+ "branch": branch,
715
+ "tag": tag
716
+ }
717
+ print_formatted(data)
718
+ case "init":
719
+ sample_spaces_path = Path(__file__).resolve().parent / "sample" / "spaces"
720
+ if not sample_spaces_path.exists():
721
+ print("Error: Sample spaces not found in the package.")
722
+ sys.exit(1)
723
+
724
+ target_path = Path.home() / ".dmart" / "spaces"
725
+
726
+ try:
727
+ if target_path.exists():
728
+ shutil.rmtree(target_path)
729
+ shutil.copytree(sample_spaces_path, target_path)
730
+ print(f"Initialized sample spaces at {target_path}")
731
+ except Exception as e:
732
+ print(f"Error initializing sample spaces: {e}")
733
+ sys.exit(1)
734
+ case "migrate":
735
+ from alembic.config import Config
736
+ from alembic import command
737
+
738
+ dmart_root = Path(__file__).resolve().parent
739
+ alembic_ini_path = dmart_root / "alembic.ini"
740
+ alembic_cfg = Config(str(alembic_ini_path))
741
+ alembic_cfg.set_main_option("script_location", str(dmart_root / "alembic"))
742
+
743
+ if "sqlite" in settings.database_driver:
744
+ db_url = f"{settings.database_driver}:///{settings.database_name}"
745
+ else:
746
+ db_url = f"{settings.database_driver}://{settings.database_username}:{settings.database_password}@{settings.database_host}:{settings.database_port}/{settings.database_name}"
747
+
748
+ alembic_cfg.set_main_option("sqlalchemy.url", db_url)
749
+
750
+ # Add dmart package to sys.path to allow alembic to find models
751
+ sys.path.insert(0, str(dmart_root.parent))
752
+
753
+ try:
754
+ command.upgrade(alembic_cfg, "head")
755
+ print("Database migration completed successfully.")
756
+ except Exception as e:
757
+ print(f"Error during database migration: {e}")
758
+ sys.exit(1)
759
+
760
+ if __name__ == "__main__":
761
+ main()