OTAnalytics 0.7.4__tar.gz → 0.7.5__tar.gz
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.
- otanalytics-0.7.5/.github/workflows/system-test.yml +34 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/test.yml +1 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.gitignore +6 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.pre-commit-config.yaml +4 -0
- otanalytics-0.7.5/CONTEXT.md +56 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/dummy_viewmodel.py +164 -67
- otanalytics-0.7.5/OTAnalytics/adapter_ui/file_export_dto.py +31 -0
- otanalytics-0.7.5/OTAnalytics/adapter_ui/local_file_providers.py +57 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/ui_factory.py +1 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/view_model.py +4 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/analysis/traffic_counting.py +6 -3
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/analysis/traffic_counting_specification.py +12 -5
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/application.py +75 -13
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/config.py +9 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/config_specification.py +1 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/datastore.py +6 -51
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/eventlist.py +12 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/export_formats/event_list.py +2 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/export_formats/road_user_assignments.py +4 -0
- otanalytics-0.7.5/OTAnalytics/application/export_path_builder.py +54 -0
- otanalytics-0.7.5/OTAnalytics/application/files.py +19 -0
- otanalytics-0.7.5/OTAnalytics/application/key_prefix.py +34 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/parser/cli_parser.py +1 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/parser/config_parser.py +23 -0
- otanalytics-0.7.5/OTAnalytics/application/parser/track_parser.py +54 -0
- otanalytics-0.7.5/OTAnalytics/application/progress.py +195 -0
- otanalytics-0.7.5/OTAnalytics/application/project_location.py +43 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/resources/resource_manager.py +25 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/run_configuration.py +1 -1
- otanalytics-0.7.5/OTAnalytics/application/startup_config.py +54 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/state.py +28 -0
- otanalytics-0.7.5/OTAnalytics/application/upload_otconfig.py +24 -0
- otanalytics-0.7.5/OTAnalytics/application/use_cases/ask_for_load_window.py +47 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/config.py +24 -3
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/config_has_changed.py +4 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/export_events.py +24 -2
- otanalytics-0.7.5/OTAnalytics/application/use_cases/flow_repository.py +116 -0
- otanalytics-0.7.5/OTAnalytics/application/use_cases/load_otconfig.py +130 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/load_otflow.py +5 -6
- otanalytics-0.7.5/OTAnalytics/application/use_cases/load_track_files.py +188 -0
- otanalytics-0.7.5/OTAnalytics/application/use_cases/provide_input_files.py +35 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/quick_save_configuration.py +2 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/reset_state.py +4 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/road_user_assignment_export.py +53 -12
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/suggest_save_path.py +58 -5
- otanalytics-0.7.5/OTAnalytics/application/use_cases/track_export.py +31 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/track_statistics_export.py +47 -13
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/event.py +26 -0
- otanalytics-0.7.5/OTAnalytics/domain/georeference.py +56 -0
- otanalytics-0.7.5/OTAnalytics/domain/load_window.py +65 -0
- otanalytics-0.7.5/OTAnalytics/domain/progress.py +161 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track.py +12 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track_dataset/filtered_track_dataset.py +3 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track_dataset/track_dataset.py +33 -0
- otanalytics-0.7.5/OTAnalytics/domain/transfer_mode.py +8 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/filter_polars_track_dataset.py +11 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/polars_track_store.py +225 -13
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/python_track_store.py +19 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/track_geometry_store/polars_geometry_store.py +367 -120
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/track_store.py +37 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/argparse_cli_parser.py +8 -6
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/convert_ottrk_to_feathers.py +27 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/export.py +55 -16
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/feathers_parser.py +22 -88
- otanalytics-0.7.5/OTAnalytics/plugin_parser/georeference_parsing.py +30 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/otconfig_parser.py +118 -39
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/ottrk_dataformat.py +15 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/otvision_parser.py +13 -6
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/pandas_parser.py +8 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/road_user_assignment_export.py +11 -6
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/streaming_parser.py +2 -5
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/track_export.py +31 -51
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/track_statistics_export.py +25 -16
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/eventlist_exporter/eventlist_exporter.py +38 -17
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/track_visualization/track_viz.py +7 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/cleanup.py +58 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/config/env_vars.py +76 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/config/parsing.py +126 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/config/s3.py +33 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/download.py +37 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/download_objects.py +106 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/filename_timestamp.py +44 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/list_objects.py +45 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/otconfig_upload.py +15 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/project_location.py +37 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/s3_file_providers.py +267 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/select_objects.py +45 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/store.py +47 -0
- otanalytics-0.7.5/OTAnalytics/plugin_s3/upload.py +46 -0
- otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv/track_dataset_writer.py +42 -0
- otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv/writers/domain.py +30 -0
- otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv/writers/pandas.py +44 -0
- otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv/writers/polars.py +43 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/application_starter.py +38 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/base_application.py +57 -9
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/cli.py +66 -44
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/ctk_ui_factory.py +20 -21
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/helpers.py +12 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_export_counts.py +76 -10
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_export_file.py +56 -14
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/gui_application.py +30 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_application.py +155 -3
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/dialogs/export_counts_dialog.py +101 -36
- otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/dialogs/file_chooser_dialog.py +279 -0
- otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/dialogs/load_window_dialog.py +128 -0
- otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/nicegui/progressbar.py +215 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/remarks_form/container.py +0 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters_form/container.py +41 -6
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/ui_factory.py +41 -9
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/visualization/counts/counts_plotter.py +3 -1
- otanalytics-0.7.5/OTAnalytics/version.py +1 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/PKG-INFO +3 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/pyproject.toml +12 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/conftest.py +13 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_export_track_statistics.py +2 -1
- otanalytics-0.7.5/tests/acceptance/test_load_from_s3.py +234 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_project_information.py +2 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/benchmark/test_benchmark_otanalytics.py +3 -2
- otanalytics-0.7.5/tests/data/track_statistics_reference.csv +2 -0
- otanalytics-0.7.5/tests/integration/OTAnalytics/plugin_s3/test_load_from_rustfs.py +252 -0
- otanalytics-0.7.5/tests/system/OTAnalytics/plugin_ui/test_cli.py +209 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/adapter_ui/test_dummy_viewmodel_loading.py +118 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/adapter_ui/test_dummy_viewmodel_otconfig.py +254 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/adapter_ui/test_dummy_viewmodel_save_otconfig.py +99 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/adapter_ui/test_helpers.py +27 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/adapter_ui/test_local_file_providers.py +94 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/analysis/test_traffic_counting.py +13 -4
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/parser/test_track_parser.py +156 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_current_key_prefix.py +58 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_datastore.py +2 -6
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_eventlist.py +95 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_export_path_builder.py +46 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_key_prefix.py +54 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_progress.py +191 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_project_location.py +57 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_run_configuration.py +2 -2
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_startup_config.py +68 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/test_upload_otconfig.py +30 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/use_cases/test_config.py +154 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_config_has_changed.py +5 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_flow_repository.py +59 -7
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/use_cases/test_load_otconfig.py +343 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_load_otflow.py +8 -8
- otanalytics-0.7.5/tests/unit/OTAnalytics/application/use_cases/test_load_track_files.py +704 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_quick_save_configuration.py +17 -17
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_reset_state.py +13 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_road_user_assignment_export.py +3 -2
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_suggest_save_path.py +1 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_event.py +56 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/domain/test_georeference.py +54 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/domain/test_load_window.py +83 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/domain/test_track.py +35 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/domain/test_transfer_mode.py +26 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/track_dataset/test_filtered_track_dataset.py +8 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_cli/test_cli_application.py +16 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_datastore/test_filter_polars_track_store.py +50 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_datastore/test_polars_track_store.py +1535 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_datastore/test_python_track_store.py +119 -1
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_datastore/test_track_store.py +195 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_datastore/track_geometry_store/test_polars_geometry_store.py +1604 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_intersect_parallelization/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/conftest.py +32 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_convert_ottrk_to_feathers.py +68 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_export.py +34 -27
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_feathers_parser.py +212 -31
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_georeference_parsing.py +23 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_otconfig_key_prefix.py +162 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_otconfig_parser.py +104 -3
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_otconfig_substitution.py +186 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_otvision_parser.py +56 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_pandas_parser.py +87 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_road_user_assignment_export.py +163 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_parser/test_track_export.py +176 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_progress/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_prototypes/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_prototypes/test_eventlist_exporter.py +89 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_prototypes/track_visualization/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/config/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/config/test_env_vars.py +49 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/config/test_parsing.py +186 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_cleanup.py +108 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_download.py +58 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_download_objects.py +218 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_filename_timestamp.py +55 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_list_objects.py +126 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_otconfig_upload.py +36 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_project_location.py +72 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_read_video_name.py +130 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_s3_file_providers.py +321 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_select_objects.py +96 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_s3/test_upload.py +61 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/conftest.py +8 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/test_domain.py +116 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/test_pandas.py +113 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/test_polars.py +108 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_track_export/csv/test_track_dataset_writer.py +91 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/dialogs/test_file_chooser_dialog.py +2 -1
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/dialogs/test_load_window_dialog.py +201 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/nicegui/test_progressbar.py +279 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/pages/remarks_form/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/pages/remarks_form/test_container.py +84 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters_form/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters_form/test_container.py +85 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/test_ui_factory.py +66 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_cli.py +157 -13
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_export_counts_dialog.py +90 -40
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_file_chooser_dialog.py +144 -10
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/test_nicegui_application.py +126 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/test_nicegui_preload.py +64 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/visualization/__init__.py +0 -0
- otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_ui/visualization/counts/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/visualization/counts/test_counts_plotter.py +7 -2
- otanalytics-0.7.5/tests/unit/__init__.py +0 -0
- otanalytics-0.7.5/tests/utils/__init__.py +0 -0
- otanalytics-0.7.5/tests/utils/app_environment.py +67 -0
- otanalytics-0.7.5/tests/utils/builders/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/event_builder.py +4 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/road_user_assignment.py +4 -0
- otanalytics-0.7.5/tests/utils/builders/s3_config_builder.py +34 -0
- otanalytics-0.7.5/tests/utils/builders/s3_store_builder.py +21 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/track_builder.py +4 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/playwright_helpers.py +59 -12
- otanalytics-0.7.5/tests/utils/progress.py +24 -0
- otanalytics-0.7.5/tests/utils/rustfs_container.py +62 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/uv.lock +572 -302
- otanalytics-0.7.4/OTAnalytics/adapter_ui/file_export_dto.py +0 -8
- otanalytics-0.7.4/OTAnalytics/application/progress.py +0 -95
- otanalytics-0.7.4/OTAnalytics/application/use_cases/flow_repository.py +0 -101
- otanalytics-0.7.4/OTAnalytics/application/use_cases/load_otconfig.py +0 -76
- otanalytics-0.7.4/OTAnalytics/application/use_cases/load_track_files.py +0 -76
- otanalytics-0.7.4/OTAnalytics/application/use_cases/track_export.py +0 -57
- otanalytics-0.7.4/OTAnalytics/domain/progress.py +0 -84
- otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/dialogs/file_chooser_dialog.py +0 -155
- otanalytics-0.7.4/OTAnalytics/version.py +0 -1
- otanalytics-0.7.4/tests/unit/OTAnalytics/application/test_progress.py +0 -53
- otanalytics-0.7.4/tests/unit/OTAnalytics/application/use_cases/test_config.py +0 -54
- otanalytics-0.7.4/tests/unit/OTAnalytics/application/use_cases/test_load_otconfig.py +0 -164
- otanalytics-0.7.4/tests/unit/OTAnalytics/application/use_cases/test_load_track_files.py +0 -244
- otanalytics-0.7.4/tests/unit/OTAnalytics/application/use_cases/test_track_export.py +0 -49
- otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_datastore/test_polars_track_store.py +0 -626
- otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_datastore/track_geometry_store/test_polars_geometry_store.py +0 -733
- otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_parser/test_road_user_assignment_export.py +0 -82
- otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_parser/test_track_export.py +0 -59
- otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_prototypes/test_eventlist_exporter.py +0 -15
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.editorconfig +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.flake8 +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/dependabot.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/acceptance-test.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/benchmark.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/build-nightly.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/build-release.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/linter.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/regression-test.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/release-pypi.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.github/workflows/release-testpypi.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.junie/guidelines.md +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Scalene-CLI (benchmark).run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Scalene-CLI.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-CLI (benchmark files).run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-CLI.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-GUI (mit Benchmarkdaten).run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-GUI (mit Testdaten).run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-GUI.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/Start-WebUI (mit Testdaten).run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/pytest-acceptance-tests.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/pytest-benchmark-tests.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/pytest-in-tests.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/pytest-regression-tests.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.run/pytest-unit-tests.run.xml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.shellcheckrc +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.vscode/launch.json +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.vscode/settings.json +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/.yamllint.yaml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/LICENSE +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/__main__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_intersect/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_button_quick_save_config.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_canvas.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_canvas.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_offset.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_remark.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_track_plotting.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_frame_track_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_main_window.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_progressbar_popup.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/abstract_treeview_interface.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/cancel_export_counts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/cancel_export_file.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/default_values.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/dto.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/file_selection_cancelled.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/flow_adapter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/flow_dto.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/helpers.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/info_box.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/message_box.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/text_resources.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_ui/ui_texts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_visualization/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/adapter_visualization/color_provider.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/analysis/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/analysis/intersect.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/analysis/road_user_assignment.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/exception.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/export_formats/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/export_formats/export_mode.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/export_formats/track_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/geometry.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/logger.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/parser/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/parser/deserializer.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/parser/flow_parser.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/playback.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/plotting.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/resources/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/track_filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/track_input_source.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/ui/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/ui/frame_control.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/add_new_remark.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/apply_cli_cuts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/assignment_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/clear_repositories.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/create_events.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/create_intersection_events.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/create_road_user_assignments.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/cut_tracks_with_sections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/editor/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/editor/section_editor.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/event_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/filter_visualization.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/flow_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/generate_flows.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/get_current_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/get_current_remark.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/highlight_intersections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/inside_cutting_section.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/intersection_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/number_of_tracks_to_be_validated.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/preload_input_files.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/reset_application.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/reset_project_config.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/revert_cuts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/save_otflow.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/section_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/start_new_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/track_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/track_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/update_count_plots.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/update_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/application/use_cases/video_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/assets/OpenTrafficCam_800.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/common.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/date.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/files.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/flow.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/geometry.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/intersect.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/observer.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/otc_classes.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/remark.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/section.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/tls8plus1_classes.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track_dataset/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track_id_provider.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/track_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/types.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/domain/video.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/helpers/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/helpers/file_helpers.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/helpers/time_profiling.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_cli/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_cli/cli_application.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/filter_pandas_track_store.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/get_current_frame_track_segments.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/pandas_track_dataset_factory.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/polars_track_id_set.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/track_geometry_store/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_datastore/track_geometry_store/shapely_store.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_filter/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_filter/dataframe_filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_filter/pandas_track_id.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/shapely/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/shapely/mapping.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/simple/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/simple/cut_tracks_with_sections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect/simple_intersect.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect_parallelization/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect_parallelization/multiprocessing.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_intersect_parallelization/sequential.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/calculation_strategy.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/metric_rates_builder.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz/metric_rates.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz/number_of_tracks_to_be_validated.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_number_of_tracks_to_be_validated/tracks_as_dataframe_provider.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/dataformat_versions.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_parser/json_parser.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_progress/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_progress/lazy_tqdm_progressbar.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_progress/multiprocessing_progress.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_progress/tqdm_progressbar.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/event_visualization.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/eventlist_exporter/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/track_visualization/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/track_visualization/cv2_image.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/track_visualization/numpy_image.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_prototypes/track_visualization/pil_image.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_track_input_source → otanalytics-0.7.5/OTAnalytics/plugin_s3}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui → otanalytics-0.7.5/OTAnalytics/plugin_s3/config}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/customtkinter_gui → otanalytics-0.7.5/OTAnalytics/plugin_track_export}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui → otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/dialogs → otanalytics-0.7.5/OTAnalytics/plugin_track_export/csv/writers}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/forms → otanalytics-0.7.5/OTAnalytics/plugin_track_input_source}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_track_input_source/single_batch.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_track_input_source/template.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/nicegui → otanalytics-0.7.5/OTAnalytics/plugin_ui}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/ctk_application.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements → otanalytics-0.7.5/OTAnalytics/plugin_ui/customtkinter_gui}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/abstract_ctk_canvas.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/abstract_ctk_frame.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/button_quick_save_config.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/canvas_observer.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/constants.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/custom_containers.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_analysis.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_bbox_offset.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_canvas.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_configuration.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_date_filter_control.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_files.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_flows.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_remarks.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_sections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_track_plotting.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_track_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_tracks.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/frame_videos.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/gui.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/line_section.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/messagebox.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/scrollable_xy_frame.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/state.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/style.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_flows.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_progress.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_sections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/toplevel_template.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/treeview_template.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/customtkinter_gui/utility_widgets.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/intersection_repository.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/nicegui/theme → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/config.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/page_builders → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/dialogs}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/dialogs/edit_flow_dialog.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/dialogs/edit_section_dialog.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/dialogs/file_picker.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/endpoints.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/file_utils.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/forms}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/forms/offset_slider_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/add_track_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/nicegui}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/constants.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/add_video_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements/button_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements/dialog.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements/forms.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/elements/table.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/nicegui_webserver.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/page_builder.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/circle.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/circle_resources.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/line.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/line_resources.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/polyline.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/section_resources.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/analysis_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/nicegui/theme}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/theme/color.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/theme/global_theme.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/theme/nicegui_layout_components.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/nicegui/validation.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/page_builders}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/page_builders/main_page_builder.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/configuration_bar → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/remarks_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/add_track_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/add_track_form/add_tracks_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/add_track_form/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/add_track_form/visualization_offset_slider_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/sections_and_flow_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/add_video_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/add_video_form/container.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/svz_metadata_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/analysis_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/analysis_form/container.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/track_statistics_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form/canvas_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form/files_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/configuration_bar}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/configuration_bar/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/configuration_bar/project_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_layers_form → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/remarks_form}/__init__.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/utils → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/sections_and_flow_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/sections_and_flow_form/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/sections_and_flow_form/flow_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/sections_and_flow_form/sections_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/visualization → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/svz_metadata_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/svz_metadata_form/svz_metadata_form.py +0 -0
- {otanalytics-0.7.4/OTAnalytics/plugin_ui/visualization/counts → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/track_statistics_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/track_statistics_form/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters.py +0 -0
- {otanalytics-0.7.4/tests → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_filters_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_layers.py +0 -0
- {otanalytics-0.7.4/tests/acceptance → otanalytics-0.7.5/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_layers_form}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_layers_form/container.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/visualization_layers_form/layers_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/pages/workspace.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/nicegui_gui/test_constants.py +0 -0
- {otanalytics-0.7.4/tests/benchmark → otanalytics-0.7.5/OTAnalytics/plugin_ui/utils}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/utils/asyncio_helper.py +0 -0
- {otanalytics-0.7.4/tests/regression → otanalytics-0.7.5/OTAnalytics/plugin_ui/visualization}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics → otanalytics-0.7.5/OTAnalytics/plugin_ui/visualization/counts}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_ui/visualization/visualization.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/OTAnalytics/plugin_video_processing/video_reader.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/README.md +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/clean-up-repository.sh +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/config.yml +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/convert_ottrk_to_feather.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/install.cmd +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/install.sh +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/install_dev.cmd +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/install_dev.sh +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/requirements.txt +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/scripts/check_clean_architecture.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/start_gui.cmd +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/start_gui.sh +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/adapter_intersect → otanalytics-0.7.5/tests}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/application → otanalytics-0.7.5/tests/acceptance}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_create_important_test_data.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_filters_navigation_buttons.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_sections_and_flows.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_tracks_add_and_display.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/acceptance/test_video_import_and_display.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/application/analysis → otanalytics-0.7.5/tests/benchmark}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/conftest.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Sample_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otconfig +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otflow +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/all_tracks.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/highlight_tracks_assigned_to_flows.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/highlight_tracks_intersecting_sections.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/highlight_tracks_not_assigned_to_flows.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/highlight_tracks_not_intersecting_sections.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/offset_before.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/start_end_all.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/start_end_assigned_to_flows.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/start_end_intersecting_sections.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/start_end_not_assigned_to_flows.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/acceptance/start_end_not_intersecting_sections.png +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/cyclists_2025-12-19_10-18-43.otconfig +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/section.json.bz2.otflow +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/sections_created_test_file.otconfig +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/test_name.otconfig +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/data/trucks_2025-12-19_10-19-22.otconfig +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/application/resources → otanalytics-0.7.5/tests/integration/OTAnalytics}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/application/ui → otanalytics-0.7.5/tests/integration/OTAnalytics/plugin_s3}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/application/use_cases → otanalytics-0.7.5/tests/integration}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/domain → otanalytics-0.7.5/tests/regression}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/regression/test_regression_otanalytics.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/domain/track_dataset → otanalytics-0.7.5/tests/system/OTAnalytics}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_datastore → otanalytics-0.7.5/tests/system/OTAnalytics/plugin_ui}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_datastore/track_geometry_store → otanalytics-0.7.5/tests/system}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_filter → otanalytics-0.7.5/tests/unit/OTAnalytics}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_intersect → otanalytics-0.7.5/tests/unit/OTAnalytics/adapter_intersect}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/adapter_intersect/test_mapping.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_intersect/shapely → otanalytics-0.7.5/tests/unit/OTAnalytics/application}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_intersect/simple → otanalytics-0.7.5/tests/unit/OTAnalytics/application/analysis}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/analysis/test_road_user_assignment.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_intersect_parallelization → otanalytics-0.7.5/tests/unit/OTAnalytics/application/parser}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated → otanalytics-0.7.5/tests/unit/OTAnalytics/application/resources}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/resources/test_resource_manager.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_helpers.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_plotting.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_state.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/test_track_filter.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz → otanalytics-0.7.5/tests/unit/OTAnalytics/application/ui}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/ui/test_frame_control.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_parser → otanalytics-0.7.5/tests/unit/OTAnalytics/application/use_cases}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_apply_cli_cuts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_clear_repositories.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_create_events.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_create_intersection_events.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_event_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_filter_visualization.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_flows_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_generate_flows.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_get_current_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_get_road_user_assignments.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_highlight_intersections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_inside_cutting_section.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_intersection_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_preload_input_files.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_reset_application.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_reset_project_config.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_revert_cuts.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_save_otflow.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_section_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_start_new_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_track_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_track_statistics.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_track_statistics_export.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_update_count_plots.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_update_project.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/application/use_cases/test_video_repository.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_progress → otanalytics-0.7.5/tests/unit/OTAnalytics/domain}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_date.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_files.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_filter.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_flow.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_geometry.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_observer.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_section.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_track_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/test_video.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_prototypes → otanalytics-0.7.5/tests/unit/OTAnalytics/domain/track_dataset}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/track_dataset/conftest.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/domain/track_dataset/test_track_dataset.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_prototypes/track_visualization → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_cli}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_ui → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_datastore}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_datastore/test_filter_pandas_track_store.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_ui/visualization → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_datastore/track_geometry_store}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_datastore/track_geometry_store/test_shapely_store.py +0 -0
- {otanalytics-0.7.4/tests/unit/OTAnalytics/plugin_ui/visualization/counts → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_filter}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_filter/test_dataframe_filter.py +0 -0
- {otanalytics-0.7.4/tests/unit → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_intersect}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/utils → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_intersect/shapely}/__init__.py +0 -0
- {otanalytics-0.7.4/tests/utils/builders → otanalytics-0.7.5/tests/unit/OTAnalytics/plugin_intersect/simple}/__init__.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_intersect/simple/test_cut_tracks_with_sections.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_intersect/test_intersect.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_intersect_parallelization/test_multiprocessing.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_intersect_parallelization/test_sequential.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/conftest.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/svz/test_number_of_tracks_to_be_validated.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/test_calculation_strategy.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_number_of_tracks_to_be_validated/test_tracks_as_dataframe_provider.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_argparse_cli_parser.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_json_parser.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_parser/test_streaming_parser.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_progress/test_multiprocessing_progress.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_prototypes/track_visualization/test_track_viz.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/conftest.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/dialogs/test_file_extension_filtering.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/dialogs/test_file_picker.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/test_circle.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/test_line.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/nicegui/svg/test_polyline.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/nicegui_gui/pages/canvas_and_files_form/test_canvas_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_edit_flow_dialog.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_edit_section_dialog.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_flow_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_intersection_repository.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_sections_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_ui/test_svz_metadata_form.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/unit/OTAnalytics/plugin_video_processing/test_video_reader.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/assertions.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/constants.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/otanalytics_builders.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/ottrk_file_input_source.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/run_configuration.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/track_dataset_provider.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/builders/track_segment_builder.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/state.py +0 -0
- {otanalytics-0.7.4 → otanalytics-0.7.5}/tests/utils/ui_helpers.py +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: System Test With Pytest
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
# Run tests each time a PR is opened or changed.
|
|
6
|
+
# Allow other Workflows (e.g., build workflows) to call this workflow.
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
permissions: read-all
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Execute system tests across various operating systems and Python versions.
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
os: [ubuntu-latest, windows-latest]
|
|
18
|
+
py: ["3.12"]
|
|
19
|
+
fail-fast: true
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout repository
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
- name: Set up Python ${{ matrix.py }}
|
|
25
|
+
uses: actions/setup-python@v6
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.py }}
|
|
28
|
+
- name: Run Python System Tests
|
|
29
|
+
uses: platomo/test-python-app-action@v4
|
|
30
|
+
timeout-minutes: 60
|
|
31
|
+
with:
|
|
32
|
+
py-version: ${{ matrix.py }}
|
|
33
|
+
package-path: OTAnalytics
|
|
34
|
+
test-path: tests/system
|
|
@@ -3,6 +3,12 @@ data/
|
|
|
3
3
|
!tests/data
|
|
4
4
|
tests/data/OTCamera19_FR20_2023-05-24*
|
|
5
5
|
tests/scripts/
|
|
6
|
+
.envrc
|
|
7
|
+
# Where S3_USER_SOURCE stages downloaded tracks and videos while running
|
|
8
|
+
.cache-otanalytics/
|
|
9
|
+
|
|
10
|
+
# Anthropic Claude
|
|
11
|
+
.claude/rules/shared
|
|
6
12
|
|
|
7
13
|
# Byte-compiled / optimized / DLL files
|
|
8
14
|
__pycache__/
|
|
@@ -47,6 +47,7 @@ repos:
|
|
|
47
47
|
- interrogate==1.7.0
|
|
48
48
|
- isort==6.0.1
|
|
49
49
|
- matplotlib==3.10.0
|
|
50
|
+
- minio==7.2.20
|
|
50
51
|
- more-itertools==10.7.0
|
|
51
52
|
- mypy==1.16.1
|
|
52
53
|
- nicegui==2.24.1
|
|
@@ -66,8 +67,11 @@ repos:
|
|
|
66
67
|
- pytest-timeout==2.4.0
|
|
67
68
|
- pytest==8.3.4
|
|
68
69
|
- starlette==0.49.1
|
|
70
|
+
- testcontainers==4.13.1
|
|
69
71
|
- twine==6.2.0
|
|
70
72
|
- types-PyYAML
|
|
73
|
+
- types-aioboto3
|
|
74
|
+
- types-aiobotocore-s3==2.26.0
|
|
71
75
|
- types-flake8
|
|
72
76
|
- types-openpyxl
|
|
73
77
|
- types-pillow
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# OTAnalytics
|
|
2
|
+
|
|
3
|
+
Traffic analysis on road user trajectories: OTAnalytics loads Tracks recorded by
|
|
4
|
+
OTVision, lets a user define Sections and Flows over them, and counts the road
|
|
5
|
+
users crossing those Sections.
|
|
6
|
+
|
|
7
|
+
## Language
|
|
8
|
+
|
|
9
|
+
### Obtaining input files
|
|
10
|
+
|
|
11
|
+
**Transfer Mode**:
|
|
12
|
+
Where an OTAnalytics instance obtains its Track and Video files — the local
|
|
13
|
+
filesystem, or an S3 bucket. Fixed for the lifetime of the process by the
|
|
14
|
+
startup configuration; it is not something a user switches while working.
|
|
15
|
+
_Avoid_: storage backend, data source (both suggest a per-load choice).
|
|
16
|
+
|
|
17
|
+
**Startup Configuration**:
|
|
18
|
+
The environment variables naming the Transfer Mode and, in S3 mode, the bucket
|
|
19
|
+
and credentials. Fixed for the lifetime of the process. Deliberately not a file.
|
|
20
|
+
Says what a deployment may authenticate to, never which project it holds: the
|
|
21
|
+
Key Prefix comes from the **otconfig** instead, because that is per-project and
|
|
22
|
+
varies per lease. Credentials must never travel in an otconfig, since users save
|
|
23
|
+
and share those files.
|
|
24
|
+
_Avoid_: config file (there isn't one, and it invites confusion with otconfig).
|
|
25
|
+
|
|
26
|
+
**Key Prefix**:
|
|
27
|
+
The S3 prefix a project's Tracks and Videos live under, covering one camera or
|
|
28
|
+
site. A property of the project, declared by its otconfig, and required there in
|
|
29
|
+
S3 mode — so opening a different project moves where an instance reads from,
|
|
30
|
+
within the one configured bucket. Until a project is loaded there is no Key
|
|
31
|
+
Prefix and nothing can be listed.
|
|
32
|
+
_Avoid_: path, folder (S3 has neither); startup configuration (it is per-project,
|
|
33
|
+
unlike the bucket and credentials).
|
|
34
|
+
|
|
35
|
+
**User Source**:
|
|
36
|
+
The local directory that downloaded objects are written into, mirroring their S3
|
|
37
|
+
keys, so that a Track file and its Video land side by side. Named after
|
|
38
|
+
OTCloud's `S3_USER_SOURCE` for cross-repo consistency, though the name conveys
|
|
39
|
+
little on its own. Its contents do not survive a restart.
|
|
40
|
+
_Avoid_: cache (implies reuse across runs, which there is none of).
|
|
41
|
+
|
|
42
|
+
**Load Window**:
|
|
43
|
+
The start and end time a user selects to decide which Tracks and Videos to load.
|
|
44
|
+
Bounded by a configured maximum duration, because continuous processing produces
|
|
45
|
+
far more data than can be held at once. An over-long selection is _clamped_ —
|
|
46
|
+
its end snaps to the maximum and the user is told — never rejected.
|
|
47
|
+
_Avoid_: time range, date range (`DateRange` already means the filter applied to
|
|
48
|
+
already-loaded Tracks, which is a different thing).
|
|
49
|
+
|
|
50
|
+
**Track File Provider** / **Video File Provider**:
|
|
51
|
+
What a request for input files is asked of. Each implementation owns its own way
|
|
52
|
+
of asking the user, so nothing downstream knows where files came from: the local
|
|
53
|
+
one opens a file chooser, the S3 one asks for a Load Window and downloads. This
|
|
54
|
+
is the seam that makes the Transfer Mode interchangeable.
|
|
55
|
+
_Avoid_: file loader, importer (both suggest they also parse, which they do not —
|
|
56
|
+
they only obtain paths).
|
|
@@ -3,7 +3,7 @@ import functools
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from time import sleep
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Iterable, Optional, Sequence
|
|
7
7
|
|
|
8
8
|
from OTAnalytics.adapter_ui.abstract_button_quick_save_config import (
|
|
9
9
|
AbstractButtonQuickSaveConfig,
|
|
@@ -33,6 +33,7 @@ from OTAnalytics.adapter_ui.default_values import (
|
|
|
33
33
|
RELATIVE_SECTION_OFFSET,
|
|
34
34
|
SUPPORTED_FORMATS,
|
|
35
35
|
)
|
|
36
|
+
from OTAnalytics.adapter_ui.file_export_dto import ExportFileDto
|
|
36
37
|
from OTAnalytics.adapter_ui.flow_adapter import (
|
|
37
38
|
GeometricCenterCalculator,
|
|
38
39
|
InnerSegmentsCenterCalculator,
|
|
@@ -61,6 +62,7 @@ from OTAnalytics.application.application import (
|
|
|
61
62
|
)
|
|
62
63
|
from OTAnalytics.application.config import (
|
|
63
64
|
CONTEXT_FILE_TYPE_EVENTS,
|
|
65
|
+
CONTEXT_FILE_TYPE_ROAD_USER_ASSIGNMENTS,
|
|
64
66
|
CONTEXT_FILE_TYPE_TRACK_STATISTICS,
|
|
65
67
|
CUTTING_SECTION_MARKER,
|
|
66
68
|
OTCONFIG_FILE_TYPE,
|
|
@@ -68,7 +70,10 @@ from OTAnalytics.application.config import (
|
|
|
68
70
|
)
|
|
69
71
|
from OTAnalytics.application.export_formats.export_mode import OVERWRITE
|
|
70
72
|
from OTAnalytics.application.logger import logger
|
|
71
|
-
from OTAnalytics.application.parser.config_parser import
|
|
73
|
+
from OTAnalytics.application.parser.config_parser import (
|
|
74
|
+
StartDateMissing,
|
|
75
|
+
SubstitutedFile,
|
|
76
|
+
)
|
|
72
77
|
from OTAnalytics.application.parser.flow_parser import FlowParser
|
|
73
78
|
from OTAnalytics.application.playback import SkipTime
|
|
74
79
|
from OTAnalytics.application.project import (
|
|
@@ -88,6 +93,7 @@ from OTAnalytics.application.project import (
|
|
|
88
93
|
SvzMetadata,
|
|
89
94
|
WeatherType,
|
|
90
95
|
)
|
|
96
|
+
from OTAnalytics.application.project_location import UnsupportedProjectLocation
|
|
91
97
|
from OTAnalytics.application.use_cases.config import ConfigValidationError
|
|
92
98
|
from OTAnalytics.application.use_cases.config_has_changed import NoExistingConfigFound
|
|
93
99
|
from OTAnalytics.application.use_cases.cut_tracks_with_sections import CutTracksDto
|
|
@@ -97,11 +103,17 @@ from OTAnalytics.application.use_cases.editor.section_editor import (
|
|
|
97
103
|
UpdateSectionCoordinates,
|
|
98
104
|
)
|
|
99
105
|
from OTAnalytics.application.use_cases.export_events import (
|
|
106
|
+
EventExportSpecification,
|
|
100
107
|
EventListExporter,
|
|
101
108
|
ExporterNotFoundError,
|
|
102
109
|
)
|
|
103
110
|
from OTAnalytics.application.use_cases.flow_repository import FlowAlreadyExists
|
|
104
111
|
from OTAnalytics.application.use_cases.generate_flows import FlowNameGenerator
|
|
112
|
+
from OTAnalytics.application.use_cases.load_otconfig import UnableToLoadOtconfigFile
|
|
113
|
+
from OTAnalytics.application.use_cases.provide_input_files import (
|
|
114
|
+
ProvideTrackFiles,
|
|
115
|
+
ProvideVideoFiles,
|
|
116
|
+
)
|
|
105
117
|
from OTAnalytics.application.use_cases.quick_save_configuration import (
|
|
106
118
|
NoExistingFileToSave,
|
|
107
119
|
)
|
|
@@ -109,6 +121,7 @@ from OTAnalytics.application.use_cases.road_user_assignment_export import (
|
|
|
109
121
|
ExportSpecification,
|
|
110
122
|
)
|
|
111
123
|
from OTAnalytics.application.use_cases.save_otflow import NoSectionsToSave
|
|
124
|
+
from OTAnalytics.application.use_cases.suggest_save_path import SavePathSuggestion
|
|
112
125
|
from OTAnalytics.application.use_cases.track_statistics_export import (
|
|
113
126
|
TrackStatisticsExportSpecification,
|
|
114
127
|
)
|
|
@@ -140,12 +153,27 @@ from OTAnalytics.domain.types import EventType
|
|
|
140
153
|
from OTAnalytics.domain.video import Video, VideoListObserver
|
|
141
154
|
|
|
142
155
|
MESSAGE_CONFIGURATION_NOT_SAVED = "The configuration has not been saved.\n"
|
|
143
|
-
|
|
156
|
+
MESSAGE_CONFIGURATION_NOT_LOADED = "The configuration has not been loaded.\n"
|
|
157
|
+
MESSAGE_CONFIGURATION_FILES_SUBSTITUTED = (
|
|
158
|
+
"The configuration references files that were not found.\n"
|
|
159
|
+
)
|
|
144
160
|
LINE_SECTION: str = "line_section"
|
|
145
161
|
TO_SECTION = "to_section"
|
|
146
162
|
FROM_SECTION = "from_section"
|
|
147
163
|
|
|
148
164
|
|
|
165
|
+
def _explain(cause: BaseException) -> str:
|
|
166
|
+
"""Name the underlying failure, not the wrapper.
|
|
167
|
+
|
|
168
|
+
`UnableToLoadOtconfigFile` carries a fixed string and keeps the real reason
|
|
169
|
+
in `__cause__`, so reporting the wrapper alone tells the user nothing they
|
|
170
|
+
can act on.
|
|
171
|
+
"""
|
|
172
|
+
if cause.__cause__ is not None:
|
|
173
|
+
return f"{cause} {cause.__cause__}"
|
|
174
|
+
return f"{cause}"
|
|
175
|
+
|
|
176
|
+
|
|
149
177
|
class MissingInjectedInstanceError(Exception):
|
|
150
178
|
"""Raise when no instance of an object was injected before referencing it"""
|
|
151
179
|
|
|
@@ -310,9 +338,13 @@ class DummyViewModel(
|
|
|
310
338
|
show_svz: bool,
|
|
311
339
|
add_new_section: AddNewSection,
|
|
312
340
|
update_section_coordinates: UpdateSectionCoordinates,
|
|
341
|
+
provide_track_files: ProvideTrackFiles,
|
|
342
|
+
provide_video_files: ProvideVideoFiles,
|
|
313
343
|
) -> None:
|
|
314
344
|
self._application = application
|
|
315
345
|
self._ui_factory = ui_factory
|
|
346
|
+
self._provide_track_files = provide_track_files
|
|
347
|
+
self._provide_video_files = provide_video_files
|
|
316
348
|
self._flow_parser: FlowParser = flow_parser
|
|
317
349
|
self._name_generator = name_generator
|
|
318
350
|
self._event_list_export_formats = event_list_export_formats
|
|
@@ -553,24 +585,7 @@ class DummyViewModel(
|
|
|
553
585
|
self._update_enabled_video_buttons()
|
|
554
586
|
|
|
555
587
|
async def add_video(self) -> None:
|
|
556
|
-
|
|
557
|
-
extension_options: Dict[str, Optional[List[str]]] = {}
|
|
558
|
-
|
|
559
|
-
# Convert "*.ext" format to ".ext" format for extension_options
|
|
560
|
-
clean_extensions = [ext for ext in SUPPORTED_VIDEO_FILE_TYPES]
|
|
561
|
-
|
|
562
|
-
# Add "All File Endings" option with all supported extensions
|
|
563
|
-
extension_options["All File Endings"] = clean_extensions
|
|
564
|
-
|
|
565
|
-
# Add individual extension options
|
|
566
|
-
for ext in clean_extensions:
|
|
567
|
-
extension_options[ext] = [ext]
|
|
568
|
-
|
|
569
|
-
video_files = await self._ui_factory.askopenfilenames(
|
|
570
|
-
title="Load video files",
|
|
571
|
-
filetypes=[("video file", SUPPORTED_VIDEO_FILE_TYPES)],
|
|
572
|
-
extension_options=extension_options,
|
|
573
|
-
)
|
|
588
|
+
video_files = await self._provide_video_files.provide()
|
|
574
589
|
if not video_files:
|
|
575
590
|
return
|
|
576
591
|
logger().info(f"Video files to load: {video_files}")
|
|
@@ -611,19 +626,25 @@ class DummyViewModel(
|
|
|
611
626
|
self.frame_project.update(name=project.name, start_date=project.start_date)
|
|
612
627
|
|
|
613
628
|
async def save_otconfig(self) -> None:
|
|
614
|
-
|
|
629
|
+
save_suggestion = self._application.suggest_save_path(OTCONFIG_FILE_TYPE)
|
|
630
|
+
if self._application.get_current_key_prefix() is not None:
|
|
631
|
+
# A project that names a location was opened by an operator naming
|
|
632
|
+
# it, not chosen from a picker (OP#10323 decision 1), so it always
|
|
633
|
+
# re-saves to its own name and place with no new UI.
|
|
634
|
+
await self._save_otconfig(save_suggestion.file_path)
|
|
635
|
+
return
|
|
615
636
|
configuration_file = await self._ui_factory.ask_for_save_file_path(
|
|
616
637
|
title="Save configuration as",
|
|
617
638
|
filetypes=[(f"{OTCONFIG_FILE_TYPE} file", f"*.{OTCONFIG_FILE_TYPE}")],
|
|
618
639
|
defaultextension=f".{OTCONFIG_FILE_TYPE}",
|
|
619
|
-
initialfile=
|
|
620
|
-
initialdir=
|
|
640
|
+
initialfile=save_suggestion.file_path.name,
|
|
641
|
+
initialdir=save_suggestion.save_directory,
|
|
621
642
|
)
|
|
622
643
|
if not configuration_file:
|
|
623
644
|
return
|
|
624
|
-
self._save_otconfig(configuration_file)
|
|
645
|
+
await self._save_otconfig(configuration_file)
|
|
625
646
|
|
|
626
|
-
def _save_otconfig(self, otconfig_file: Path) -> None:
|
|
647
|
+
async def _save_otconfig(self, otconfig_file: Path) -> None:
|
|
627
648
|
# Ensure the file has the correct extension
|
|
628
649
|
otconfig_file_str = ensure_file_extension_is_present(
|
|
629
650
|
str(otconfig_file), [f"*.{OTCONFIG_FILE_TYPE}"], f".{OTCONFIG_FILE_TYPE}"
|
|
@@ -632,7 +653,7 @@ class DummyViewModel(
|
|
|
632
653
|
|
|
633
654
|
logger().info(f"Config file to save: {otconfig_file}")
|
|
634
655
|
try:
|
|
635
|
-
self._application.save_otconfig(otconfig_file)
|
|
656
|
+
await self._application.save_otconfig(otconfig_file)
|
|
636
657
|
except NoSectionsToSave:
|
|
637
658
|
message = (
|
|
638
659
|
f"{MESSAGE_CONFIGURATION_NOT_SAVED}"
|
|
@@ -692,9 +713,9 @@ class DummyViewModel(
|
|
|
692
713
|
)
|
|
693
714
|
if not otconfig_file:
|
|
694
715
|
return
|
|
695
|
-
self._load_otconfig(otconfig_file)
|
|
716
|
+
await self._load_otconfig(otconfig_file)
|
|
696
717
|
|
|
697
|
-
def _load_otconfig(self, otconfig_file: Path) -> None:
|
|
718
|
+
async def _load_otconfig(self, otconfig_file: Path) -> None:
|
|
698
719
|
proceed = self._ui_factory.info_box(
|
|
699
720
|
message=(
|
|
700
721
|
"This will load a stored configuration from file. \n"
|
|
@@ -707,10 +728,73 @@ class DummyViewModel(
|
|
|
707
728
|
if proceed.canceled:
|
|
708
729
|
return
|
|
709
730
|
logger().info(f"{OTCONFIG_FILE_TYPE} file to load: {otconfig_file}")
|
|
710
|
-
|
|
731
|
+
try:
|
|
732
|
+
await self._application.load_otconfig_async(file=Path(otconfig_file))
|
|
733
|
+
except (
|
|
734
|
+
UnableToLoadOtconfigFile,
|
|
735
|
+
UnsupportedProjectLocation,
|
|
736
|
+
OSError,
|
|
737
|
+
) as cause:
|
|
738
|
+
# A file the config references is missing, the config contradicts
|
|
739
|
+
# itself, or its data lives where this installation cannot read it.
|
|
740
|
+
# All are the user's to act on, so name the cause.
|
|
741
|
+
self._report_load_failure(_explain(cause))
|
|
742
|
+
return
|
|
743
|
+
except Exception as cause:
|
|
744
|
+
# The boundary of a user action: without this, a malformed config
|
|
745
|
+
# reaches the browser as a traceback. The traceback still logs.
|
|
746
|
+
logger().exception("Failed to load configuration file", exc_info=cause)
|
|
747
|
+
self._report_load_failure("An unexpected error occurred.")
|
|
748
|
+
return
|
|
711
749
|
self.show_current_project()
|
|
712
750
|
self.update_svz_metadata_view()
|
|
713
751
|
|
|
752
|
+
def report_substituted_files(
|
|
753
|
+
self, substitutions: Sequence[SubstitutedFile]
|
|
754
|
+
) -> None:
|
|
755
|
+
"""Tell the user which references were rebound while loading.
|
|
756
|
+
|
|
757
|
+
The parser resolves a missing reference to a same-named file beside the
|
|
758
|
+
otconfig. The names match but the contents need not: re-detected or
|
|
759
|
+
re-tracked output reuses the filename with different detections. So the
|
|
760
|
+
project is loaded, and the user is told what it actually holds.
|
|
761
|
+
"""
|
|
762
|
+
if not substitutions:
|
|
763
|
+
return
|
|
764
|
+
rebound = "\n".join(
|
|
765
|
+
f"• '{substitution.requested}' → '{substitution.used}'"
|
|
766
|
+
for substitution in substitutions
|
|
767
|
+
)
|
|
768
|
+
self._tell_user(
|
|
769
|
+
f"{MESSAGE_CONFIGURATION_FILES_SUBSTITUTED}"
|
|
770
|
+
f"The files below were not found where the configuration says, so a "
|
|
771
|
+
f"file of the same name next to the configuration was loaded "
|
|
772
|
+
f"instead. Check that this is the data you meant:\n{rebound}"
|
|
773
|
+
)
|
|
774
|
+
|
|
775
|
+
def _report_load_failure(self, reason: str) -> None:
|
|
776
|
+
self._tell_user(f"{MESSAGE_CONFIGURATION_NOT_LOADED}{reason}")
|
|
777
|
+
|
|
778
|
+
def _tell_user(self, message: str) -> None:
|
|
779
|
+
"""Log a message and show it if the ui can be reached.
|
|
780
|
+
|
|
781
|
+
Reporting must never break what it reports on. Nicegui resolves the
|
|
782
|
+
client through the slot stack and raises when that stack is empty, so
|
|
783
|
+
`info_box` fails whenever no browser is attached — during the startup
|
|
784
|
+
preload of a `--config` file, for one. Left unguarded, reporting a
|
|
785
|
+
substitution there would propagate out of the parse and stop the server
|
|
786
|
+
from starting. The log is the guarantee; the box is best effort.
|
|
787
|
+
"""
|
|
788
|
+
logger().warning(message)
|
|
789
|
+
try:
|
|
790
|
+
self._ui_factory.info_box(
|
|
791
|
+
message=message, initial_position=self._get_window_position()
|
|
792
|
+
)
|
|
793
|
+
except Exception as cause:
|
|
794
|
+
logger().exception(
|
|
795
|
+
"Could not show this message to the user", exc_info=cause
|
|
796
|
+
)
|
|
797
|
+
|
|
714
798
|
def set_tracks_frame(self, frame: AbstractFrame) -> None:
|
|
715
799
|
self._frame_tracks = frame
|
|
716
800
|
|
|
@@ -815,17 +899,11 @@ class DummyViewModel(
|
|
|
815
899
|
|
|
816
900
|
@action
|
|
817
901
|
async def load_tracks(self) -> None:
|
|
818
|
-
track_files = await self.
|
|
819
|
-
title="Load track files",
|
|
820
|
-
filetypes=[
|
|
821
|
-
("tracks file", "*.ottrk"),
|
|
822
|
-
],
|
|
823
|
-
)
|
|
902
|
+
track_files = await self._provide_track_files.provide()
|
|
824
903
|
if not track_files:
|
|
825
904
|
return
|
|
826
905
|
logger().info(f"Tracks files to load: {track_files}")
|
|
827
|
-
|
|
828
|
-
self._application.add_tracks_of_files(track_files=track_paths)
|
|
906
|
+
await self._application.add_tracks_of_files_async(track_files=track_files)
|
|
829
907
|
|
|
830
908
|
async def load_configuration(self) -> None: # sourcery skip: avoid-builtin-shadow
|
|
831
909
|
# INFO: Current behavior: Overwrites existing sections
|
|
@@ -844,7 +922,7 @@ class DummyViewModel(
|
|
|
844
922
|
elif configuration_file.suffix == f".{OTFLOW_FILE_TYPE}":
|
|
845
923
|
self._load_otflow(configuration_file)
|
|
846
924
|
elif configuration_file.suffix == f".{OTCONFIG_FILE_TYPE}":
|
|
847
|
-
self._load_otconfig(configuration_file)
|
|
925
|
+
await self._load_otconfig(configuration_file)
|
|
848
926
|
else:
|
|
849
927
|
raise ValueError("Configuration file to load has unknown file extension")
|
|
850
928
|
|
|
@@ -870,7 +948,13 @@ class DummyViewModel(
|
|
|
870
948
|
self.refresh_items_on_canvas()
|
|
871
949
|
|
|
872
950
|
async def save_configuration(self) -> None:
|
|
873
|
-
|
|
951
|
+
save_suggestion = self._application.suggest_save_path(OTCONFIG_FILE_TYPE)
|
|
952
|
+
if self._application.get_current_key_prefix() is not None:
|
|
953
|
+
# A project that names a location is always an otconfig and always
|
|
954
|
+
# re-saves to its own name and place with no new UI (OP#10323
|
|
955
|
+
# decision 1 & 5).
|
|
956
|
+
await self._save_otconfig(save_suggestion.file_path)
|
|
957
|
+
return
|
|
874
958
|
configuration_file = await self._ui_factory.ask_for_save_file_path(
|
|
875
959
|
title="Save configuration as",
|
|
876
960
|
filetypes=[
|
|
@@ -878,8 +962,8 @@ class DummyViewModel(
|
|
|
878
962
|
(f"{OTFLOW_FILE_TYPE} file", f"*.{OTFLOW_FILE_TYPE}"),
|
|
879
963
|
],
|
|
880
964
|
defaultextension=f".{OTCONFIG_FILE_TYPE}",
|
|
881
|
-
initialfile=
|
|
882
|
-
initialdir=
|
|
965
|
+
initialfile=save_suggestion.file_path.name,
|
|
966
|
+
initialdir=save_suggestion.save_directory,
|
|
883
967
|
)
|
|
884
968
|
if not configuration_file.stem:
|
|
885
969
|
return
|
|
@@ -895,13 +979,13 @@ class DummyViewModel(
|
|
|
895
979
|
if configuration_file.suffix == f".{OTFLOW_FILE_TYPE}":
|
|
896
980
|
self._save_otflow(configuration_file)
|
|
897
981
|
elif configuration_file.suffix == f".{OTCONFIG_FILE_TYPE}":
|
|
898
|
-
self._save_otconfig(configuration_file)
|
|
982
|
+
await self._save_otconfig(configuration_file)
|
|
899
983
|
else:
|
|
900
984
|
raise ValueError("Configuration file to save has unknown file extension")
|
|
901
985
|
|
|
902
986
|
async def quick_save_configuration(self) -> None:
|
|
903
987
|
try:
|
|
904
|
-
self._application.quick_save_configuration()
|
|
988
|
+
await self._application.quick_save_configuration()
|
|
905
989
|
except NoExistingFileToSave:
|
|
906
990
|
await self.save_configuration()
|
|
907
991
|
|
|
@@ -1389,33 +1473,40 @@ class DummyViewModel(
|
|
|
1389
1473
|
for key, exporter in self._event_list_export_formats.items()
|
|
1390
1474
|
}
|
|
1391
1475
|
try:
|
|
1392
|
-
event_list_exporter,
|
|
1476
|
+
event_list_exporter, export_config = await self._configure_event_exporter(
|
|
1393
1477
|
export_format_extensions
|
|
1394
1478
|
)
|
|
1395
|
-
|
|
1479
|
+
specification = EventExportSpecification(
|
|
1480
|
+
export_directory=export_config.export_directory,
|
|
1481
|
+
export_filename_stem=export_config.file_stem,
|
|
1482
|
+
export_mode=OVERWRITE,
|
|
1483
|
+
)
|
|
1484
|
+
self._application.export_events(specification, event_list_exporter)
|
|
1396
1485
|
logger().info(
|
|
1397
|
-
f"Exporting eventlist using {event_list_exporter.get_name()} to
|
|
1486
|
+
f"Exporting eventlist using {event_list_exporter.get_name()} to "
|
|
1487
|
+
f"{export_config.as_file_path()}"
|
|
1398
1488
|
)
|
|
1399
1489
|
except CancelExportFile:
|
|
1400
1490
|
logger().info("User canceled configuration of export")
|
|
1401
1491
|
|
|
1402
1492
|
async def _configure_event_exporter(
|
|
1403
1493
|
self, export_format_extensions: dict[str, str]
|
|
1404
|
-
) -> tuple[EventListExporter,
|
|
1494
|
+
) -> tuple[EventListExporter, ExportFileDto]:
|
|
1405
1495
|
export_config = await self._ui_factory.configure_export_file(
|
|
1406
1496
|
title="Export events",
|
|
1407
1497
|
export_format_extensions=export_format_extensions,
|
|
1408
|
-
|
|
1498
|
+
context_file_type=CONTEXT_FILE_TYPE_EVENTS,
|
|
1409
1499
|
viewmodel=self,
|
|
1410
1500
|
)
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1501
|
+
event_list_exporter = self._event_list_export_formats.get(
|
|
1502
|
+
export_config.export_format, None
|
|
1503
|
+
)
|
|
1414
1504
|
if event_list_exporter is None:
|
|
1415
1505
|
raise ExporterNotFoundError(
|
|
1416
1506
|
f"{event_list_exporter} is not a valid export format"
|
|
1417
1507
|
)
|
|
1418
|
-
|
|
1508
|
+
|
|
1509
|
+
return event_list_exporter, export_config
|
|
1419
1510
|
|
|
1420
1511
|
def set_track_offset(self, offset_x: float, offset_y: float) -> None:
|
|
1421
1512
|
start_msg_popup = self._ui_factory.minimal_info_box(
|
|
@@ -1697,18 +1788,20 @@ class DummyViewModel(
|
|
|
1697
1788
|
export_config = await self._ui_factory.configure_export_file(
|
|
1698
1789
|
title="Export road user assignments",
|
|
1699
1790
|
export_format_extensions=export_formats,
|
|
1700
|
-
|
|
1791
|
+
context_file_type=CONTEXT_FILE_TYPE_ROAD_USER_ASSIGNMENTS,
|
|
1701
1792
|
viewmodel=self,
|
|
1702
1793
|
)
|
|
1703
1794
|
logger().debug(export_config)
|
|
1704
|
-
save_path = export_config.file
|
|
1705
|
-
export_format = export_config.export_format
|
|
1706
|
-
|
|
1707
1795
|
export_specification = ExportSpecification(
|
|
1708
|
-
|
|
1796
|
+
export_directory=export_config.export_directory,
|
|
1797
|
+
export_filename_stem=export_config.file_stem,
|
|
1798
|
+
format=export_config.export_format,
|
|
1799
|
+
export_mode=OVERWRITE,
|
|
1709
1800
|
)
|
|
1710
1801
|
self._application.export_road_user_assignments(export_specification)
|
|
1711
|
-
logger().info(
|
|
1802
|
+
logger().info(
|
|
1803
|
+
f"Exporting road user assignments to {export_config.as_file_path()}"
|
|
1804
|
+
)
|
|
1712
1805
|
except CancelExportFile:
|
|
1713
1806
|
logger().info("User canceled configuration of export")
|
|
1714
1807
|
|
|
@@ -1776,7 +1869,9 @@ class DummyViewModel(
|
|
|
1776
1869
|
def update_remark_view(self, _: Any = None) -> None:
|
|
1777
1870
|
self.frame_remark.load_remark()
|
|
1778
1871
|
|
|
1779
|
-
def get_save_path_suggestion(
|
|
1872
|
+
def get_save_path_suggestion(
|
|
1873
|
+
self, file_type: str, context_file_type: str
|
|
1874
|
+
) -> SavePathSuggestion:
|
|
1780
1875
|
return self._application.suggest_save_path(file_type, context_file_type)
|
|
1781
1876
|
|
|
1782
1877
|
def set_frame_track_statistics(self, frame: AbstractFrameTrackStatistics) -> None:
|
|
@@ -1808,17 +1903,19 @@ class DummyViewModel(
|
|
|
1808
1903
|
export_config = await self._ui_factory.configure_export_file(
|
|
1809
1904
|
title="Export track statistics",
|
|
1810
1905
|
export_format_extensions=export_formats,
|
|
1811
|
-
|
|
1906
|
+
context_file_type=CONTEXT_FILE_TYPE_TRACK_STATISTICS,
|
|
1812
1907
|
viewmodel=self,
|
|
1813
1908
|
)
|
|
1814
1909
|
logger().debug(export_config)
|
|
1815
|
-
save_path = export_config.file
|
|
1816
|
-
export_format = export_config.export_format
|
|
1817
|
-
|
|
1818
1910
|
export_specification = TrackStatisticsExportSpecification(
|
|
1819
|
-
|
|
1911
|
+
export_directory=export_config.export_directory,
|
|
1912
|
+
export_filename_stem=export_config.file_stem,
|
|
1913
|
+
format=export_config.export_format,
|
|
1914
|
+
export_mode=OVERWRITE,
|
|
1915
|
+
)
|
|
1916
|
+
destination = self._application.export_track_statistics(
|
|
1917
|
+
export_specification
|
|
1820
1918
|
)
|
|
1821
|
-
|
|
1822
|
-
logger().info(f"Exporting track statistics to {save_path}")
|
|
1919
|
+
logger().info(f"Exporting track statistics to {destination}")
|
|
1823
1920
|
except CancelExportFile:
|
|
1824
1921
|
logger().info("User canceled configuration of export")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True)
|
|
6
|
+
class ExportFileDto:
|
|
7
|
+
"""
|
|
8
|
+
Data transfer object for file export information.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
export_directory (Path): The directory where the file will be exported.
|
|
12
|
+
file_stem (str): The stem of the file name (without extension).
|
|
13
|
+
export_format (str): The format of the exported file. The file extension.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
export_directory: Path
|
|
17
|
+
file_stem: str
|
|
18
|
+
export_format_extension: str
|
|
19
|
+
export_format: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_file_path(cls, file_path: Path, export_format: str) -> "ExportFileDto":
|
|
23
|
+
return cls(
|
|
24
|
+
export_directory=file_path.parent,
|
|
25
|
+
file_stem=file_path.stem,
|
|
26
|
+
export_format_extension=file_path.suffix,
|
|
27
|
+
export_format=export_format,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def as_file_path(self) -> Path:
|
|
31
|
+
return self.export_directory / f"{self.file_stem}{self.export_format_extension}"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Local-filesystem implementations of the input file providers."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from OTAnalytics.adapter_ui.ui_factory import UiFactory
|
|
6
|
+
from OTAnalytics.application.config import SUPPORTED_VIDEO_FILE_TYPES
|
|
7
|
+
from OTAnalytics.application.use_cases.provide_input_files import (
|
|
8
|
+
ProvideTrackFiles,
|
|
9
|
+
ProvideVideoFiles,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
ALL_FILE_ENDINGS = "All File Endings"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LocalTrackFileProvider(ProvideTrackFiles):
|
|
16
|
+
"""Asks the user to pick ottrk files from the local filesystem.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
ui_factory (UiFactory): builds the file chooser for the active front-end.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, ui_factory: UiFactory) -> None:
|
|
23
|
+
self._ui_factory = ui_factory
|
|
24
|
+
|
|
25
|
+
async def provide(self) -> list[Path]:
|
|
26
|
+
return await self._ui_factory.askopenfilenames(
|
|
27
|
+
title="Load track files",
|
|
28
|
+
filetypes=[("tracks file", "*.ottrk")],
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LocalVideoFileProvider(ProvideVideoFiles):
|
|
33
|
+
"""Asks the user to pick video files from the local filesystem.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
ui_factory (UiFactory): builds the file chooser for the active front-end.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, ui_factory: UiFactory) -> None:
|
|
40
|
+
self._ui_factory = ui_factory
|
|
41
|
+
|
|
42
|
+
async def provide(self) -> list[Path]:
|
|
43
|
+
return await self._ui_factory.askopenfilenames(
|
|
44
|
+
title="Load video files",
|
|
45
|
+
filetypes=[("video file", SUPPORTED_VIDEO_FILE_TYPES)],
|
|
46
|
+
extension_options=_video_extension_options(),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _video_extension_options() -> dict[str, list[str] | None]:
|
|
51
|
+
"""One entry offering every supported type, then one per type."""
|
|
52
|
+
options: dict[str, list[str] | None] = {
|
|
53
|
+
ALL_FILE_ENDINGS: list(SUPPORTED_VIDEO_FILE_TYPES)
|
|
54
|
+
}
|
|
55
|
+
for extension in SUPPORTED_VIDEO_FILE_TYPES:
|
|
56
|
+
options[extension] = [extension]
|
|
57
|
+
return options
|