thebundle 0.0.1__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 (71) hide show
  1. thebundle-0.0.1/.github/workflows/python-macos.yml +28 -0
  2. thebundle-0.0.1/.github/workflows/python-ubuntu.yml +28 -0
  3. thebundle-0.0.1/.github/workflows/python-windows.yml +28 -0
  4. thebundle-0.0.1/.gitignore +180 -0
  5. thebundle-0.0.1/LICENSE +18 -0
  6. thebundle-0.0.1/PKG-INFO +22 -0
  7. thebundle-0.0.1/README.md +40 -0
  8. thebundle-0.0.1/demo/add_license.py +69 -0
  9. thebundle-0.0.1/demo/black.py +23 -0
  10. thebundle-0.0.1/demo/clean_pycache.py +30 -0
  11. thebundle-0.0.1/demo/record.py +76 -0
  12. thebundle-0.0.1/pyproject.toml +33 -0
  13. thebundle-0.0.1/setup.cfg +4 -0
  14. thebundle-0.0.1/src/bundle/__init__.py +38 -0
  15. thebundle-0.0.1/src/bundle/_version.py +16 -0
  16. thebundle-0.0.1/src/bundle/data/README.md +133 -0
  17. thebundle-0.0.1/src/bundle/data/__init__.py +39 -0
  18. thebundle-0.0.1/src/bundle/data/data.py +147 -0
  19. thebundle-0.0.1/src/bundle/data/json.py +273 -0
  20. thebundle-0.0.1/src/bundle/entity/README.md +59 -0
  21. thebundle-0.0.1/src/bundle/entity/__init__.py +21 -0
  22. thebundle-0.0.1/src/bundle/entity/entity.py +69 -0
  23. thebundle-0.0.1/src/bundle/logs/__init__.py +123 -0
  24. thebundle-0.0.1/src/bundle/process/README.md +92 -0
  25. thebundle-0.0.1/src/bundle/process/__init__.py +27 -0
  26. thebundle-0.0.1/src/bundle/process/_abc.py +59 -0
  27. thebundle-0.0.1/src/bundle/process/asynchronous.py +114 -0
  28. thebundle-0.0.1/src/bundle/process/synchronous.py +119 -0
  29. thebundle-0.0.1/src/bundle/tasks/README.md +51 -0
  30. thebundle-0.0.1/src/bundle/tasks/__init__.py +29 -0
  31. thebundle-0.0.1/src/bundle/tasks/_abc.py +49 -0
  32. thebundle-0.0.1/src/bundle/tasks/asynchronous.py +41 -0
  33. thebundle-0.0.1/src/bundle/tasks/synchronous.py +41 -0
  34. thebundle-0.0.1/src/bundle/tests/__init__.py +31 -0
  35. thebundle-0.0.1/src/bundle/tests/tools/__init__.py +34 -0
  36. thebundle-0.0.1/src/bundle/tests/tools/assertions.py +47 -0
  37. thebundle-0.0.1/src/bundle/tests/tools/cprofile.py +95 -0
  38. thebundle-0.0.1/src/bundle/tests/tools/data.py +52 -0
  39. thebundle-0.0.1/src/bundle/tests/tools/data_json.py +102 -0
  40. thebundle-0.0.1/src/bundle/tests/tools/entity.py +26 -0
  41. thebundle-0.0.1/src/bundle/tests/tools/process.py +91 -0
  42. thebundle-0.0.1/src/bundle/tests/tools/tasks.py +87 -0
  43. thebundle-0.0.1/src/references/windows/ref/JSONData.json +3 -0
  44. thebundle-0.0.1/src/references/windows/ref/NestedDatajson.json +9 -0
  45. thebundle-0.0.1/src/references/windows/ref/TestAsyncProcess.json +16 -0
  46. thebundle-0.0.1/src/references/windows/ref/TestAsyncTask.json +12 -0
  47. thebundle-0.0.1/src/references/windows/ref/TestEntity.json +10 -0
  48. thebundle-0.0.1/src/references/windows/ref/TestProcess.json +16 -0
  49. thebundle-0.0.1/src/references/windows/ref/TestStreamingAsyncProcess.json +16 -0
  50. thebundle-0.0.1/src/references/windows/ref/TestStreamingProcess.json +16 -0
  51. thebundle-0.0.1/src/references/windows/ref/TestTask.json +12 -0
  52. thebundle-0.0.1/src/references/windows/schema/JSONData.json +13 -0
  53. thebundle-0.0.1/src/references/windows/schema/NestedDatajson.json +39 -0
  54. thebundle-0.0.1/src/references/windows/schema/TestAsyncProcess.json +70 -0
  55. thebundle-0.0.1/src/references/windows/schema/TestAsyncTask.json +54 -0
  56. thebundle-0.0.1/src/references/windows/schema/TestEntity.json +46 -0
  57. thebundle-0.0.1/src/references/windows/schema/TestProcess.json +70 -0
  58. thebundle-0.0.1/src/references/windows/schema/TestStreamingAsyncProcess.json +70 -0
  59. thebundle-0.0.1/src/references/windows/schema/TestStreamingProcess.json +70 -0
  60. thebundle-0.0.1/src/references/windows/schema/TestTask.json +54 -0
  61. thebundle-0.0.1/src/thebundle.egg-info/PKG-INFO +22 -0
  62. thebundle-0.0.1/src/thebundle.egg-info/SOURCES.txt +69 -0
  63. thebundle-0.0.1/src/thebundle.egg-info/dependency_links.txt +1 -0
  64. thebundle-0.0.1/src/thebundle.egg-info/requires.txt +19 -0
  65. thebundle-0.0.1/src/thebundle.egg-info/top_level.txt +2 -0
  66. thebundle-0.0.1/tests/__init__.py +11 -0
  67. thebundle-0.0.1/tests/test_data.py +37 -0
  68. thebundle-0.0.1/tests/test_entity.py +19 -0
  69. thebundle-0.0.1/tests/test_process.py +54 -0
  70. thebundle-0.0.1/tests/test_tasks.py +33 -0
  71. thebundle-0.0.1/thebundle.png +0 -0
@@ -0,0 +1,28 @@
1
+ name: macOS
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: macos-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: [3.10, 3.11, 3.12]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v3
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install .[test]
25
+
26
+ - name: Run tests
27
+ run: |
28
+ pytest tests/
@@ -0,0 +1,28 @@
1
+ name: Ubuntu
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: [3.10, 3.11, 3.12]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v3
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install .[test]
25
+
26
+ - name: Run tests
27
+ run: |
28
+ pytest tests/
@@ -0,0 +1,28 @@
1
+ name: Windows
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: windows-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: [3.10, 3.11, 3.12]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v3
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install .[test]
25
+
26
+ - name: Run tests
27
+ run: |
28
+ pytest tests/
@@ -0,0 +1,180 @@
1
+ venv
2
+ wenv
3
+
4
+ build
5
+
6
+ # Byte-compiled / optimized / DLL files
7
+ __pycache__/
8
+ *.py[cod]
9
+ *$py.class
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py,cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ .pybuilder/
81
+ target/
82
+
83
+ # Jupyter Notebook
84
+ .ipynb_checkpoints
85
+
86
+ # IPython
87
+ profile_default/
88
+ ipython_config.py
89
+
90
+ # pyenv
91
+ # For a library or package, you might want to ignore these files since the code is
92
+ # intended to run in multiple environments; otherwise, check them in:
93
+ # .python-version
94
+
95
+ # pipenv
96
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
97
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
98
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
99
+ # install all needed dependencies.
100
+ #Pipfile.lock
101
+
102
+ # poetry
103
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
104
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
105
+ # commonly ignored for libraries.
106
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
107
+ #poetry.lock
108
+
109
+ # pdm
110
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
111
+ #pdm.lock
112
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
113
+ # in version control.
114
+ # https://pdm.fming.dev/#use-with-ide
115
+ .pdm.toml
116
+
117
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
118
+ __pypackages__/
119
+
120
+ # Celery stuff
121
+ celerybeat-schedule
122
+ celerybeat.pid
123
+
124
+ # SageMath parsed files
125
+ *.sage.py
126
+
127
+ # Environments
128
+ .env
129
+ .venv
130
+ env/
131
+ venv/
132
+ ENV/
133
+ env.bak/
134
+ venv.bak/
135
+
136
+ # Spyder project settings
137
+ .spyderproject
138
+ .spyproject
139
+
140
+ # Rope project settings
141
+ .ropeproject
142
+
143
+ # mkdocs documentation
144
+ /site
145
+
146
+ # mypy
147
+ .mypy_cache/
148
+ .dmypy.json
149
+ dmypy.json
150
+
151
+ # Pyre type checker
152
+ .pyre/
153
+
154
+ # pytype static type analyzer
155
+ .pytype/
156
+
157
+ # Cython debug symbols
158
+ cython_debug/
159
+
160
+ # PyCharm
161
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
162
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
163
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
164
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
165
+ #.idea/
166
+ __pycache__/
167
+ *.egg-info
168
+ *.egg-info/
169
+
170
+ tests/ref/failed
171
+ tests/ref/cprofile
172
+
173
+ logs/
174
+
175
+ *.prof
176
+
177
+ tmp/
178
+ .vscode/
179
+
180
+ src/bundle/_version.py
@@ -0,0 +1,18 @@
1
+ Copyright 2023 HorusElohim
2
+
3
+ Licensed to the Apache Software Foundation (ASF) under one
4
+ or more contributor license agreements. See the NOTICE file
5
+ distributed with this work for additional information
6
+ regarding copyright ownership. The ASF licenses this file
7
+ to you under the Apache License, Version 2.0 (the
8
+ "License"); you may not use this file except in compliance
9
+ with the License. You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing,
14
+ software distributed under the License is distributed on an
15
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ KIND, either express or implied. See the License for the
17
+ specific language governing permissions and limitations
18
+ under the License.
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.1
2
+ Name: thebundle
3
+ Version: 0.0.1
4
+ Summary: Python TheBundle essential code.
5
+ Requires-Python: >=3.10
6
+ License-File: LICENSE
7
+ Requires-Dist: requests
8
+ Requires-Dist: jsonschema
9
+ Requires-Dist: setuptools_scm
10
+ Provides-Extra: test
11
+ Requires-Dist: pytest; extra == "test"
12
+ Requires-Dist: coverage; extra == "test"
13
+ Requires-Dist: radon; extra == "test"
14
+ Requires-Dist: flake8; extra == "test"
15
+ Requires-Dist: black; extra == "test"
16
+ Requires-Dist: isort; extra == "test"
17
+ Requires-Dist: mypy; extra == "test"
18
+ Provides-Extra: dev
19
+ Requires-Dist: snakeviz; extra == "dev"
20
+ Provides-Extra: pypi
21
+ Requires-Dist: build; extra == "pypi"
22
+ Requires-Dist: twine; extra == "pypi"
@@ -0,0 +1,40 @@
1
+
2
+ # BUNDLE: The Next-Generation Python Toolkit
3
+
4
+ ![The Bundle Dream](thebundle.png)
5
+
6
+
7
+ ## Getting Started
8
+
9
+ Embark on your BUNDLE journey:
10
+ 1. Install BUNDLE: `pip install thebundle`
11
+ 2. Explore our extensive documentation for more insights.
12
+ 3. Experiment with our test suite to see BUNDLE in action.
13
+
14
+
15
+ Welcome to BUNDLE, a comprehensive Python package designed to enhance various aspects of coding, from data handling and entity management to process control and task execution. BUNDLE streamlines complex tasks, offering robust and efficient solutions for both synchronous and asynchronous operations.
16
+
17
+ ### [data](src/bundle/data/README.md)
18
+ The data subpackage provides advanced data handling capabilities, focusing on easy conversions between Python data classes and dictionaries, JSON serialization/deserialization, and JSON schema validations.
19
+
20
+ ### [entity](src/bundle/entity/README.md)
21
+ This subpackage introduces an advanced Entity class, an enhanced data structure that serves as a base for developing more complex classes with additional features like lifecycle timestamps and auto-saving capabilities.
22
+
23
+ ### [tasks](src/bundle/tasks/README.md)
24
+ This subpackage is dedicated to task management and execution. It includes classes for both synchronous and asynchronous task execution, extending these functionalities to a variety of use cases.
25
+
26
+ ### [process](src/bundle/process/README.md)
27
+ The process subpackage offers sophisticated process handling capabilities, ideal for managing and interacting with system processes in both synchronous and asynchronous contexts.
28
+
29
+
30
+ ### Testing and Tools
31
+ BUNDLE is equipped with a comprehensive testing suite, ensuring reliability and stability across its functionalities. The tests cover all aspects of the package, from data handling to process management.
32
+
33
+ *tests/tools:* Contains various utility functions and tools to support testing, including assertions, profiling, and more.
34
+
35
+ ## License
36
+ BUNDLE is open-sourced under the APACHE-V2 License.
37
+
38
+ ## Join the BUNDLE Revolution!
39
+
40
+ Step into the future of Python development with BUNDLE. Redefine what's possible with your code.
@@ -0,0 +1,69 @@
1
+ import asyncio
2
+ import os
3
+ import bundle
4
+
5
+ LOGGER = bundle.logging.getLogger(__name__)
6
+
7
+ LICENSE_TEXT = """# Copyright 2023 HorusElohim
8
+
9
+ # Licensed to the Apache Software Foundation (ASF) under one
10
+ # or more contributor license agreements. See the NOTICE file
11
+ # distributed with this work for additional information
12
+ # regarding copyright ownership. The ASF licenses this file
13
+ # to you under the Apache License, Version 2.0 (the
14
+ # "License"); you may not use this file except in compliance
15
+ # with the License. You may obtain a copy of the License at
16
+
17
+ # http://www.apache.org/licenses/LICENSE-2.0
18
+
19
+ # Unless required by applicable law or agreed to in writing,
20
+ # software distributed under the License is distributed on an
21
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22
+ # KIND, either express or implied. See the License for the
23
+ # specific language governing permissions and limitations
24
+ # under the License.
25
+ """
26
+
27
+ EXCLUDED_FILE = ["_version.py"]
28
+
29
+
30
+ @bundle.data.dataclass
31
+ class FindPythonFilesTask(bundle.tasks.AsyncTask):
32
+ async def exec(self):
33
+ tasks = []
34
+ for root, _, files in os.walk(self.path):
35
+ for file in files:
36
+ if file.endswith(".py") and file not in EXCLUDED_FILE:
37
+ file_path = os.path.join(root, file)
38
+ task = AddLicenseTask(name="AddLicenseTask", path=file_path)
39
+ tasks.append(task())
40
+ await asyncio.gather(*tasks)
41
+
42
+
43
+ @bundle.data.dataclass
44
+ class AddLicenseTask(bundle.tasks.AsyncTask):
45
+ async def exec(self):
46
+ with open(self.path, "r+", encoding="utf-8") as f:
47
+ content = f.read()
48
+ if "Copyright 2023 HorusElohim" not in content:
49
+ LOGGER.warn("missing LICENSE for %s", self.path)
50
+ f.seek(0, 0)
51
+ f.write(LICENSE_TEXT + "\n\n" + content)
52
+ LOGGER.info("LICENSE added %s", self.path)
53
+
54
+
55
+ async def apply_license_to_files(path):
56
+ find_task = FindPythonFilesTask(name="FindPythonFilesTask", path=path)
57
+ await find_task()
58
+
59
+
60
+ if __name__ == "__main__":
61
+ import click
62
+
63
+ @click.command()
64
+ @click.option("--path", default=bundle.__path__[0], help="Path to apply the license.")
65
+ def main(path):
66
+ """Simple script that applies a license comment to Python files in a given path."""
67
+ asyncio.run(apply_license_to_files(path))
68
+
69
+ main()
@@ -0,0 +1,23 @@
1
+ import click
2
+ import bundle
3
+ import subprocess
4
+
5
+ LOGGER = bundle.logging.getLogger(__name__)
6
+
7
+
8
+ def apply_black_to_file(path: bundle.typing.Union[bundle.Path, str]):
9
+ LOGGER.info("applying black to '%s' ...", path)
10
+ p = bundle.process.Process(command=f"black {path}")
11
+ p(shell=True, text=True)
12
+ LOGGER.info("black applied to '%s' ✅", path)
13
+
14
+
15
+ @click.command()
16
+ @click.option("--path", default=bundle.__path__[0], help="Path to format with Black.")
17
+ def main(path):
18
+ """Simple script that applies Black formatter to a given path."""
19
+ apply_black_to_file(path)
20
+
21
+
22
+ if __name__ == "__main__":
23
+ main()
@@ -0,0 +1,30 @@
1
+ import click
2
+ import bundle
3
+ import shutil
4
+ import os
5
+
6
+ LOGGER = bundle.logging.getLogger(__name__)
7
+
8
+
9
+ @bundle.data.dataclass
10
+ class CleanPyCache(bundle.tasks.Task):
11
+ def exec(self) -> None:
12
+ if not self.path.is_dir():
13
+ raise ValueError(f"The path {self.path} is not a valid directory.")
14
+
15
+ for root, dirs, files in os.walk(self.path):
16
+ if "__pycache__" in dirs:
17
+ pycache_path = bundle.Path(root) / "__pycache__"
18
+ LOGGER.info(f"Removing {pycache_path}")
19
+ shutil.rmtree(pycache_path)
20
+
21
+
22
+ @click.command()
23
+ @click.option("--path", default=bundle.__path__[0], help="Path to format with Black.")
24
+ def main(path):
25
+ """Simple script that clean all the __pycache__ to a given path."""
26
+ CleanPyCache(path=bundle.Path(path))()
27
+
28
+
29
+ if __name__ == "__main__":
30
+ main()
@@ -0,0 +1,76 @@
1
+ import bundle
2
+ import signal
3
+
4
+
5
+ BIN_PATH = bundle.Path(r"C:\FFmpeg\ffmpeg-6.0-essentials_build\bin\ffmpeg.exe")
6
+
7
+
8
+ @bundle.data.dataclass
9
+ class FFmpegRecord(bundle.process.Process):
10
+ bin_path: bundle.Path = bundle.data.field(default_factory=lambda: BIN_PATH)
11
+ format: str = "gdigrab"
12
+ framerate: float = 60
13
+ width: int = 2560
14
+ height: int = 1440
15
+ input: str = "desktop"
16
+ codec: str = "libx264"
17
+ preset: str = "medium"
18
+ pix_fmt: str = "yuv420p"
19
+ output_file: str = "output.mp4"
20
+ audio_codec: str = "aac"
21
+ audio_bitrate: str = "192k"
22
+ audio_channels: int = 2
23
+ audio_sample_rate: int = 44100
24
+ video_bitrate: str = "6000k"
25
+ crf: int = 18 # Lower CRF value means better quality
26
+ tune: str = "zerolatency"
27
+ filters: str = ""
28
+ profile: str = ""
29
+ level: str = ""
30
+ maxrate: str = ""
31
+ bufsize: str = ""
32
+ overwrite: bool = True
33
+ duration: str = ""
34
+ auto_save: bool = True
35
+
36
+ def __post_init__(self):
37
+ super().__post_init__()
38
+ self.command = (
39
+ f"{self.bin_path} "
40
+ f"-f {self.format} "
41
+ f"-framerate {self.framerate} "
42
+ f"-video_size {self.width}x{self.height} "
43
+ f"-i {self.input} "
44
+ f"-c:v {self.codec} "
45
+ f"-b:v {self.video_bitrate} "
46
+ f"-crf {self.crf} "
47
+ f"-preset {self.preset} "
48
+ f"-pix_fmt {self.pix_fmt} "
49
+ f"{f'-tune {self.tune} ' if self.tune else ''}"
50
+ f"{f'-vf {self.filters} ' if self.filters else ''}"
51
+ f"{f'-profile:v {self.profile} ' if self.profile else ''}"
52
+ f"{f'-level {self.level} ' if self.level else ''}"
53
+ f"{f'-maxrate {self.maxrate} ' if self.maxrate else ''}"
54
+ f"{f'-bufsize {self.bufsize} ' if self.bufsize else ''}"
55
+ f"-c:a {self.audio_codec} "
56
+ f"-b:a {self.audio_bitrate} "
57
+ f"-ac {self.audio_channels} "
58
+ f"-ar {self.audio_sample_rate} "
59
+ f"{'-y ' if self.overwrite else ''}"
60
+ f"{f'-t {self.duration} ' if self.duration else ''}"
61
+ f"{self.output_file}"
62
+ )
63
+
64
+
65
+ if __name__ == "__main__":
66
+
67
+ def signal_handler(sig, frame):
68
+ print("Stopping recording...")
69
+ ffrecord.terminate()
70
+
71
+ signal.signal(signal.SIGINT, signal_handler)
72
+
73
+ print("Starting recording. Press Ctrl+C to stop.")
74
+ name = f"Recording_{bundle.datetime.now().strftime('%Y.%m.%d.%H.%M.%S')}"
75
+ ffrecord = FFmpegRecord(name=name)
76
+ ffrecord()
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel", "setuptools_scm", "build"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "thebundle"
7
+ dynamic = ["version"]
8
+ description = "Python TheBundle essential code."
9
+ requires-python = ">=3.10"
10
+ dependencies = ["requests", "jsonschema", "setuptools_scm"]
11
+
12
+ [tool.setuptools_scm]
13
+ version_file = "src/bundle/_version.py"
14
+
15
+ [project.optional-dependencies]
16
+ test = ["pytest", "coverage", "radon", "flake8", "black", "isort", "mypy"]
17
+ dev = ["snakeviz"]
18
+ pypi = ["build", "twine"]
19
+
20
+
21
+ [tool.pytest.ini_options]
22
+ addopts = ["--doctest-modules", "--capture=no"]
23
+ testpaths = ["tests"]
24
+ log_cli = true
25
+ log_cli_level = "DEBUG"
26
+
27
+ [tool.black]
28
+ line-length = 128
29
+ target-version = ['py310']
30
+ include = '\.pyi?$'
31
+
32
+ [tool.flake8]
33
+ max-line-length = 128
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ # Copyright 2023 HorusElohim
2
+
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+
21
+ import time
22
+ from datetime import datetime
23
+ import logging
24
+ import typing
25
+ from pathlib import Path
26
+
27
+ from ._version import version, version_tuple
28
+ from .logs import setup_logging, LOGGING_LEVEL, LogEmoji
29
+
30
+ LOGGER = setup_logging(log_level=LOGGING_LEVEL, to_json=True)
31
+
32
+ from . import data
33
+ from . import entity
34
+ from . import tasks
35
+ from . import process
36
+ from . import tests
37
+
38
+ LOGGER.debug("bundle loaded")
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '0.0.1'
16
+ __version_tuple__ = version_tuple = (0, 0, 1)