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/cli.py ADDED
@@ -0,0 +1,1133 @@
1
+ #!/usr/bin/env python
2
+
3
+ import os
4
+ from prompt_toolkit import PromptSession
5
+ import sys
6
+
7
+ from prompt_toolkit.filters import has_completions, completion_is_selected
8
+ from prompt_toolkit.key_binding import KeyBindings
9
+ from rich import pretty
10
+ from rich import print
11
+ from rich.console import Console
12
+ from pydantic_settings import BaseSettings, SettingsConfigDict
13
+ import requests
14
+ import re
15
+
16
+ # from rich.tree import Tree
17
+ from rich.table import Table
18
+ from dataclasses import dataclass
19
+ from prompt_toolkit.styles import Style
20
+ from prompt_toolkit.formatted_text import HTML
21
+ from prompt_toolkit.completion import Completer, Completion # , FuzzyCompleter
22
+ from prompt_toolkit.history import FileHistory
23
+ from prompt_toolkit.cursor_shapes import CursorShape
24
+ from rich.traceback import install
25
+ import json
26
+ import pathlib
27
+ from enum import Enum
28
+ import termios
29
+ import tty
30
+ from dataclasses import field
31
+ from pathlib import Path
32
+
33
+ install(show_locals=False)
34
+
35
+ KEYWORDS = [
36
+ "ls",
37
+ "switch",
38
+ "mv",
39
+ "cat",
40
+ "cd",
41
+ "rm",
42
+ "print",
43
+ "pwd",
44
+ "help",
45
+ "mkdir",
46
+ "schema",
47
+ "create",
48
+ "attach",
49
+ "request",
50
+ "csv",
51
+ "progress",
52
+ ]
53
+
54
+ style = Style.from_dict(
55
+ {
56
+ "completion-menu.completion": "bg:#008888 #ffffff",
57
+ "completion-menu.completion.current": "bg:#00aaaa #000000",
58
+ "scrollbar.background": "bg:#88aaaa",
59
+ "scrollbar.button": "bg:#222222",
60
+ "prompt": "#dddd22 bold",
61
+ }
62
+ )
63
+
64
+ console = Console()
65
+ pretty.install()
66
+
67
+
68
+ class Settings(BaseSettings):
69
+ url: str = "http://localhost:8282"
70
+ shortname: str = "dmart"
71
+ password: str = "xxxx"
72
+ query_limit: int = 50
73
+ retrieve_json_payload: bool = True
74
+ default_space: str = "management"
75
+ pagination: int = 50
76
+
77
+ model_config = SettingsConfigDict(env_file = os.getenv("BACKEND_ENV", os.path.dirname(os.path.realpath(__file__)) + "/cli.ini"), env_file_encoding = "utf-8")
78
+
79
+
80
+ settings = Settings()
81
+
82
+
83
+ class CLI_MODE(str, Enum):
84
+ REPL = "REPL"
85
+ CMD = "CMD"
86
+ SCRIPT = "SCRIPT"
87
+
88
+
89
+ mode = CLI_MODE.REPL
90
+
91
+
92
+ class SpaceManagmentType(str, Enum):
93
+ CREATE = "create"
94
+ UPDATE = "update"
95
+ DELETE = "delete"
96
+
97
+
98
+ @dataclass
99
+ class DMart:
100
+ session = requests.Session()
101
+ headers = {"Content-Type": "application/json"}
102
+ dmart_spaces : list = field(default_factory=lambda: [])
103
+ space_names : list[str] = field(default_factory=list[str])
104
+ current_space: str = settings.default_space
105
+ current_subpath: str = "/"
106
+ current_subpath_entries : list = field(default_factory=list)
107
+
108
+ def __dmart_api(self, endpoint, json=None):
109
+ url = f"{settings.url}{endpoint}"
110
+
111
+ if json:
112
+ response = self.session.post(url, headers=self.headers, json=json)
113
+ else:
114
+ response = self.session.get(url)
115
+
116
+ response_body = response.json()
117
+ if response.status_code != 200:
118
+ print(f"[red]{endpoint}", end="\r")
119
+ return response_body
120
+
121
+ def create_content(self, endpoint, json):
122
+ url = f"{settings.url}{endpoint}"
123
+
124
+ response = self.session.post(url, headers=self.headers, json=json)
125
+
126
+ if response.status_code != 200:
127
+ print(endpoint, response.json())
128
+ return response.json().get('status', None)
129
+
130
+ def delete(self, spacename, subpath, shortname, resource_type):
131
+ endpoint = "/managed/request"
132
+ json = {
133
+ "space_name": spacename,
134
+ "request_type": "delete",
135
+ "records": [
136
+ {
137
+ "resource_type": resource_type,
138
+ "subpath": subpath,
139
+ "shortname": shortname,
140
+ "attributes": {},
141
+ }
142
+ ],
143
+ }
144
+ return self.__dmart_api(endpoint, json)
145
+
146
+ def register(self, invitation):
147
+ json = {
148
+ "resource_type": "user",
149
+ "spacename": "management",
150
+ "subpath": "/users",
151
+ "shortname": settings.shortname,
152
+ "attributes": {"invitation": invitation, "password": settings.password},
153
+ }
154
+ self.__dmart_api("/user/create", json)
155
+
156
+ def login(self):
157
+ json = {"shortname": settings.shortname, "password": settings.password}
158
+ response = self.__dmart_api("/user/login", json)
159
+ if response["status"] == "success":
160
+ self.headers = {
161
+ **self.headers,
162
+ "Authorization": f'Bearer {response["records"][0]["attributes"]["access_token"]}',
163
+ }
164
+ return response
165
+
166
+ def profile(self):
167
+ self.__dmart_api("/user/profile")
168
+
169
+ def spaces(self, force: bool = False):
170
+ if force or not self.dmart_spaces:
171
+ json = {
172
+ "type": "spaces",
173
+ "space_name": "management",
174
+ "subpath": "/",
175
+ }
176
+
177
+ response = self.__dmart_api("/managed/query", json)
178
+ self.dmart_spaces = response["records"]
179
+ self.space_names = [one["shortname"] for one in self.dmart_spaces]
180
+ return self.dmart_spaces
181
+
182
+ def query(self, json):
183
+ json["limit"] = settings.query_limit
184
+ json["retrieve_json_payload"] = settings.retrieve_json_payload
185
+ return self.__dmart_api("/managed/query", json)
186
+
187
+ def meta(self, resource_type, space_name, subpath, shortname):
188
+ endpoint = "managed/meta"
189
+ url = f"{settings.url}/{endpoint}/{resource_type}/{space_name}/{subpath}/{shortname}"
190
+ response = self.session.get(url)
191
+
192
+ if response.status_code != 200:
193
+ print(endpoint, response.json())
194
+ return response.json()
195
+
196
+ def payload(self, resource_type, space_name, subpath, shortname):
197
+ endpoint = "managed/payload"
198
+ url = f"{settings.url}/{endpoint}/{resource_type}/{space_name}/{subpath}/{shortname}.json"
199
+ response = self.session.get(url)
200
+
201
+ # if response.status_code != 200:
202
+ # print(endpoint, response.json())
203
+ return response.status_code, response.json()
204
+
205
+ def print_spaces(self):
206
+ print_spaces = "Available spaces: "
207
+ for one in self.space_names:
208
+ if self.current_space == one:
209
+ one = f" [bold yellow]{one}[/] "
210
+ else:
211
+ one = f" [blue]{one}[/] "
212
+ print_spaces += one
213
+ print(print_spaces)
214
+
215
+ def list(self):
216
+ json = {
217
+ "space_name": dmart.current_space,
218
+ "type": "subpath",
219
+ "subpath": dmart.current_subpath.replace("//", "/"),
220
+ "retrieve_json_payload": True,
221
+ "limit": 100,
222
+ }
223
+
224
+ ret = self.query(json)
225
+ self.current_subpath_entries.clear()
226
+ if "records" in ret:
227
+ for one in ret["records"]:
228
+ self.current_subpath_entries.append(one)
229
+
230
+ def get_mime_type(self, ext):
231
+ match ext:
232
+ case ".jfif" | ".jfif-tbnl" | ".jpe" | ".jpeg" | ".jpg":
233
+ return "image/jpeg"
234
+ case ".png":
235
+ return "image/png"
236
+ case ".json":
237
+ return "application/json"
238
+
239
+ def create_folder(self, shortname):
240
+ json = {
241
+ "space_name": self.current_space,
242
+ "request_type": "create",
243
+ "records": [
244
+ {
245
+ "resource_type": "folder",
246
+ "subpath": self.current_subpath,
247
+ "shortname": shortname,
248
+ "attributes": {"is_active": True},
249
+ }
250
+ ],
251
+ }
252
+ endpoint = "/managed/request"
253
+ return self.__dmart_api(endpoint, json)
254
+
255
+ def manage_space(self, spacename, mode: SpaceManagmentType):
256
+ endpoint = "/managed/space"
257
+ json = {
258
+ "space_name": spacename,
259
+ "request_type": mode.value,
260
+ "records": [
261
+ {
262
+ "resource_type": "space",
263
+ "subpath": "/",
264
+ "shortname": spacename,
265
+ "attributes": {},
266
+ }
267
+ ],
268
+ }
269
+ result = self.__dmart_api(endpoint, json)
270
+ self.spaces(force=True)
271
+ return result
272
+
273
+ def create_entry(self, shortname, resource_type):
274
+ endpoint = "/managed/request"
275
+ json = {
276
+ "space_name": self.current_space,
277
+ "request_type": "create",
278
+ "records": [
279
+ {
280
+ "resource_type": resource_type,
281
+ "subpath": self.current_subpath,
282
+ "shortname": shortname,
283
+ "attributes": {"is_active": True},
284
+ }
285
+ ],
286
+ }
287
+ return self.__dmart_api(endpoint, json)
288
+
289
+ def create_attachments(self, request_record: dict, payload_file):
290
+ endpoint = f"{settings.url}/managed/resource_with_payload"
291
+ with open("temp.json", "w") as request_record_file:
292
+ json.dump(request_record, request_record_file)
293
+
294
+ with open("temp.json", "rb") as request_file:
295
+ with open(payload_file, "rb") as media_file:
296
+ request_file.seek(0)
297
+ data = [
298
+ (
299
+ "request_record",
300
+ ("record.json", request_file, "application/json"),
301
+ ),
302
+ (
303
+ "payload_file",
304
+ (
305
+ media_file.name.split("/")[-1],
306
+ media_file,
307
+ self.get_mime_type(pathlib.Path(payload_file).suffix),
308
+ ),
309
+ ),
310
+ ]
311
+ response = self.session.post(
312
+ endpoint,
313
+ data={"space_name": self.current_space},
314
+ files=data,
315
+ headers=self.headers,
316
+ )
317
+ if response.status_code != 200:
318
+ print(endpoint, response.json())
319
+
320
+ os.remove("temp.json")
321
+ return response.json()
322
+
323
+ def upload_csv(self, resource_type, subpath, schema_shortname, payload_file):
324
+ with open(payload_file, "rb") as media_file:
325
+ endpoint = f"{settings.url}/managed/resources_from_csv/{resource_type}/{dmart.current_space}/{subpath}/{schema_shortname}"
326
+ headers = {**self.headers}
327
+ del headers["Content-Type"]
328
+ response = self.session.post(
329
+ endpoint,
330
+ files=[
331
+ ('resources_file', ('file', media_file, 'text/csv'))
332
+ ],
333
+ headers=headers,
334
+ )
335
+ if response.status_code != 200:
336
+ print(endpoint, response.json())
337
+
338
+ return response.json()
339
+
340
+ def upload_schema(self, shortname, payload_file_path):
341
+ data = {
342
+ "resource_type": "schema",
343
+ "subpath": "schema",
344
+ "shortname": shortname,
345
+ "attributes": {"schema_shortname": "meta_schema", "is_active": True},
346
+ }
347
+ endpoint = f"{settings.url}/managed/resource_with_payload"
348
+
349
+ with open("temp.json", "w") as request_record_file:
350
+ json.dump(data, request_record_file)
351
+
352
+ with open("temp.json", "rb") as request_record:
353
+ with open(payload_file_path, "rb") as payload_file:
354
+ files = {
355
+ "space_name": (None, self.current_space),
356
+ "request_record": request_record,
357
+ "payload_file": payload_file,
358
+ }
359
+ headers = {**self.headers}
360
+ del headers["Content-Type"]
361
+ response = self.session.post(
362
+ endpoint,
363
+ files=files,
364
+ headers=headers,
365
+ )
366
+
367
+ if response.status_code != 200:
368
+ print(endpoint, response.json())
369
+
370
+ return response.json()
371
+
372
+ def upload_folder(self, folder_schema_path):
373
+ endpoint = f"{settings.url}/managed/request"
374
+ with open(folder_schema_path, "r") as folder_schema:
375
+ response = self.session.post(
376
+ url=endpoint,
377
+ data=folder_schema,
378
+ headers=self.headers,
379
+ )
380
+ if response.status_code != 200:
381
+ print(endpoint, response.json())
382
+ else:
383
+ print(response.json())
384
+ return response.json()
385
+
386
+ def move(
387
+ self,
388
+ resource_type,
389
+ source_path,
390
+ source_shortname,
391
+ destination_path,
392
+ destination_shortname,
393
+ ):
394
+ endpoint = "/managed/request"
395
+ data = {
396
+ "space_name": self.current_space,
397
+ "request_type": "move",
398
+ "records": [
399
+ {
400
+ "resource_type": resource_type,
401
+ "subpath": self.current_subpath,
402
+ "shortname": source_shortname,
403
+ "attributes": {
404
+ "src_subpath": source_path,
405
+ "src_shortname": source_shortname,
406
+ "dest_subpath": destination_path,
407
+ "dest_shortname": destination_shortname,
408
+ },
409
+ }
410
+ ],
411
+ }
412
+ return self.__dmart_api(endpoint, data)
413
+
414
+ def import_zip(self, zip_file_path):
415
+ endpoint = f"{settings.url}/managed/import"
416
+ with open(zip_file_path, "rb") as zip_file:
417
+ headers = {**self.headers}
418
+ del headers["Content-Type"]
419
+ response = self.session.post(
420
+ endpoint,
421
+ files={"zip_file": zip_file},
422
+ headers=headers,
423
+ )
424
+ if response.status_code != 200:
425
+ print(endpoint, response.json())
426
+ return response.json()
427
+
428
+ def export_json(self, query_json_file):
429
+ output_file_name = "/export.zip"
430
+ os_downloads_path = str(Path.home()/"Downloads")
431
+ output_file_path = os_downloads_path + output_file_name
432
+ with open(query_json_file, "r") as f:
433
+ data = json.load(f)
434
+ endpoint = f"{settings.url}/managed/export"
435
+ response = self.session.post(endpoint, headers=self.headers, json=data, stream=True)
436
+ if response.status_code != 200:
437
+ print(endpoint, response.json())
438
+ return response.json()
439
+ with open(output_file_path, "wb") as out_file:
440
+ for chunk in response.iter_content(chunk_size=8192):
441
+ if chunk:
442
+ out_file.write(chunk)
443
+ print(f"Exported to {os_downloads_path}")
444
+ return {"status": "success", "file": output_file_path}
445
+
446
+
447
+ dmart = DMart()
448
+
449
+
450
+ class CustomCompleter(Completer):
451
+ def get_completions(self, document, complete_event):
452
+ cmd = document.text
453
+ arg = document.get_word_under_cursor()
454
+ if len(cmd) < 2 or re.match(r"^\s*$", cmd):
455
+ for one in KEYWORDS:
456
+ if one.startswith(arg):
457
+ yield Completion(one, start_position=-len(arg))
458
+ elif re.match(r"^\s*\w+\s+", cmd):
459
+ if cmd.startswith("s"):
460
+ for one in dmart.space_names:
461
+ if one.startswith(arg):
462
+ yield Completion(one, start_position=-len(arg))
463
+ else:
464
+ for one in dmart.current_subpath_entries:
465
+ if one[ "shortname" ].startswith(
466
+ arg
467
+ ):
468
+ if "cd" in cmd and one["resource_type"] == "folder":
469
+ yield Completion(
470
+ one["shortname"],
471
+ start_position=-len(arg),
472
+ display_meta=one["resource_type"],
473
+ )
474
+ elif "cd" not in cmd:
475
+ yield Completion(
476
+ one["shortname"],
477
+ start_position=-len(arg),
478
+ display_meta=one["resource_type"],
479
+ )
480
+
481
+
482
+
483
+ def bottom_toolbar():
484
+ return HTML(
485
+ f'<b>{dmart.current_space}</b> : <b><style bg="ansired">{dmart.current_subpath}</style></b>'
486
+ )
487
+
488
+
489
+ def check_update_space(space, subpath=None):
490
+ for one in dmart.space_names:
491
+ if one.startswith(space) and not one.startswith(dmart.current_space):
492
+ dmart.current_space = one
493
+ print("Current space switched to:", dmart.current_space)
494
+ if subpath is not None:
495
+ dmart.current_subpath = subpath
496
+ dmart.list()
497
+ dmart.print_spaces()
498
+ break
499
+
500
+
501
+ def action(text: str):
502
+ old_space, old_subpath = dmart.current_space, dmart.current_subpath
503
+ match text.split():
504
+ case ["h" | "help" | "?"]:
505
+ table = Table(title="Help")
506
+ table.add_column("Command")
507
+ table.add_column("Description")
508
+ table.add_row(
509
+ r"[blue]s[paces][/] [green]\[space_name][/]",
510
+ "List availble spaces or switch to space",
511
+ )
512
+ table.add_row(
513
+ r"[blue]ls[/] [green]\[folder_name][/]",
514
+ "List entries under current subpath",
515
+ )
516
+ table.add_row("[blue]pwd[/]", "Print current subpath")
517
+ table.add_row("[blue]cd[/] [green]folder_name[/]", "Enter the folder")
518
+ table.add_row("[blue]cd ..[/]", "Go one-level up with the subpath")
519
+ table.add_row(
520
+ r"[blue]p\[rint][/blue] [green]shortname[/]",
521
+ "Print meta data for the entry shortname under current subpath",
522
+ )
523
+ table.add_row(
524
+ r"[blue]c\[at][/] [green]shortname[/]",
525
+ "Print the json payload (only) for th entry shortnae under current subpath",
526
+ )
527
+ table.add_row(
528
+ "[blue]rm[/] [green]shortname|*[/]",
529
+ "Delete the shortname (entry or attachment)",
530
+ )
531
+ table.add_row(
532
+ "[blue]create [space|folder] <shortname>[/]", "Create space/folder for current space"
533
+ )
534
+ table.add_row(
535
+ "[blue]upload csv <resource_type> <shortname> <schema_shortname> <csv_file>[/]",
536
+ "Upload data to the current space with schema validation",
537
+ )
538
+ table.add_row(
539
+ "[blue]upload schema <shortname> <json_file>[/]",
540
+ "Upload schema to the current space",
541
+ )
542
+ table.add_row(
543
+ "[blue]request <resource_type> <json_file>[/]",
544
+ "Add/Manage a resource to/in the space",
545
+ )
546
+ table.add_row(
547
+ "[blue]progress <subpath> <shortname> <action>[/]",
548
+ "Progress a ticket into a new state using an action",
549
+ )
550
+ table.add_row(
551
+ "[blue]move <resource_type> <source> <destination>[/]", "Move resource"
552
+ )
553
+ table.add_row("[blue]import <zip_file>[/]", "Import a ZIP file")
554
+ table.add_row("[blue]export <query_json> [/]", "Export a ZIP file")
555
+ table.add_row("[blue]exit|Ctrl+d[/]", "Exit the app")
556
+ table.add_row("[blue]help|h|?[/]", "Show this help")
557
+ print(table)
558
+ return None
559
+ case ["mkdir", dir_shortname]:
560
+ print(dmart.create_folder(dir_shortname))
561
+ return None
562
+ case ["attach", *args]:
563
+ shortname = None
564
+ entry_shortname = None
565
+ payload_file = None
566
+ payload_type = None
567
+
568
+ shortname = args[0]
569
+ entry_shortname = args[1]
570
+ payload_type = args[2]
571
+ payload_file = args[3]
572
+
573
+ print(
574
+ dmart.create_attachments(
575
+ {
576
+ "shortname": shortname,
577
+ "resource_type": payload_type,
578
+ "subpath": f"{dmart.current_subpath}/{entry_shortname}",
579
+ "attributes": {"is_active": True},
580
+ },
581
+ payload_file,
582
+ )
583
+ )
584
+ return None
585
+ case ["upload", "schema", *args]:
586
+ shortname = None
587
+ payload_file = None
588
+
589
+ if len(args) == 3:
590
+ search = re.search(r"@\w+", args[2])
591
+ if not search:
592
+ print("[red]Malformated Command")
593
+ return None
594
+ space = search.group()
595
+ space = space.replace("@", "")
596
+ check_update_space(space)
597
+ dmart.current_subpath = args[2].replace(f"@{space}/", "")
598
+ dmart.list()
599
+ shortname = args[0]
600
+ payload_file = args[1]
601
+
602
+ dmart.upload_schema(shortname, payload_file)
603
+ check_update_space(old_space)
604
+ dmart.current_subpath = old_subpath
605
+ dmart.list()
606
+ return None
607
+ case ["create", *args]:
608
+ shortname = None
609
+ resource_type = None
610
+ if len(args) == 3:
611
+ search = re.search(r"@\w+", args[2])
612
+ if not search:
613
+ print("[red]Malformated Command")
614
+ return None
615
+ space = search.group()
616
+ space = space.replace("@", "")
617
+ check_update_space(space)
618
+ dmart.current_subpath = args[2].replace(f"@{space}", "")
619
+ dmart.list()
620
+ shortname = args[0]
621
+ resource_type = args[1]
622
+
623
+ if args[0] == "space":
624
+ print(dmart.manage_space(args[1], SpaceManagmentType.CREATE))
625
+ else:
626
+ print(dmart.create_entry(resource_type, shortname))
627
+
628
+ check_update_space(old_space)
629
+ dmart.current_subpath = old_subpath
630
+ dmart.list()
631
+ return None
632
+ case ["move", type, source, destination]:
633
+ if not source.startswith("/"):
634
+ source += f"{dmart.current_subpath}/{source}"
635
+ if not destination.startswith("/"):
636
+ destination += f"{dmart.current_subpath}/{destination}"
637
+ source_path = "/".join(source.split("/")[:-1])
638
+ source_shortname = source.split("/")[-1]
639
+ destination_path = "/".join(destination.split("/")[:-1])
640
+ destination_shortname = destination.split("/")[-1]
641
+ print(
642
+ dmart.move(
643
+ type,
644
+ source_path,
645
+ source_shortname,
646
+ destination_path,
647
+ destination_shortname,
648
+ )
649
+ )
650
+ return None
651
+
652
+ case ["progress", ticket_subpath, ticket_shortname, new_state]:
653
+ endpoint = f"{settings.url}/managed/progress-ticket/{dmart.current_space}/{ticket_subpath}/{ticket_shortname}/{new_state}"
654
+ response = dmart.session.put(
655
+ url=endpoint,
656
+ data={},
657
+ headers=dmart.headers,
658
+ )
659
+ print(response.json())
660
+ return None
661
+ case ["request", *args]:
662
+ if len(args) != 1:
663
+ print("[red]Malformated Command")
664
+ return None
665
+
666
+ with open(args[0]) as f:
667
+ return print(
668
+ dmart.create_content("/managed/request", json.load(f)), end="\r"
669
+ )
670
+
671
+ check_update_space(old_space)
672
+ dmart.current_subpath = old_subpath
673
+ dmart.list()
674
+ return None
675
+ case ["query", shortname]:
676
+ action(f"query {shortname}")
677
+ action("ls")
678
+ action("cd ..")
679
+ return None
680
+ case ["upload", "csv", *args]:
681
+ if len(args) == 4:
682
+ print(dmart.upload_csv(args[0], args[1], args[2], args[3]))
683
+ elif len(args) == 3:
684
+ print("[red]Malformated Command")
685
+ return None
686
+ check_update_space(old_space)
687
+ dmart.current_subpath = old_subpath
688
+ dmart.list()
689
+ return None
690
+ case ["rm", "*"]:
691
+ dmart.list()
692
+ for one in dmart.current_subpath_entries:
693
+ shortname = one["shortname"]
694
+ resource_type = one["resource_type"]
695
+ if shortname and resource_type:
696
+ print(
697
+ shortname,
698
+ dmart.delete(
699
+ dmart.current_space,
700
+ dmart.current_subpath,
701
+ shortname,
702
+ resource_type,
703
+ ),
704
+ )
705
+ return None
706
+ case ["rm", *content]:
707
+ if content[0] == "space":
708
+ print(dmart.manage_space(content[1], SpaceManagmentType.DELETE))
709
+ else:
710
+ content = content[0]
711
+ if content.startswith("@"):
712
+ path = content[1]
713
+ search = re.search(r"@\w+", content)
714
+ if not search:
715
+ print("[red]Malformated Command")
716
+ return None
717
+ space = search.group()
718
+ space = space.replace("@", "")
719
+ check_update_space(space)
720
+ dmart.list()
721
+ content = content.replace(f"@{space}/", "")
722
+ # print(dmart.current_subpath_entries)
723
+ shortname = ""
724
+ resource_type = ""
725
+ for one in dmart.current_subpath_entries:
726
+ if one["shortname"] == content:
727
+ shortname = one["shortname"]
728
+ resource_type = one["resource_type"]
729
+ if shortname and resource_type:
730
+ print(
731
+ dmart.delete(
732
+ dmart.current_space,
733
+ dmart.current_subpath,
734
+ shortname,
735
+ resource_type,
736
+ )
737
+ )
738
+ else:
739
+ print("item not found")
740
+ check_update_space(old_space)
741
+ dmart.list()
742
+ case ["pwd"]:
743
+ print(f"{dmart.current_space}:{dmart.current_subpath}")
744
+ return None
745
+ case ["cd"]:
746
+ dmart.current_subpath = "/"
747
+ dmart.list()
748
+ print(f"[yellow]Switched subpath to:[/] [green]{dmart.current_subpath}[/]")
749
+ return None
750
+ case ["cd", ".."]:
751
+ if dmart.current_subpath != "/":
752
+ dmart.current_subpath = "/".join(dmart.current_subpath.split("/")[:-1])
753
+ if not dmart.current_subpath:
754
+ dmart.current_subpath = "/"
755
+ dmart.list()
756
+ print(f"[yellow]Switched subpath to:[/] [green]{dmart.current_subpath}[/]")
757
+ return None
758
+ case ["p" | "print", content]:
759
+ shortname = ""
760
+ resource_type = ""
761
+ shortname = content
762
+ for one in dmart.current_subpath_entries:
763
+ if one["shortname"].startswith(shortname):
764
+ shortname = one["shortname"]
765
+ resource_type = one["resource_type"]
766
+ if shortname and resource_type:
767
+ print(
768
+ dmart.meta(
769
+ resource_type,
770
+ dmart.current_space,
771
+ dmart.current_subpath,
772
+ shortname,
773
+ )
774
+ )
775
+ else:
776
+ print("item not found")
777
+ case ["cd", directory]:
778
+ if directory.startswith("@"):
779
+ search = re.search(r"@\w+", directory)
780
+ if not search:
781
+ print("[red]Malformated Command")
782
+ return None
783
+ space = search.group()
784
+ space = space.replace("@", "")
785
+ check_update_space(space)
786
+ dmart.current_subpath = directory.replace(f"@{space}/", "")
787
+ dmart.list()
788
+ directory = dmart.current_subpath
789
+ new_subpath = ""
790
+ for one in dmart.current_subpath_entries:
791
+ if (
792
+ one["shortname"].startswith(directory)
793
+ and one["resource_type"] == "folder"
794
+ ):
795
+ new_subpath = (
796
+ ""
797
+ if dmart.current_subpath == "/" or dmart.current_subpath == ""
798
+ else dmart.current_subpath
799
+ )
800
+ if new_subpath != "":
801
+ new_subpath += "/"
802
+ new_subpath += one["shortname"]
803
+ dmart.current_subpath = new_subpath
804
+ dmart.list()
805
+ print(
806
+ f"[yellow]Switched subpath to:[/] [green]{dmart.current_subpath}[/]"
807
+ )
808
+ break
809
+ return None
810
+ return None
811
+ case ["c" | "cat", *extra_shortname]:
812
+ old_path = dmart.current_subpath
813
+ if "/" in extra_shortname[0]:
814
+ dmart.current_subpath = "/".join(extra_shortname[0].split("/")[:-1])
815
+ extra_shortname[0] = "".join(extra_shortname[0].split("/")[-1])
816
+ dmart.list()
817
+ dmart.current_subpath = old_path
818
+
819
+ record = {}
820
+ if extra_shortname[0] == "*":
821
+ for one in dmart.current_subpath_entries:
822
+ print(one)
823
+ elif len(extra_shortname) > 0:
824
+ shortname = extra_shortname[0]
825
+ for one in dmart.current_subpath_entries:
826
+ if one["shortname"].startswith(shortname):
827
+ record = one
828
+ if record is not None:
829
+ print(record)
830
+ else:
831
+ print("[yellow]Item is not found[/]")
832
+ case ["ls", *_extra_subpath]:
833
+ if len(_extra_subpath) >= 2:
834
+ print("Too many args passed !")
835
+ return None
836
+
837
+ extra_subpath = ""
838
+ if len(_extra_subpath) == 1 and not _extra_subpath[0].isnumeric():
839
+ if _extra_subpath[0].startswith("/"):
840
+ _extra_subpath[0] = _extra_subpath[0][1:]
841
+ if _extra_subpath[0].endswith("/"):
842
+ _extra_subpath[0] = _extra_subpath[0][:-1]
843
+
844
+ if _extra_subpath[0].startswith("@"):
845
+ search = re.search(r"@\w+", _extra_subpath[0])
846
+ if not search:
847
+ print("[red]Malformated Command")
848
+ return None
849
+ space = search.group()
850
+ space = space.replace("@", "")
851
+ check_update_space(space)
852
+ dmart.current_subpath = _extra_subpath[0].replace(f"@{space}/", "")
853
+ dmart.list()
854
+ else:
855
+ dmart.current_subpath = _extra_subpath[0]
856
+ dmart.list()
857
+
858
+
859
+ if extra_subpath == "":
860
+ for one in dmart.current_subpath_entries:
861
+ if one["shortname"].startswith(extra_subpath):
862
+ extra_subpath = one["shortname"]
863
+
864
+ path = f"[yellow]{dmart.current_space}[/]:[blue]{dmart.current_subpath}"
865
+ if dmart.current_subpath != "/":
866
+ path = f"{path}/{extra_subpath}"
867
+ else:
868
+ path = f"{path}{extra_subpath}"
869
+ # tree = Tree(path)
870
+
871
+ pagination_length = 0
872
+ if len(_extra_subpath) >= 1 and _extra_subpath[-1].isnumeric():
873
+ pagination_length = int(_extra_subpath[-1])
874
+ else:
875
+ pagination_length = settings.pagination
876
+
877
+ pagination_bucket : list[list] = []
878
+ bucket = []
879
+ idx = 0
880
+ for one in dmart.current_subpath_entries:
881
+ icon = ":page_facing_up:"
882
+ extra = ""
883
+ if one["resource_type"] == "folder":
884
+ icon = ":file_folder:"
885
+ if (
886
+ isinstance(one, dict)
887
+ and "attributes" in one
888
+ and isinstance(one["attributes"], dict)
889
+ and "payload" in one["attributes"]
890
+ and isinstance(one["attributes"]["payload"], dict)
891
+ and "content_type" in one["attributes"]["payload"]
892
+ ):
893
+ if "schema_shortname" in one["attributes"]["payload"]:
894
+ schema = f",schema= {one["attributes"]["payload"].get("schema_shortname", "N/A")}"
895
+ extra = f"[yellow](payload:type={one['attributes']['payload']['content_type']}{schema})[/]"
896
+
897
+ idx += 1
898
+ bucket.append(f"{icon} [green]{one['shortname']}[/] {extra}")
899
+ if idx == pagination_length:
900
+ idx = 0
901
+ pagination_bucket.append(bucket)
902
+ bucket = []
903
+
904
+ if len(bucket) != 0:
905
+ pagination_bucket.append(bucket)
906
+ idx = 0
907
+ c = ""
908
+ if len(pagination_bucket) == 1:
909
+ for bucket in pagination_bucket[0]:
910
+ print(bucket)
911
+ else:
912
+ while True:
913
+ if len(pagination_bucket) == 0:
914
+ break
915
+
916
+ for bucket in pagination_bucket[idx]:
917
+ print(bucket)
918
+
919
+ if idx >= len(pagination_bucket) - 1:
920
+ break
921
+
922
+ print("q: quite, n: next")
923
+ fd = sys.stdin.fileno()
924
+ old_settings = termios.tcgetattr(fd)
925
+ try:
926
+ tty.setraw(fd)
927
+ c = sys.stdin.readline(1)
928
+
929
+ if c == "q":
930
+ break
931
+ if c == "n" or c == "\r":
932
+ idx += 1
933
+ finally:
934
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
935
+ # c = input("q: quite, b: previous, n: next = ")
936
+ # print(tree)
937
+ dmart.current_space, dmart.current_subpath = old_space, old_subpath
938
+ dmart.list()
939
+ return None
940
+ case ["s" | "switch", *space]:
941
+ if len(space) == 0:
942
+ dmart.print_spaces()
943
+ return None
944
+ match = False
945
+ for one in dmart.space_names:
946
+ if space and one.startswith(space[0]):
947
+ print(
948
+ f"Switching current space from {dmart.current_space} to {one} / {space}"
949
+ )
950
+ dmart.current_space = one
951
+ dmart.list()
952
+ match = True
953
+ dmart.print_spaces()
954
+ break
955
+ if not match:
956
+ print(f"Requested space {space} not found")
957
+ return None
958
+ return None
959
+ case ["import", zip_file]:
960
+ print(dmart.import_zip(zip_file))
961
+ return None
962
+ case ["export", query_json_file]:
963
+ print(dmart.export_json(query_json_file))
964
+ return None
965
+ case _:
966
+ print(f"[red]Command[/] [yello]{text}[/] [red]unknown[/]")
967
+ return None
968
+
969
+
970
+ var : dict = {}
971
+
972
+
973
+ def parsing_variables(sliced_command):
974
+ for i in range(len(sliced_command)):
975
+ search = re.search(r"\$\w*", sliced_command[i])
976
+ if search is not None:
977
+ if v := search[0]:
978
+ sliced_command[i] = sliced_command[i].replace(v, var.get(v, ""))
979
+ return sliced_command
980
+
981
+
982
+ key_bindings = KeyBindings()
983
+ filter = has_completions & ~completion_is_selected
984
+ @key_bindings.add("enter", filter=filter)
985
+ def _(event):
986
+ event.current_buffer.go_to_completion(0)
987
+ event.current_buffer.validate_and_handle()
988
+
989
+
990
+ def main():
991
+ try:
992
+ # print(Panel.fit("For help, type : [bold]?[/]", title="DMart Cli"))
993
+ print("[bold][green]DMART[/] [yellow]Command line interface[/][/]")
994
+ print(
995
+ f"Connecting to [yellow]{settings.url}[/] user: [yellow]{settings.shortname}[/]"
996
+ )
997
+
998
+ ret = dmart.login()
999
+ if ret["status"] == "failed":
1000
+ print("Login failed")
1001
+ exit(1)
1002
+ dmart.profile()
1003
+ spaces = dmart.spaces()
1004
+ dmart.current_space = settings.default_space # dmart.space_names[0]
1005
+
1006
+ dmart.list()
1007
+ # print("Available spaces:", space_names)
1008
+ # print("Current space:", current_space)
1009
+ dmart.print_spaces()
1010
+ print("[red]Type [bold]?[/] for help[/]")
1011
+ # current_subpath = "/"
1012
+ # session = PromptSession(lexer=PygmentsLexer(DmartLexer), completer=dmart_completer, style=style)
1013
+
1014
+ session = PromptSession(
1015
+ style=style,
1016
+ completer=CustomCompleter(),
1017
+ history=FileHistory(".cli_history"),
1018
+ key_bindings=key_bindings
1019
+ )
1020
+
1021
+ global mode
1022
+ if len(sys.argv) >= 2:
1023
+ if sys.argv[1] == "s":
1024
+ mode = CLI_MODE.SCRIPT
1025
+ elif sys.argv[1] == "c":
1026
+ mode = CLI_MODE.CMD
1027
+ if sys.argv[3].startswith("/"):
1028
+ check_update_space(sys.argv[2], sys.argv[3])
1029
+ del sys.argv[2]
1030
+ del sys.argv[2]
1031
+ else:
1032
+ check_update_space(sys.argv[2])
1033
+ del sys.argv[2]
1034
+ del sys.argv[0]
1035
+ del sys.argv[0]
1036
+ elif sys.argv[1] == "cli":
1037
+ # When called via 'dmart cli ...'
1038
+ if len(sys.argv) >= 3:
1039
+ if sys.argv[2] == "s":
1040
+ mode = CLI_MODE.SCRIPT
1041
+ del sys.argv[0] # dmart
1042
+ del sys.argv[0] # cli
1043
+ del sys.argv[0] # s
1044
+ elif sys.argv[2] == "c":
1045
+ mode = CLI_MODE.CMD
1046
+ if len(sys.argv) >= 5 and sys.argv[4].startswith("/"):
1047
+ check_update_space(sys.argv[3], sys.argv[4])
1048
+ del sys.argv[3]
1049
+ del sys.argv[3]
1050
+ elif len(sys.argv) >= 4:
1051
+ check_update_space(sys.argv[3])
1052
+ del sys.argv[3]
1053
+ del sys.argv[0] # dmart
1054
+ del sys.argv[0] # cli
1055
+ del sys.argv[0] # c
1056
+ else:
1057
+ del sys.argv[0]
1058
+ del sys.argv[0]
1059
+ else:
1060
+ del sys.argv[0]
1061
+ del sys.argv[0]
1062
+
1063
+ if mode == CLI_MODE.CMD:
1064
+ print(sys.argv)
1065
+ action(" ".join(sys.argv))
1066
+ elif mode == CLI_MODE.SCRIPT:
1067
+ with open(sys.argv[0], "r") as commands:
1068
+ is_comment_block = False
1069
+ for command in commands:
1070
+ if (
1071
+ command.startswith("#")
1072
+ or command.startswith("//")
1073
+ or command == "\n"
1074
+ ):
1075
+ continue
1076
+ elif command.startswith("/*"):
1077
+ is_comment_block = True
1078
+ continue
1079
+ elif command.startswith("*/"):
1080
+ is_comment_block = False
1081
+ continue
1082
+ elif is_comment_block:
1083
+ continue
1084
+
1085
+ print("[green]> ", command)
1086
+ sliced_command = command.split()
1087
+
1088
+ if sliced_command[0] == "VAR":
1089
+ var[sliced_command[1]] = sliced_command[2]
1090
+ continue
1091
+
1092
+ sliced_command = parsing_variables(sliced_command)
1093
+
1094
+ action(" ".join(sliced_command))
1095
+ elif mode == CLI_MODE.REPL:
1096
+ while True:
1097
+ try:
1098
+ text = session.prompt(
1099
+ [("class:prompt", "❯ ")], # ≻≻
1100
+ # cursor=CursorShape.BLINKING_BLOCK,
1101
+ # cursor=CursorShape.BLINKING_BEAM,
1102
+ cursor=CursorShape.BLINKING_UNDERLINE,
1103
+ bottom_toolbar=bottom_toolbar,
1104
+ complete_in_thread=True,
1105
+ complete_while_typing=True,
1106
+ )
1107
+ # remove whitespaces
1108
+ text = re.sub(r"^\s+", "", text) # leading
1109
+ text = re.sub(r"\s+$", "", text) # trailing
1110
+ text = re.sub(
1111
+ r"\s+", " ", text
1112
+ ) # replace multiple inline whitespaces with one
1113
+ if text in ["exit", "q", "quit"]:
1114
+ break
1115
+ else:
1116
+ if text == "":
1117
+ continue
1118
+ action(text)
1119
+ except KeyboardInterrupt as ex:
1120
+ print(repr(ex))
1121
+ continue
1122
+ except EOFError as _:
1123
+ print("[green]Exiting ...[/]")
1124
+ break
1125
+ # else:
1126
+ # print('You entered:', repr(text))
1127
+ print("[yellow]Good bye![/]")
1128
+ except requests.exceptions.ConnectionError as _ :
1129
+ print("[yellow]Connection error[/]")
1130
+
1131
+
1132
+ if __name__ == "__main__":
1133
+ main()