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.
- thebundle-0.0.1/.github/workflows/python-macos.yml +28 -0
- thebundle-0.0.1/.github/workflows/python-ubuntu.yml +28 -0
- thebundle-0.0.1/.github/workflows/python-windows.yml +28 -0
- thebundle-0.0.1/.gitignore +180 -0
- thebundle-0.0.1/LICENSE +18 -0
- thebundle-0.0.1/PKG-INFO +22 -0
- thebundle-0.0.1/README.md +40 -0
- thebundle-0.0.1/demo/add_license.py +69 -0
- thebundle-0.0.1/demo/black.py +23 -0
- thebundle-0.0.1/demo/clean_pycache.py +30 -0
- thebundle-0.0.1/demo/record.py +76 -0
- thebundle-0.0.1/pyproject.toml +33 -0
- thebundle-0.0.1/setup.cfg +4 -0
- thebundle-0.0.1/src/bundle/__init__.py +38 -0
- thebundle-0.0.1/src/bundle/_version.py +16 -0
- thebundle-0.0.1/src/bundle/data/README.md +133 -0
- thebundle-0.0.1/src/bundle/data/__init__.py +39 -0
- thebundle-0.0.1/src/bundle/data/data.py +147 -0
- thebundle-0.0.1/src/bundle/data/json.py +273 -0
- thebundle-0.0.1/src/bundle/entity/README.md +59 -0
- thebundle-0.0.1/src/bundle/entity/__init__.py +21 -0
- thebundle-0.0.1/src/bundle/entity/entity.py +69 -0
- thebundle-0.0.1/src/bundle/logs/__init__.py +123 -0
- thebundle-0.0.1/src/bundle/process/README.md +92 -0
- thebundle-0.0.1/src/bundle/process/__init__.py +27 -0
- thebundle-0.0.1/src/bundle/process/_abc.py +59 -0
- thebundle-0.0.1/src/bundle/process/asynchronous.py +114 -0
- thebundle-0.0.1/src/bundle/process/synchronous.py +119 -0
- thebundle-0.0.1/src/bundle/tasks/README.md +51 -0
- thebundle-0.0.1/src/bundle/tasks/__init__.py +29 -0
- thebundle-0.0.1/src/bundle/tasks/_abc.py +49 -0
- thebundle-0.0.1/src/bundle/tasks/asynchronous.py +41 -0
- thebundle-0.0.1/src/bundle/tasks/synchronous.py +41 -0
- thebundle-0.0.1/src/bundle/tests/__init__.py +31 -0
- thebundle-0.0.1/src/bundle/tests/tools/__init__.py +34 -0
- thebundle-0.0.1/src/bundle/tests/tools/assertions.py +47 -0
- thebundle-0.0.1/src/bundle/tests/tools/cprofile.py +95 -0
- thebundle-0.0.1/src/bundle/tests/tools/data.py +52 -0
- thebundle-0.0.1/src/bundle/tests/tools/data_json.py +102 -0
- thebundle-0.0.1/src/bundle/tests/tools/entity.py +26 -0
- thebundle-0.0.1/src/bundle/tests/tools/process.py +91 -0
- thebundle-0.0.1/src/bundle/tests/tools/tasks.py +87 -0
- thebundle-0.0.1/src/references/windows/ref/JSONData.json +3 -0
- thebundle-0.0.1/src/references/windows/ref/NestedDatajson.json +9 -0
- thebundle-0.0.1/src/references/windows/ref/TestAsyncProcess.json +16 -0
- thebundle-0.0.1/src/references/windows/ref/TestAsyncTask.json +12 -0
- thebundle-0.0.1/src/references/windows/ref/TestEntity.json +10 -0
- thebundle-0.0.1/src/references/windows/ref/TestProcess.json +16 -0
- thebundle-0.0.1/src/references/windows/ref/TestStreamingAsyncProcess.json +16 -0
- thebundle-0.0.1/src/references/windows/ref/TestStreamingProcess.json +16 -0
- thebundle-0.0.1/src/references/windows/ref/TestTask.json +12 -0
- thebundle-0.0.1/src/references/windows/schema/JSONData.json +13 -0
- thebundle-0.0.1/src/references/windows/schema/NestedDatajson.json +39 -0
- thebundle-0.0.1/src/references/windows/schema/TestAsyncProcess.json +70 -0
- thebundle-0.0.1/src/references/windows/schema/TestAsyncTask.json +54 -0
- thebundle-0.0.1/src/references/windows/schema/TestEntity.json +46 -0
- thebundle-0.0.1/src/references/windows/schema/TestProcess.json +70 -0
- thebundle-0.0.1/src/references/windows/schema/TestStreamingAsyncProcess.json +70 -0
- thebundle-0.0.1/src/references/windows/schema/TestStreamingProcess.json +70 -0
- thebundle-0.0.1/src/references/windows/schema/TestTask.json +54 -0
- thebundle-0.0.1/src/thebundle.egg-info/PKG-INFO +22 -0
- thebundle-0.0.1/src/thebundle.egg-info/SOURCES.txt +69 -0
- thebundle-0.0.1/src/thebundle.egg-info/dependency_links.txt +1 -0
- thebundle-0.0.1/src/thebundle.egg-info/requires.txt +19 -0
- thebundle-0.0.1/src/thebundle.egg-info/top_level.txt +2 -0
- thebundle-0.0.1/tests/__init__.py +11 -0
- thebundle-0.0.1/tests/test_data.py +37 -0
- thebundle-0.0.1/tests/test_entity.py +19 -0
- thebundle-0.0.1/tests/test_process.py +54 -0
- thebundle-0.0.1/tests/test_tasks.py +33 -0
- 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
|
thebundle-0.0.1/LICENSE
ADDED
|
@@ -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.
|
thebundle-0.0.1/PKG-INFO
ADDED
|
@@ -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
|
+

|
|
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,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)
|