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.
- dmart/__init__.py +7 -0
- dmart/alembic/README +1 -0
- dmart/alembic/__init__.py +0 -0
- dmart/alembic/env.py +91 -0
- dmart/alembic/notes.txt +11 -0
- dmart/alembic/script.py.mako +28 -0
- dmart/alembic/scripts/__init__.py +0 -0
- dmart/alembic/scripts/calculate_checksums.py +77 -0
- dmart/alembic/scripts/migration_f7a4949eed19.py +28 -0
- dmart/alembic/versions/0f3d2b1a7c21_add_authz_materialized_views.py +87 -0
- dmart/alembic/versions/10d2041b94d4_last_checksum_history.py +62 -0
- dmart/alembic/versions/1cf4e1ee3cb8_ext_permission_with_filter_fields_values.py +33 -0
- dmart/alembic/versions/26bfe19b49d4_rm_failedloginattempts.py +42 -0
- dmart/alembic/versions/3c8bca2219cc_add_otp_table.py +38 -0
- dmart/alembic/versions/6675fd9dfe42_remove_unique_from_sessions_table.py +36 -0
- dmart/alembic/versions/71bc1df82e6a_adding_user_last_login_at.py +43 -0
- dmart/alembic/versions/74288ccbd3b5_initial.py +264 -0
- dmart/alembic/versions/7520a89a8467_rm_activesession_table.py +39 -0
- dmart/alembic/versions/848b623755a4_make_created_nd_updated_at_required.py +138 -0
- dmart/alembic/versions/8640dcbebf85_add_notes_to_users.py +32 -0
- dmart/alembic/versions/91c94250232a_adding_fk_on_owner_shortname.py +104 -0
- dmart/alembic/versions/98ecd6f56f9a_ext_meta_with_owner_group_shortname.py +66 -0
- dmart/alembic/versions/9aae9138c4ef_indexing_created_at_updated_at.py +80 -0
- dmart/alembic/versions/__init__.py +0 -0
- dmart/alembic/versions/b53f916b3f6d_json_to_jsonb.py +492 -0
- dmart/alembic/versions/eb5f1ec65156_adding_user_locked_to_device.py +36 -0
- dmart/alembic/versions/f7a4949eed19_adding_query_policies_to_meta.py +60 -0
- dmart/alembic.ini +117 -0
- dmart/api/__init__.py +0 -0
- dmart/api/info/__init__.py +0 -0
- dmart/api/info/router.py +109 -0
- dmart/api/managed/__init__.py +0 -0
- dmart/api/managed/router.py +1541 -0
- dmart/api/managed/utils.py +1879 -0
- dmart/api/public/__init__.py +0 -0
- dmart/api/public/router.py +758 -0
- dmart/api/qr/__init__.py +0 -0
- dmart/api/qr/router.py +108 -0
- dmart/api/user/__init__.py +0 -0
- dmart/api/user/model/__init__.py +0 -0
- dmart/api/user/model/errors.py +14 -0
- dmart/api/user/model/requests.py +165 -0
- dmart/api/user/model/responses.py +11 -0
- dmart/api/user/router.py +1413 -0
- dmart/api/user/service.py +270 -0
- dmart/bundler.py +52 -0
- dmart/cli.py +1133 -0
- dmart/config/__init__.py +0 -0
- dmart/config/channels.json +11 -0
- dmart/config/notification.json +17 -0
- dmart/config.env.sample +27 -0
- dmart/config.ini.sample +7 -0
- dmart/conftest.py +13 -0
- dmart/curl.sh +196 -0
- dmart/cxb/__init__.py +0 -0
- dmart/cxb/assets/@codemirror-Rn7_6DkE.js +10 -0
- dmart/cxb/assets/@edraj-CS4NwVbD.js +1 -0
- dmart/cxb/assets/@floating-ui-BwwcF-xh.js +1 -0
- dmart/cxb/assets/@formatjs-yKEsAtjs.js +1 -0
- dmart/cxb/assets/@fortawesome-DRW1UCdr.js +9 -0
- dmart/cxb/assets/@jsonquerylang-laKNoFFq.js +12 -0
- dmart/cxb/assets/@lezer-za4Q-8Ew.js +1 -0
- dmart/cxb/assets/@marijn-DXwl3gUT.js +1 -0
- dmart/cxb/assets/@popperjs-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/@replit--ERk53eB.js +1 -0
- dmart/cxb/assets/@roxi-CGMFK4i8.js +6 -0
- dmart/cxb/assets/@typewriter-cCzskkIv.js +17 -0
- dmart/cxb/assets/@zerodevx-BlBZjKxu.js +1 -0
- dmart/cxb/assets/@zerodevx-CVEpe6WZ.css +1 -0
- dmart/cxb/assets/BreadCrumbLite-DAhOx38v.js +1 -0
- dmart/cxb/assets/EntryRenderer-CCqV8Rkg.js +32 -0
- dmart/cxb/assets/EntryRenderer-DXytdFp9.css +1 -0
- dmart/cxb/assets/ListView-BQelo7vZ.js +16 -0
- dmart/cxb/assets/ListView-U8of-_c-.css +1 -0
- dmart/cxb/assets/Prism--hMplq-p.js +3 -0
- dmart/cxb/assets/Prism-Uh6uStUw.css +1 -0
- dmart/cxb/assets/Table2Cols-BsbwicQm.js +1 -0
- dmart/cxb/assets/_..-BvT6vdHa.css +1 -0
- dmart/cxb/assets/_...404_-fuLH_rX9.js +2 -0
- dmart/cxb/assets/_...fallback_-Ba_NLmAE.js +1 -0
- dmart/cxb/assets/_module-3HrtKAWo.js +3 -0
- dmart/cxb/assets/_module-DFKFq0AM.js +4 -0
- dmart/cxb/assets/_module-Dgq0ZVtz.js +1 -0
- dmart/cxb/assets/ajv-Cpj98o6Y.js +1 -0
- dmart/cxb/assets/axios-CG2WSiiR.js +6 -0
- dmart/cxb/assets/clsx-B-dksMZM.js +1 -0
- dmart/cxb/assets/codemirror-wrapped-line-indent-DPhKvljI.js +1 -0
- dmart/cxb/assets/compare-C3AjiGFR.js +1 -0
- dmart/cxb/assets/compute-scroll-into-view-Bl8rNFhg.js +1 -0
- dmart/cxb/assets/consolite-DlCuI0F9.js +1 -0
- dmart/cxb/assets/crelt-C8TCjufn.js +1 -0
- dmart/cxb/assets/date-fns-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/deepmerge-rn4rBaHU.js +1 -0
- dmart/cxb/assets/dmart_services-AL6-IdDE.js +1 -0
- dmart/cxb/assets/downloadFile-D08i0YDh.js +1 -0
- dmart/cxb/assets/easy-signal-BiPFIK3O.js +1 -0
- dmart/cxb/assets/esm-env-rsSWfq8L.js +1 -0
- dmart/cxb/assets/export-OF_rTiXu.js +1 -0
- dmart/cxb/assets/fast-deep-equal-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/fast-diff-C-IidNf4.js +1 -0
- dmart/cxb/assets/fast-uri-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/flowbite-svelte-BLvjb-sa.js +1 -0
- dmart/cxb/assets/flowbite-svelte-CD54FDqW.css +1 -0
- dmart/cxb/assets/flowbite-svelte-icons-BI8GVhw_.js +1 -0
- dmart/cxb/assets/github-slugger-CQ4oX9Ud.js +1 -0
- dmart/cxb/assets/global-igKv-1g9.js +1 -0
- dmart/cxb/assets/hookar-BMRD9G9H.js +1 -0
- dmart/cxb/assets/immutable-json-patch-DtRO2E_S.js +1 -0
- dmart/cxb/assets/import-1vE3gBat.js +1 -0
- dmart/cxb/assets/index-B-eTh-ZX.js +1 -0
- dmart/cxb/assets/index-BSsK-X71.js +1 -0
- dmart/cxb/assets/index-BVyxzKtH.js +1 -0
- dmart/cxb/assets/index-BdeNM69f.js +1 -0
- dmart/cxb/assets/index-CC-A1ipE.js +1 -0
- dmart/cxb/assets/index-CQohGiYB.js +1 -0
- dmart/cxb/assets/index-ChjnkpdZ.js +4 -0
- dmart/cxb/assets/index-DLP7csA4.js +1 -0
- dmart/cxb/assets/index-DTfhnhwd.js +1 -0
- dmart/cxb/assets/index-DdXRK7n9.js +2 -0
- dmart/cxb/assets/index-DtiCmB4o.js +1 -0
- dmart/cxb/assets/index-NBrXBlLA.css +2 -0
- dmart/cxb/assets/index-X1uNehO7.js +1 -0
- dmart/cxb/assets/index-nrQW6Nrr.js +1 -0
- dmart/cxb/assets/info-B986lRiM.js +1 -0
- dmart/cxb/assets/intl-messageformat-Dc5UU-HB.js +3 -0
- dmart/cxb/assets/jmespath-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/json-schema-traverse-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/json-source-map-DRgZidqy.js +5 -0
- dmart/cxb/assets/jsonpath-plus-l0sNRNKZ.js +1 -0
- dmart/cxb/assets/jsonrepair-B30Dx381.js +8 -0
- dmart/cxb/assets/lodash-es-DZVAA2ox.js +1 -0
- dmart/cxb/assets/marked-DKjyhwJX.js +56 -0
- dmart/cxb/assets/marked-gfm-heading-id-U5zO829x.js +2 -0
- dmart/cxb/assets/marked-mangle-CDMeiHC6.js +1 -0
- dmart/cxb/assets/memoize-one-BdPwpGay.js +1 -0
- dmart/cxb/assets/natural-compare-lite-Bg2Xcf-o.js +7 -0
- dmart/cxb/assets/pagination-svelte-D5CyoiE_.js +13 -0
- dmart/cxb/assets/pagination-svelte-v10nAbbM.css +1 -0
- dmart/cxb/assets/plantuml-encoder-C47mzt9T.js +1 -0
- dmart/cxb/assets/prismjs-DTUiLGJu.js +9 -0
- dmart/cxb/assets/profile-BUf-tKMe.js +1 -0
- dmart/cxb/assets/query-CNmXTsgf.js +1 -0
- dmart/cxb/assets/queryHelpers-C9iBWwqe.js +1 -0
- dmart/cxb/assets/scroll-into-view-if-needed-KR58zyjF.js +1 -0
- dmart/cxb/assets/spaces-0oyGvpii.js +1 -0
- dmart/cxb/assets/style-mod-Bs6eFhZE.js +3 -0
- dmart/cxb/assets/svelte-B2XmcTi_.js +4 -0
- dmart/cxb/assets/svelte-awesome-COLlx0DN.css +1 -0
- dmart/cxb/assets/svelte-awesome-DhnMA6Q_.js +1 -0
- dmart/cxb/assets/svelte-datatables-net-CY7LBj6I.js +1 -0
- dmart/cxb/assets/svelte-floating-ui-BlS3sOAQ.js +1 -0
- dmart/cxb/assets/svelte-i18n-CT2KkQaN.js +3 -0
- dmart/cxb/assets/svelte-jsoneditor-BzfX6Usi.css +1 -0
- dmart/cxb/assets/svelte-jsoneditor-CUGSvWId.js +25 -0
- dmart/cxb/assets/svelte-select-CegQKzqH.css +1 -0
- dmart/cxb/assets/svelte-select-CjHAt_85.js +6 -0
- dmart/cxb/assets/tailwind-merge-CJvxXMcu.js +1 -0
- dmart/cxb/assets/tailwind-variants-Cj20BoQ3.js +1 -0
- dmart/cxb/assets/toast-B9WDyfyI.js +1 -0
- dmart/cxb/assets/tslib-pJfR_DrR.js +1 -0
- dmart/cxb/assets/typewriter-editor-DkTVIJdm.js +25 -0
- dmart/cxb/assets/user-DeK_NB5v.js +1 -0
- dmart/cxb/assets/vanilla-picker-l5rcX3cq.js +8 -0
- dmart/cxb/assets/w3c-keyname-Vcq4gwWv.js +1 -0
- dmart/cxb/config.json +11 -0
- dmart/cxb/config.sample.json +11 -0
- dmart/cxb/favicon.ico +0 -0
- dmart/cxb/favicon.png +0 -0
- dmart/cxb/index.html +28 -0
- dmart/data_adapters/__init__.py +0 -0
- dmart/data_adapters/adapter.py +16 -0
- dmart/data_adapters/base_data_adapter.py +467 -0
- dmart/data_adapters/file/__init__.py +0 -0
- dmart/data_adapters/file/adapter.py +2043 -0
- dmart/data_adapters/file/adapter_helpers.py +1013 -0
- dmart/data_adapters/file/archive.py +150 -0
- dmart/data_adapters/file/create_index.py +331 -0
- dmart/data_adapters/file/create_users_folders.py +52 -0
- dmart/data_adapters/file/custom_validations.py +68 -0
- dmart/data_adapters/file/drop_index.py +40 -0
- dmart/data_adapters/file/health_check.py +560 -0
- dmart/data_adapters/file/redis_services.py +1110 -0
- dmart/data_adapters/helpers.py +27 -0
- dmart/data_adapters/sql/__init__.py +0 -0
- dmart/data_adapters/sql/adapter.py +3218 -0
- dmart/data_adapters/sql/adapter_helpers.py +491 -0
- dmart/data_adapters/sql/create_tables.py +451 -0
- dmart/data_adapters/sql/create_users_folders.py +53 -0
- dmart/data_adapters/sql/db_to_json_migration.py +485 -0
- dmart/data_adapters/sql/health_check_sql.py +232 -0
- dmart/data_adapters/sql/json_to_db_migration.py +454 -0
- dmart/data_adapters/sql/update_query_policies.py +101 -0
- dmart/data_generator.py +81 -0
- dmart/dmart.py +761 -0
- dmart/get_settings.py +7 -0
- dmart/hypercorn_config.toml +3 -0
- dmart/info.json +1 -0
- dmart/languages/__init__.py +0 -0
- dmart/languages/arabic.json +15 -0
- dmart/languages/english.json +16 -0
- dmart/languages/kurdish.json +14 -0
- dmart/languages/loader.py +12 -0
- dmart/login_creds.sh +7 -0
- dmart/login_creds.sh.sample +7 -0
- dmart/main.py +563 -0
- dmart/manifest.sh +12 -0
- dmart/migrate.py +24 -0
- dmart/models/__init__.py +0 -0
- dmart/models/api.py +203 -0
- dmart/models/core.py +597 -0
- dmart/models/enums.py +255 -0
- dmart/password_gen.py +8 -0
- dmart/plugins/__init__.py +0 -0
- dmart/plugins/action_log/__init__.py +0 -0
- dmart/plugins/action_log/config.json +13 -0
- dmart/plugins/action_log/plugin.py +121 -0
- dmart/plugins/admin_notification_sender/__init__.py +0 -0
- dmart/plugins/admin_notification_sender/config.json +13 -0
- dmart/plugins/admin_notification_sender/plugin.py +124 -0
- dmart/plugins/ldap_manager/__init__.py +0 -0
- dmart/plugins/ldap_manager/config.json +12 -0
- dmart/plugins/ldap_manager/dmart.schema +146 -0
- dmart/plugins/ldap_manager/plugin.py +100 -0
- dmart/plugins/ldap_manager/slapd.conf +53 -0
- dmart/plugins/local_notification/__init__.py +0 -0
- dmart/plugins/local_notification/config.json +13 -0
- dmart/plugins/local_notification/plugin.py +123 -0
- dmart/plugins/realtime_updates_notifier/__init__.py +0 -0
- dmart/plugins/realtime_updates_notifier/config.json +12 -0
- dmart/plugins/realtime_updates_notifier/plugin.py +58 -0
- dmart/plugins/redis_db_update/__init__.py +0 -0
- dmart/plugins/redis_db_update/config.json +13 -0
- dmart/plugins/redis_db_update/plugin.py +188 -0
- dmart/plugins/resource_folders_creation/__init__.py +0 -0
- dmart/plugins/resource_folders_creation/config.json +12 -0
- dmart/plugins/resource_folders_creation/plugin.py +81 -0
- dmart/plugins/system_notification_sender/__init__.py +0 -0
- dmart/plugins/system_notification_sender/config.json +13 -0
- dmart/plugins/system_notification_sender/plugin.py +188 -0
- dmart/plugins/update_access_controls/__init__.py +0 -0
- dmart/plugins/update_access_controls/config.json +12 -0
- dmart/plugins/update_access_controls/plugin.py +9 -0
- dmart/publish.sh +57 -0
- dmart/pylint.sh +16 -0
- dmart/pyrightconfig.json +7 -0
- dmart/redis_connections.sh +13 -0
- dmart/reload.sh +56 -0
- dmart/run.sh +3 -0
- dmart/run_notification_campaign.py +85 -0
- dmart/sample/spaces/applications/.dm/meta.space.json +30 -0
- dmart/sample/spaces/applications/api/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/api/.dm/query_all_applications/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/meta.warframe.json +1 -0
- dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/warframe.png +0 -0
- dmart/sample/spaces/applications/api/.dm/test_by_saad/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/.dm/user_profile/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/create_log/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/create_public_logs/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/query_all_translated_data/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/query_logs/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/query_translated_enums/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/query_translated_others/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/.dm/query_translated_resolution/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/applications/create_log.json +1 -0
- dmart/sample/spaces/applications/api/applications/create_public_logs.json +1 -0
- dmart/sample/spaces/applications/api/applications/query_all_translated_data.json +1 -0
- dmart/sample/spaces/applications/api/applications/query_logs.json +1 -0
- dmart/sample/spaces/applications/api/applications/query_translated_enums.json +1 -0
- dmart/sample/spaces/applications/api/applications/query_translated_others.json +1 -0
- dmart/sample/spaces/applications/api/applications/query_translated_resolution.json +1 -0
- dmart/sample/spaces/applications/api/applications.json +1 -0
- dmart/sample/spaces/applications/api/management/.dm/create_subaccount/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/management/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/api/management/.dm/update_password/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/management/create_subaccount.json +53 -0
- dmart/sample/spaces/applications/api/management/update_password.json +1 -0
- dmart/sample/spaces/applications/api/management.json +1 -0
- dmart/sample/spaces/applications/api/query_all_applications.json +15 -0
- dmart/sample/spaces/applications/api/test_by_saad.json +1 -0
- dmart/sample/spaces/applications/api/user/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/api/user/.dm/test_by_saad/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/user/.dm/user_profile/meta.content.json +1 -0
- dmart/sample/spaces/applications/api/user/test_by_saad.json +1 -0
- dmart/sample/spaces/applications/api/user/user_profile.json +1 -0
- dmart/sample/spaces/applications/api/user_profile.json +1 -0
- dmart/sample/spaces/applications/api.json +1 -0
- dmart/sample/spaces/applications/collections/.dm/meta.folder.json +19 -0
- dmart/sample/spaces/applications/collections.json +1 -0
- dmart/sample/spaces/applications/configurations/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/configurations/time_out.json +1 -0
- dmart/sample/spaces/applications/configurations.json +19 -0
- dmart/sample/spaces/applications/errors.json +1 -0
- dmart/sample/spaces/applications/logs/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/logs.json +1 -0
- dmart/sample/spaces/applications/queries/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/queries/.dm/order/meta.content.json +1 -0
- dmart/sample/spaces/applications/queries/order.json +1 -0
- dmart/sample/spaces/applications/queries.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/api/meta.schema.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/configuration/meta.schema.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/error/meta.schema.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/log/meta.schema.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/schema/.dm/query/meta.schema.json +16 -0
- dmart/sample/spaces/applications/schema/.dm/translation/meta.schema.json +1 -0
- dmart/sample/spaces/applications/schema/api.json +28 -0
- dmart/sample/spaces/applications/schema/configuration.json +1 -0
- dmart/sample/spaces/applications/schema/error.json +43 -0
- dmart/sample/spaces/applications/schema/log.json +1 -0
- dmart/sample/spaces/applications/schema/query.json +118 -0
- dmart/sample/spaces/applications/schema/translation.json +26 -0
- dmart/sample/spaces/applications/schema.json +1 -0
- dmart/sample/spaces/applications/translations/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/applications/translations.json +1 -0
- dmart/sample/spaces/archive/.dm/meta.space.json +27 -0
- dmart/sample/spaces/custom_plugins/dummy/__pycache__/plugin.cpython-314.pyc +0 -0
- dmart/sample/spaces/custom_plugins/dummy/config.json +28 -0
- dmart/sample/spaces/custom_plugins/dummy/plugin.py +6 -0
- dmart/sample/spaces/custom_plugins/missed_entry/config.json +12 -0
- dmart/sample/spaces/custom_plugins/missed_entry/plugin.py +119 -0
- dmart/sample/spaces/custom_plugins/own_changed_notification/__pycache__/plugin.cpython-314.pyc +0 -0
- dmart/sample/spaces/custom_plugins/own_changed_notification/config.json +12 -0
- dmart/sample/spaces/custom_plugins/own_changed_notification/plugin.py +65 -0
- dmart/sample/spaces/custom_plugins/reports_stats/config.json +14 -0
- dmart/sample/spaces/custom_plugins/reports_stats/plugin.py +82 -0
- dmart/sample/spaces/custom_plugins/system_notification_sender/config.json +22 -0
- dmart/sample/spaces/custom_plugins/system_notification_sender/notification.py +268 -0
- dmart/sample/spaces/custom_plugins/system_notification_sender/plugin.py +98 -0
- dmart/sample/spaces/management/.dm/events.jsonl +32 -0
- dmart/sample/spaces/management/.dm/meta.space.json +48 -0
- dmart/sample/spaces/management/.dm/notifications/attachments.view.json/admin.json +36 -0
- dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.admin.json +1 -0
- dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.system.json +1 -0
- dmart/sample/spaces/management/.dm/notifications/attachments.view.json/system.json +32 -0
- dmart/sample/spaces/management/collections/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/collections.json +1 -0
- dmart/sample/spaces/management/groups/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/groups.json +1 -0
- dmart/sample/spaces/management/health_check/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/health_check.json +1 -0
- dmart/sample/spaces/management/notifications/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/notifications/admin/.dm/meta.folder.json +9 -0
- dmart/sample/spaces/management/notifications/system/.dm/meta.folder.json +9 -0
- dmart/sample/spaces/management/notifications.json +1 -0
- dmart/sample/spaces/management/permissions/.dm/access_applications/meta.permission.json +31 -0
- dmart/sample/spaces/management/permissions/.dm/access_applications_world/meta.permission.json +31 -0
- dmart/sample/spaces/management/permissions/.dm/access_messages/meta.permission.json +23 -0
- dmart/sample/spaces/management/permissions/.dm/access_personal/meta.permission.json +40 -0
- dmart/sample/spaces/management/permissions/.dm/access_protected/meta.permission.json +33 -0
- dmart/sample/spaces/management/permissions/.dm/access_public/meta.permission.json +24 -0
- dmart/sample/spaces/management/permissions/.dm/browse_all_folders/meta.permission.json +23 -0
- dmart/sample/spaces/management/permissions/.dm/create_log/meta.permission.json +24 -0
- dmart/sample/spaces/management/permissions/.dm/interviewer/meta.permission.json +1 -0
- dmart/sample/spaces/management/permissions/.dm/manage_applications/meta.permission.json +1 -0
- dmart/sample/spaces/management/permissions/.dm/manage_debug/meta.permission.json +25 -0
- dmart/sample/spaces/management/permissions/.dm/manage_spaces/meta.permission.json +24 -0
- dmart/sample/spaces/management/permissions/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/permissions/.dm/rules_management_default/meta.permission.json +32 -0
- dmart/sample/spaces/management/permissions/.dm/super_manager/meta.permission.json +52 -0
- dmart/sample/spaces/management/permissions/.dm/view_activity_log/meta.permission.json +26 -0
- dmart/sample/spaces/management/permissions/.dm/view_collections/meta.permission.json +29 -0
- dmart/sample/spaces/management/permissions/.dm/view_logs/meta.permission.json +30 -0
- dmart/sample/spaces/management/permissions/.dm/view_roles/meta.permission.json +29 -0
- dmart/sample/spaces/management/permissions/.dm/view_users/meta.permission.json +25 -0
- dmart/sample/spaces/management/permissions/.dm/view_world/meta.permission.json +31 -0
- dmart/sample/spaces/management/permissions/.dm/world/meta.permission.json +35 -0
- dmart/sample/spaces/management/permissions.json +1 -0
- dmart/sample/spaces/management/requests.json +1 -0
- dmart/sample/spaces/management/roles/.dm/dummy/meta.role.json +12 -0
- dmart/sample/spaces/management/roles/.dm/logged_in/meta.role.json +18 -0
- dmart/sample/spaces/management/roles/.dm/manager/meta.role.json +13 -0
- dmart/sample/spaces/management/roles/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/roles/.dm/moderator/meta.role.json +13 -0
- dmart/sample/spaces/management/roles/.dm/super_admin/meta.role.json +14 -0
- dmart/sample/spaces/management/roles/.dm/test_role/meta.role.json +13 -0
- dmart/sample/spaces/management/roles/.dm/world/meta.role.json +15 -0
- dmart/sample/spaces/management/roles.json +1 -0
- dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/meta.ui_schema.json +10 -0
- dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/ui_schema.json +32 -0
- dmart/sample/spaces/management/schema/.dm/admin_notification_request/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/api/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/folder_rendering/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/health_check/meta.schema.json +17 -0
- dmart/sample/spaces/management/schema/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/schema/.dm/meta_schema/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/metafile/meta.schema.json +14 -0
- dmart/sample/spaces/management/schema/.dm/notification/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/meta.ui_schema.json +10 -0
- dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/ui_schema.json +32 -0
- dmart/sample/spaces/management/schema/.dm/system_notification_request/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/view/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/.dm/workflow/meta.schema.json +1 -0
- dmart/sample/spaces/management/schema/admin_notification_request.json +89 -0
- dmart/sample/spaces/management/schema/api.json +1 -0
- dmart/sample/spaces/management/schema/folder_rendering.json +238 -0
- dmart/sample/spaces/management/schema/health_check.json +8 -0
- dmart/sample/spaces/management/schema/meta_schema.json +74 -0
- dmart/sample/spaces/management/schema/metafile.json +153 -0
- dmart/sample/spaces/management/schema/notification.json +28 -0
- dmart/sample/spaces/management/schema/system_notification_request.json +57 -0
- dmart/sample/spaces/management/schema/view.json +23 -0
- dmart/sample/spaces/management/schema/workflow.json +87 -0
- dmart/sample/spaces/management/schema.json +1 -0
- dmart/sample/spaces/management/users/.dm/alibaba/meta.user.json +23 -0
- dmart/sample/spaces/management/users/.dm/anonymous/meta.user.json +18 -0
- dmart/sample/spaces/management/users/.dm/dmart/meta.user.json +26 -0
- dmart/sample/spaces/management/users/.dm/meta.folder.json +14 -0
- dmart/sample/spaces/management/workflows/.dm/channel/meta.content.json +1 -0
- dmart/sample/spaces/management/workflows/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/management/workflows/channel.json +148 -0
- dmart/sample/spaces/management/workflows.json +1 -0
- dmart/sample/spaces/maqola/.dm/meta.space.json +33 -0
- dmart/sample/spaces/personal/.dm/meta.space.json +24 -0
- dmart/sample/spaces/personal/people/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/messages/.dm/0b5f7e7f/meta.content.json +1 -0
- dmart/sample/spaces/personal/people/dmart/messages/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/messages/.dm/mytest/meta.content.json +1 -0
- dmart/sample/spaces/personal/people/dmart/messages/0b5f7e7f.json +1 -0
- dmart/sample/spaces/personal/people/dmart/messages/mytest.json +1 -0
- dmart/sample/spaces/personal/people/dmart/notifications/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/private/.dm/inner/meta.content.json +1 -0
- dmart/sample/spaces/personal/people/dmart/private/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/private/inner.json +1 -0
- dmart/sample/spaces/personal/people/dmart/protected/.dm/avatar/meta.content.json +1 -0
- dmart/sample/spaces/personal/people/dmart/protected/.dm/meta.folder.json +1 -0
- dmart/sample/spaces/personal/people/dmart/protected/avatar.png +0 -0
- dmart/sample/spaces/personal/people/dmart/public/.dm/meta.folder.json +1 -0
- dmart/sample/test/.gitignore +2 -0
- dmart/sample/test/createcontent.json +9 -0
- dmart/sample/test/createmedia.json +9 -0
- dmart/sample/test/createmedia_entry.json +6 -0
- dmart/sample/test/createschema.json +8 -0
- dmart/sample/test/createschemawork.json +11 -0
- dmart/sample/test/createticket.json +13 -0
- dmart/sample/test/data.json +4 -0
- dmart/sample/test/deletecontent.json +12 -0
- dmart/sample/test/logo.jpeg +0 -0
- dmart/sample/test/my.jpg +0 -0
- dmart/sample/test/myticket.json +23 -0
- dmart/sample/test/resources.csv +12 -0
- dmart/sample/test/schema.json +16 -0
- dmart/sample/test/temp.json +1 -0
- dmart/sample/test/test.dmart +45 -0
- dmart/sample/test/ticket_schema.json +23 -0
- dmart/sample/test/ticket_workflow.json +85 -0
- dmart/sample/test/ticketbody.json +4 -0
- dmart/sample/test/ticketcontent.json +14 -0
- dmart/sample/test/updatecontent.json +20 -0
- dmart/sample/test/workflow_schema.json +68 -0
- dmart/scheduled_notification_handler.py +121 -0
- dmart/schema_migration.py +208 -0
- dmart/schema_modulate.py +192 -0
- dmart/set_admin_passwd.py +75 -0
- dmart/sync.py +202 -0
- dmart/test_utils.py +34 -0
- dmart/utils/__init__.py +0 -0
- dmart/utils/access_control.py +306 -0
- dmart/utils/async_request.py +8 -0
- dmart/utils/exporter.py +309 -0
- dmart/utils/firebase_notifier.py +57 -0
- dmart/utils/generate_email.py +37 -0
- dmart/utils/helpers.py +352 -0
- dmart/utils/hypercorn_config.py +12 -0
- dmart/utils/internal_error_code.py +60 -0
- dmart/utils/jwt.py +124 -0
- dmart/utils/logger.py +167 -0
- dmart/utils/middleware.py +99 -0
- dmart/utils/notification.py +75 -0
- dmart/utils/password_hashing.py +16 -0
- dmart/utils/plugin_manager.py +202 -0
- dmart/utils/query_policies_helper.py +128 -0
- dmart/utils/regex.py +44 -0
- dmart/utils/repository.py +529 -0
- dmart/utils/router_helper.py +19 -0
- dmart/utils/settings.py +212 -0
- dmart/utils/sms_notifier.py +21 -0
- dmart/utils/social_sso.py +67 -0
- dmart/utils/templates/activation.html.j2 +26 -0
- dmart/utils/templates/reminder.html.j2 +17 -0
- dmart/utils/ticket_sys_utils.py +203 -0
- dmart/utils/web_notifier.py +29 -0
- dmart/websocket.py +231 -0
- dmart-1.4.40.post8.dist-info/METADATA +75 -0
- dmart-1.4.40.post8.dist-info/RECORD +489 -0
- dmart-1.4.40.post8.dist-info/WHEEL +5 -0
- dmart-1.4.40.post8.dist-info/entry_points.txt +2 -0
- 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()
|