datanavigator 1.0.0__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.
Files changed (41) hide show
  1. datanavigator-1.0.0/.gitignore +163 -0
  2. datanavigator-1.0.0/.readthedocs.yaml +29 -0
  3. datanavigator-1.0.0/LICENSE +9 -0
  4. datanavigator-1.0.0/PKG-INFO +99 -0
  5. datanavigator-1.0.0/README.md +68 -0
  6. datanavigator-1.0.0/datanavigator/__init__.py +133 -0
  7. datanavigator-1.0.0/datanavigator/__version__.py +1 -0
  8. datanavigator-1.0.0/datanavigator/_config.py +53 -0
  9. datanavigator-1.0.0/datanavigator/assets.py +362 -0
  10. datanavigator-1.0.0/datanavigator/components.py +512 -0
  11. datanavigator-1.0.0/datanavigator/core.py +397 -0
  12. datanavigator-1.0.0/datanavigator/events.py +833 -0
  13. datanavigator-1.0.0/datanavigator/examples.py +291 -0
  14. datanavigator-1.0.0/datanavigator/opticalflow.py +173 -0
  15. datanavigator-1.0.0/datanavigator/plots.py +123 -0
  16. datanavigator-1.0.0/datanavigator/pointtracking.py +1667 -0
  17. datanavigator-1.0.0/datanavigator/signals.py +86 -0
  18. datanavigator-1.0.0/datanavigator/utils.py +409 -0
  19. datanavigator-1.0.0/datanavigator/videos.py +351 -0
  20. datanavigator-1.0.0/docs/Makefile +20 -0
  21. datanavigator-1.0.0/docs/api.md +79 -0
  22. datanavigator-1.0.0/docs/conf.py +48 -0
  23. datanavigator-1.0.0/docs/index.md +13 -0
  24. datanavigator-1.0.0/docs/make.bat +35 -0
  25. datanavigator-1.0.0/docs/requirements.txt +4 -0
  26. datanavigator-1.0.0/pyproject.toml +39 -0
  27. datanavigator-1.0.0/requirements.yml +18 -0
  28. datanavigator-1.0.0/tests/__init__.py +0 -0
  29. datanavigator-1.0.0/tests/conftest.py +199 -0
  30. datanavigator-1.0.0/tests/test___init__.py +31 -0
  31. datanavigator-1.0.0/tests/test__config.py +63 -0
  32. datanavigator-1.0.0/tests/test_components.py +354 -0
  33. datanavigator-1.0.0/tests/test_core.py +180 -0
  34. datanavigator-1.0.0/tests/test_events.py +491 -0
  35. datanavigator-1.0.0/tests/test_examples.py +307 -0
  36. datanavigator-1.0.0/tests/test_opticalflow.py +48 -0
  37. datanavigator-1.0.0/tests/test_plots.py +71 -0
  38. datanavigator-1.0.0/tests/test_pointtracking.py +1355 -0
  39. datanavigator-1.0.0/tests/test_signals.py +82 -0
  40. datanavigator-1.0.0/tests/test_utils.py +115 -0
  41. datanavigator-1.0.0/tests/test_videos.py +163 -0
@@ -0,0 +1,163 @@
1
+ .vscode/*
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ .pybuilder/
78
+ target/
79
+
80
+ # Jupyter Notebook
81
+ .ipynb_checkpoints
82
+
83
+ # IPython
84
+ profile_default/
85
+ ipython_config.py
86
+
87
+ # pyenv
88
+ # For a library or package, you might want to ignore these files since the code is
89
+ # intended to run in multiple environments; otherwise, check them in:
90
+ # .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # poetry
100
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
101
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
102
+ # commonly ignored for libraries.
103
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
104
+ #poetry.lock
105
+
106
+ # pdm
107
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
108
+ #pdm.lock
109
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
110
+ # in version control.
111
+ # https://pdm.fming.dev/#use-with-ide
112
+ .pdm.toml
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ .venv-dev
128
+ env/
129
+ venv/
130
+ ENV/
131
+ env.bak/
132
+ venv.bak/
133
+
134
+ # Spyder project settings
135
+ .spyderproject
136
+ .spyproject
137
+
138
+ # Rope project settings
139
+ .ropeproject
140
+
141
+ # mkdocs documentation
142
+ /site
143
+
144
+ # mypy
145
+ .mypy_cache/
146
+ .dmypy.json
147
+ dmypy.json
148
+
149
+ # Pyre type checker
150
+ .pyre/
151
+
152
+ # pytype static type analyzer
153
+ .pytype/
154
+
155
+ # Cython debug symbols
156
+ cython_debug/
157
+
158
+ # PyCharm
159
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
160
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
161
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
162
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
163
+ #.idea/
@@ -0,0 +1,29 @@
1
+ # Read the Docs configuration file for Sphinx projects
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ # Required
5
+ version: 2
6
+
7
+ # Set the OS, Python version and other tools you might need
8
+ build:
9
+ os: ubuntu-22.04
10
+ tools:
11
+ python: "3.12"
12
+
13
+ # Build documentation in the "docs/" directory with Sphinx
14
+ sphinx:
15
+ configuration: docs/conf.py
16
+
17
+ # Optionally build your docs in additional formats such as PDF and ePub
18
+ formats:
19
+ - pdf
20
+ - epub
21
+
22
+ # Optional but recommended, declare the Python requirements required
23
+ # to build your documentation
24
+ # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
25
+ python:
26
+ install:
27
+ - requirements: docs/requirements.txt
28
+ - method: pip
29
+ path: .
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present Praneeth Namburi <praneeth.namburi@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.1
2
+ Name: datanavigator
3
+ Version: 1.0.0
4
+ Summary: Interactive data visualization for signals, videos, and complex data objects.
5
+ Author-email: Praneeth Namburi <praneeth.namburi@gmail.com>
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Topic :: Scientific/Engineering
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: Implementation :: CPython
19
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
20
+ Requires-Dist: numpy
21
+ Requires-Dist: pandas
22
+ Requires-Dist: matplotlib
23
+ Requires-Dist: opencv-contrib-python
24
+ Requires-Dist: portion
25
+ Requires-Dist: ffmpeg-python
26
+ Requires-Dist: pysampled
27
+ Requires-Dist: decord
28
+ Requires-Dist: tables
29
+ Project-URL: Home, https://github.com/praneethnamburi/datanavigator
30
+
31
+ # datanavigator
32
+
33
+ [![src](https://img.shields.io/badge/src-github-blue)](https://github.com/praneethnamburi/datanavigator)
34
+ [![PyPI - Version](https://img.shields.io/pypi/v/datanavigator.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/datanavigator/)
35
+ [![Documentation Status](https://readthedocs.org/projects/datanavigator/badge/?version=latest)](https://datanavigator.readthedocs.io)
36
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/praneethnamburi/datanavigator/main/LICENSE)
37
+
38
+ *Interactive data visualization for signals, videos, and complex data objects.*
39
+
40
+ `datanavigator` is a matplotlib-based toolkit for interactive data visualization that handles signals, videos, and complex data objects. It provides both simple tools for navigating data with minimal programming and a user-friendly API for building sophisticated data interaction applications. This versatility makes it both powerful and accessible, regardless of a user's programming expertise.
41
+
42
+ ## Installation
43
+
44
+ ```sh
45
+ pip install datanavigator
46
+ ```
47
+
48
+ If you encounter dependency issues, use the `requirements.yml` file with conda to either create a new environment or update your existing environment. Then, run the command above to install `datanavigator`.
49
+
50
+ ```sh
51
+ git clone https://github.com/praneethnamburi/datanavigator.git
52
+ cd datanavigator
53
+ conda env create -n env-datanavigator -f requirements.yml
54
+ conda activate env-datanavigator
55
+ pip install datanavigator
56
+ ```
57
+
58
+ ## Quickstart
59
+
60
+ ### 1. Browse video frames and extract a clip
61
+ ```python
62
+ import datanavigator as dnav
63
+
64
+ video_browser = dnav.VideoBrowser(dnav.get_example_video())
65
+ # Use the arrow keys to browse through frames.
66
+ # Press Ctrl+K to bring up a list of available keyboard shortcuts
67
+ # To extract a clip,
68
+ # 1. navigate to the start frame and press 1
69
+ # 2. navigate to the end frame and press 2
70
+ # 3. press e to save the extracted clip
71
+ # run dnav.get_clip_folder() to find the saved video clip
72
+
73
+ # Or, you can extract a clip from the command line
74
+ clip_path = video_browser.extract_clip(start_frame=100, end_frame=200)
75
+ print(f"Extracted clip saved to: {clip_path}")
76
+ ```
77
+
78
+ ### 2. Browse time series data and mark events of interest
79
+ ```python
80
+ import datanavigator as dnav
81
+ signal_browser = dnav.EventPickerDemo()
82
+ ```
83
+
84
+ ## License
85
+
86
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
87
+
88
+
89
+ ## Contact
90
+
91
+ [Praneeth Namburi](https://praneethnamburi.com)
92
+
93
+ Project Link: [https://github.com/praneethnamburi/datanavigator](https://github.com/praneethnamburi/datanavigator)
94
+
95
+
96
+ ## Acknowledgments
97
+
98
+ This tool was developed as part of the ImmersionToolbox initiative at the [MIT.nano Immersion Lab](https://immersion.mit.edu). Thanks to NCSOFT for supporting this initiative.
99
+
@@ -0,0 +1,68 @@
1
+ # datanavigator
2
+
3
+ [![src](https://img.shields.io/badge/src-github-blue)](https://github.com/praneethnamburi/datanavigator)
4
+ [![PyPI - Version](https://img.shields.io/pypi/v/datanavigator.svg?logo=pypi&label=PyPI&logoColor=gold)](https://pypi.org/project/datanavigator/)
5
+ [![Documentation Status](https://readthedocs.org/projects/datanavigator/badge/?version=latest)](https://datanavigator.readthedocs.io)
6
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/praneethnamburi/datanavigator/main/LICENSE)
7
+
8
+ *Interactive data visualization for signals, videos, and complex data objects.*
9
+
10
+ `datanavigator` is a matplotlib-based toolkit for interactive data visualization that handles signals, videos, and complex data objects. It provides both simple tools for navigating data with minimal programming and a user-friendly API for building sophisticated data interaction applications. This versatility makes it both powerful and accessible, regardless of a user's programming expertise.
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ pip install datanavigator
16
+ ```
17
+
18
+ If you encounter dependency issues, use the `requirements.yml` file with conda to either create a new environment or update your existing environment. Then, run the command above to install `datanavigator`.
19
+
20
+ ```sh
21
+ git clone https://github.com/praneethnamburi/datanavigator.git
22
+ cd datanavigator
23
+ conda env create -n env-datanavigator -f requirements.yml
24
+ conda activate env-datanavigator
25
+ pip install datanavigator
26
+ ```
27
+
28
+ ## Quickstart
29
+
30
+ ### 1. Browse video frames and extract a clip
31
+ ```python
32
+ import datanavigator as dnav
33
+
34
+ video_browser = dnav.VideoBrowser(dnav.get_example_video())
35
+ # Use the arrow keys to browse through frames.
36
+ # Press Ctrl+K to bring up a list of available keyboard shortcuts
37
+ # To extract a clip,
38
+ # 1. navigate to the start frame and press 1
39
+ # 2. navigate to the end frame and press 2
40
+ # 3. press e to save the extracted clip
41
+ # run dnav.get_clip_folder() to find the saved video clip
42
+
43
+ # Or, you can extract a clip from the command line
44
+ clip_path = video_browser.extract_clip(start_frame=100, end_frame=200)
45
+ print(f"Extracted clip saved to: {clip_path}")
46
+ ```
47
+
48
+ ### 2. Browse time series data and mark events of interest
49
+ ```python
50
+ import datanavigator as dnav
51
+ signal_browser = dnav.EventPickerDemo()
52
+ ```
53
+
54
+ ## License
55
+
56
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
57
+
58
+
59
+ ## Contact
60
+
61
+ [Praneeth Namburi](https://praneethnamburi.com)
62
+
63
+ Project Link: [https://github.com/praneethnamburi/datanavigator](https://github.com/praneethnamburi/datanavigator)
64
+
65
+
66
+ ## Acknowledgments
67
+
68
+ This tool was developed as part of the ImmersionToolbox initiative at the [MIT.nano Immersion Lab](https://immersion.mit.edu). Thanks to NCSOFT for supporting this initiative.
@@ -0,0 +1,133 @@
1
+ r"""
2
+ Interactive data visualization for signals, videos, and complex data objects.
3
+
4
+ Browsers
5
+
6
+ - :py:class:`GenericBrowser`: Generic class to browse data. Meant to be extended.
7
+ - :py:class:`SignalBrowser`: Browse an array of pysampled.Data elements, or 2D arrays.
8
+ - :py:class:`PlotBrowser`: Scroll through an array of complex data where a plotting function is defined for each element.
9
+ - :py:class:`VideoBrowser`: Scroll through the frames of a video.
10
+ - :py:class:`VideoPlotBrowser`: Browse through video and 1D signals synced to the video side by side.
11
+ - :py:class:`ComponentBrowser`: Browse signals (e.g., from periodic motion) as scatterplots of components (e.g., from UMAP, PCA).
12
+
13
+
14
+ Point tracking
15
+
16
+ - :py:class:`Video`: Extended VideoReader class with additional functionalities (helper for VideoPointAnnotator).
17
+ - :py:class:`VideoAnnotation`: Manage one point annotation layer in a video.
18
+ - :py:class:`VideoAnnotations`: Manager for multiple video annotation layers.
19
+ - :py:class:`VideoPointAnnotator`: Annotate points in a video.
20
+
21
+ Optical flow
22
+
23
+ - :py:func:`lucas_kanade`: Track points in a video using the Lucas-Kanade algorithm.
24
+ - :py:func:`lucas_kanade_rstc`: Track points in a video using Lucas-Kanade with reverse sigmoid tracking correction.
25
+ - :py:func:`test_lucas_kanade_rstc`: Test function for Lucas-Kanade with reverse sigmoid tracking correction.
26
+
27
+ Assets
28
+
29
+ - :py:class:`Button`: Custom button widget with a 'name' state.
30
+ - :py:class:`StateButton`: Button widget that stores a number/coordinate state.
31
+ - :py:class:`ToggleButton`: Button widget with a toggle state.
32
+ - :py:class:`Selector`: Select points in a plot using the lasso selection widget.
33
+ - :py:class:`StateVariable`: Manage state variables with multiple states.
34
+ - :py:class:`EventData`: Manage the data from one event type in one trial.
35
+ - :py:class:`Event`: Manage selection of a sequence of events.
36
+
37
+ Assetcontainers
38
+
39
+ - :py:class:`AssetContainer`: Container for managing assets such as buttons, memory slots, etc.
40
+ - :py:class:`Buttons`: Manager for buttons in a matplotlib figure or GUI.
41
+ - :py:class:`Selectors`: Manager for selector objects for picking points on line2D objects.
42
+ - :py:class:`MemorySlots`: Manager for memory slots to store and navigate positions.
43
+ - :py:class:`StateVariables`: Manager for state variables.
44
+ - :py:class:`Events`: Manager for event objects.
45
+ """
46
+ import os
47
+ import sys
48
+ import shutil
49
+
50
+ from .__version__ import __version__
51
+
52
+ from ._config import (
53
+ get_cache_folder,
54
+ get_clip_folder,
55
+ set_cache_folder,
56
+ set_clip_folder,
57
+ )
58
+ from .assets import (
59
+ AssetContainer,
60
+ Button,
61
+ Buttons,
62
+ MemorySlots,
63
+ Selector,
64
+ Selectors,
65
+ StateButton,
66
+ StateVariable,
67
+ StateVariables,
68
+ ToggleButton,
69
+ )
70
+ from .events import portion, Event, EventData, Events
71
+
72
+ from .core import GenericBrowser
73
+ from .plots import PlotBrowser
74
+ from .signals import SignalBrowser
75
+ from .videos import VideoBrowser, VideoPlotBrowser
76
+ from .components import ComponentBrowser
77
+
78
+ from .opticalflow import lucas_kanade, lucas_kanade_rstc
79
+ from .pointtracking import VideoAnnotation, VideoAnnotations, VideoPointAnnotator
80
+
81
+ from .utils import (
82
+ TextView,
83
+ Video,
84
+ get_palette,
85
+ is_path_exists_or_creatable,
86
+ is_video,
87
+ ticks_from_times,
88
+ )
89
+
90
+ from .examples import (
91
+ get_example_video,
92
+ EventPickerDemo,
93
+ ButtonDemo,
94
+ SelectorDemo,
95
+ )
96
+
97
+
98
+ def _check_ffmpeg():
99
+ def check_command(command):
100
+ """Check if a command is available in the system's PATH."""
101
+ return shutil.which(command) is not None
102
+
103
+ def print_install_instructions():
104
+ """Print installation instructions for ffmpeg and ffprobe."""
105
+ if sys.platform.startswith("win"):
106
+ print("\nFFmpeg is not installed or not in PATH.")
107
+ print("Download it from: https://ffmpeg.org/download.html")
108
+ print("After installation, add FFmpeg's 'bin' folder to the system PATH.")
109
+ else:
110
+ print("\nFFmpeg is not installed or not in PATH.")
111
+ print("On Debian/Ubuntu, install it with: sudo apt install ffmpeg")
112
+ print("On macOS, install it with: brew install ffmpeg")
113
+ print("On Fedora, install it with: sudo dnf install ffmpeg")
114
+ print("On Arch Linux, install it with: sudo pacman -S ffmpeg")
115
+
116
+ # Check if ffmpeg and ffprobe are available
117
+ ffmpeg_found = check_command("ffmpeg")
118
+
119
+ if not ffmpeg_found:
120
+ print("Cound not find ffmpeg.")
121
+ print_install_instructions()
122
+
123
+
124
+ def _check_clip_folder():
125
+ if not os.path.exists(get_clip_folder()):
126
+ folder = os.getcwd()
127
+ print(f"Using the current working directory-{folder}-for storing video clips.")
128
+ set_clip_folder(folder)
129
+ print("To change, use datanavigator.set_clip_folder(<folder_name>)")
130
+
131
+
132
+ _check_ffmpeg()
133
+ _check_clip_folder()
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"
@@ -0,0 +1,53 @@
1
+ """
2
+ This module provides functions to set and get the paths for the clip and cache folders.
3
+
4
+ The clip folder is used to store video clips, for example, when using VideoBrowser.
5
+ The cache folder is used by the :py:mod:`datanavigator.examples` to write json file containing marked events.
6
+ """
7
+
8
+ import os
9
+ import logging
10
+
11
+ # Configure logging
12
+ logging.basicConfig(level=logging.INFO)
13
+
14
+ # Use environment variables for default paths
15
+ CLIP_FOLDER: str = os.getenv("CLIP_FOLDER", "C:\\data\\_clipcollection")
16
+ CACHE_FOLDER: str = os.getenv("CACHE_FOLDER", "C:\\data\\_cache")
17
+
18
+
19
+ def set_clip_folder(folder: str) -> None:
20
+ """Set the path for storing video clips."""
21
+ if not os.path.exists(folder):
22
+ raise ValueError(f"The provided folder path does not exist: {folder}")
23
+
24
+ global CLIP_FOLDER
25
+ CLIP_FOLDER = folder
26
+ logging.info(f"Clip folder set to: {CLIP_FOLDER}")
27
+
28
+ global CACHE_FOLDER
29
+ if not os.path.exists(CACHE_FOLDER):
30
+ logging.info(
31
+ "Setting the cache folder to be the same as the clip folder. To change, use set_cache_folder(<folder_name>)."
32
+ )
33
+ CACHE_FOLDER = folder
34
+
35
+
36
+ def get_clip_folder() -> str:
37
+ """Get the current path of the clip folder."""
38
+ return CLIP_FOLDER
39
+
40
+
41
+ def set_cache_folder(folder: str) -> None:
42
+ """Set the path for the cache folder."""
43
+ if not os.path.exists(folder):
44
+ raise ValueError(f"The provided folder path does not exist: {folder}")
45
+
46
+ global CACHE_FOLDER
47
+ CACHE_FOLDER = folder
48
+ logging.info(f"Cache folder set to: {CACHE_FOLDER}")
49
+
50
+
51
+ def get_cache_folder() -> str:
52
+ """Get the current path of the cache folder."""
53
+ return CACHE_FOLDER