28 Commits

Author SHA1 Message Date
21df4998a2 upd pytest dep version 2024-02-15 18:47:44 +00:00
7bff293820 py 12 added to tox envs 2024-02-08 12:13:30 +00:00
c8d0a0078d adds more logging for getters 2023-10-21 18:02:55 +01:00
87a1d62414 ensure we don't try to join a thread that wasn't created
(in the event of a timeout error)
2023-10-21 07:48:09 +01:00
f863723a4e add group dev (dev-dependencies deprecated) 2023-08-27 19:04:18 +01:00
afa1867abc add poetry badge 2023-08-19 19:56:35 +01:00
fcb656b7d0 reword docstring 2023-08-19 19:56:17 +01:00
9c0e2bef39 2.4.9 section added to CHANGELOG
patch bump
2023-08-13 18:20:28 +01:00
36692d1bc7 fixes error with escape character in regex 2023-08-13 18:16:49 +01:00
753714b639 should the loader attempt to load an invalid toml config
log as error but allow the loader to continue
2023-08-13 18:16:33 +01:00
27a26b8fe9 remove __str__ override 2023-08-13 18:15:31 +01:00
79260a0e47 check vban direction
check that index is numeric

remove button as possible key.
not defined in RT packets anyway

patch bump
2023-08-10 21:24:59 +01:00
f9bcbfa74a patch bump 2023-08-10 19:14:06 +01:00
0f2fb7121d add poetry test scripts for each kind 2023-08-10 19:13:34 +01:00
a635109308 make better use of pattern matching features
error test updated
2023-08-10 19:12:52 +01:00
a61e09b075 avoid using key word as variable name 2023-08-10 19:11:59 +01:00
763e44df12 refactor target
add error test for ValueError

test badges updated

patch bump
2023-08-09 17:03:55 +01:00
69472a783e patch bump 2023-08-07 17:39:39 +01:00
9a1ba06a21 update test badges 2023-08-07 17:39:26 +01:00
14b2ee473a mark config tests as slow 2023-08-07 17:39:13 +01:00
ca2427c29a lowercase identifiers 2023-08-07 17:38:51 +01:00
ebacdcf82a use _cmd() helper method to build cmd string 2023-08-07 17:38:37 +01:00
7416108489 add error tests 2023-08-07 16:31:19 +01:00
bd6e57b3c6 define message attribute for VBANCMD error classes
override str magic method
2023-08-07 16:31:08 +01:00
eed036ca03 patch bump 2023-08-05 14:06:47 +01:00
55211b9b19 replace generator function with factory function 2023-08-05 14:06:39 +01:00
4af7c0f694 initialize stop_event to None
in case outbound mode enabled
2023-08-05 14:05:18 +01:00
f082fa8ac5 reword 2023-08-05 13:40:32 +01:00
24 changed files with 314 additions and 166 deletions

View File

@@ -11,6 +11,18 @@ Before any major/minor/patch bump all unit tests will be run to verify they pass
- [x]
## [2.4.9] - 2023-08-13
### Added
- Error tests added in tests/test_errors.py
- Errors section in README updated.
### Changed
- VBANCMDConnectionError class now subclasses VBANCMDError
- If the configs loader is passed an invalid config TOML it will log an error but continue to load further configs into memory.
## [2.3.2] - 2023-07-12
### Added

View File

@@ -1,5 +1,6 @@
[![PyPI version](https://badge.fury.io/py/vban-cmd.svg)](https://badge.fury.io/py/vban-cmd)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/onyx-and-iris/vban-cmd-python/blob/dev/LICENSE)
[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
![Tests Status](./tests/basic.svg?dummy=8484744)
@@ -94,6 +95,7 @@ def main():
{
"strip-2": {"A1": True, "B1": True, "gain": -6.0},
"bus-2": {"mute": True, "eq": {"on": True}},
"vban-in-0": {"on": True},
}
)
@@ -355,6 +357,7 @@ vban.apply(
"strip-0": {"A1": True, "B1": True, "gain": -6.0},
"bus-1": {"mute": True, "mode": "composite"},
"bus-2": {"eq": {"on": True}},
"vban-in-0": {"on": True},
}
)
```
@@ -511,7 +514,7 @@ States not guaranteed to be current (requires use of dirty parameters to confirm
## Errors
- `errors.VBANCMDError`: Exception raised when general errors occur.
- `errors.VBANCMDError`: Base VBANCMD Exception class.
- `errors.VBANCMDConnectionError`: Exception raised when connection/timeout errors occur.
## Logging

View File

@@ -37,6 +37,7 @@ def main():
{
"strip-2": {"A1": True, "B1": True, "gain": -6.0},
"bus-2": {"mute": True},
"vban-in-0": {"on": True},
}
)

224
poetry.lock generated
View File

@@ -1,24 +1,36 @@
[[package]]
name = "attrs"
version = "22.1.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=3.5"
[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"]
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
[[package]]
name = "black"
version = "22.8.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.6.2"
files = [
{file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"},
{file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"},
{file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"},
{file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"},
{file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"},
{file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"},
{file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"},
{file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"},
{file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"},
{file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"},
{file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"},
{file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"},
{file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"},
{file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"},
{file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"},
{file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"},
{file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"},
{file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"},
{file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"},
{file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"},
{file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"},
]
[package.dependencies]
click = ">=8.0.0"
@@ -37,25 +49,34 @@ uvloop = ["uvloop (>=0.15.2)"]
name = "cachetools"
version = "5.3.1"
description = "Extensible memoizing collections and decorators"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"},
{file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"},
]
[[package]]
name = "chardet"
version = "5.1.0"
description = "Universal encoding detector for Python 3"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"},
{file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"},
]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
@@ -64,151 +85,195 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "distlib"
version = "0.3.6"
description = "Distribution utilities"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
{file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
{file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "filelock"
version = "3.12.2"
description = "A platform independent file lock."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
{file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
]
[package.extras]
docs = ["furo (>=2023.5.20)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)", "sphinx (>=7.0.1)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)", "pytest (>=7.3.1)"]
docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
[[package]]
name = "isort"
version = "5.10.1"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
python-versions = ">=3.6.1,<4.0"
files = [
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
]
[package.extras]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
pipfile-deprecated-finder = ["pipreqs", "requirementslib"]
plugins = ["setuptools"]
requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
[[package]]
name = "packaging"
version = "23.1"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
]
[[package]]
name = "pathspec"
version = "0.10.1"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"},
{file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"},
]
[[package]]
name = "platformdirs"
version = "3.7.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-3.7.0-py3-none-any.whl", hash = "sha256:cfd065ba43133ff103ab3bd10aecb095c2a0035fcd1f07217c9376900d94ba07"},
{file = "platformdirs-3.7.0.tar.gz", hash = "sha256:87fbf6473e87c078d536980ba970a472422e94f17b752cfad17024c18876d481"},
]
[package.extras]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)", "sphinx (>=7.0.1)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest (>=7.3.1)"]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "py"
version = "1.11.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pyproject-api"
version = "1.5.2"
description = "API to interact with the python pyproject.toml based projects"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyproject_api-1.5.2-py3-none-any.whl", hash = "sha256:9cffcbfb64190f207444d7579d315f3278f2c04ba46d685fad93197b5326d348"},
{file = "pyproject_api-1.5.2.tar.gz", hash = "sha256:999f58fa3c92b23ebd31a6bad5d1f87d456744d75e05391be7f5c729015d3d91"},
]
[package.dependencies]
packaging = ">=23.1"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
[package.extras]
docs = ["furo (>=2023.5.20)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)", "sphinx (>=7.0.1)"]
testing = ["covdefaults (>=2.3)", "importlib-metadata (>=6.6)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest (>=7.3.1)", "setuptools (>=67.8)", "wheel (>=0.40)"]
docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "importlib-metadata (>=6.6)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "setuptools (>=67.8)", "wheel (>=0.40)"]
[[package]]
name = "pytest"
version = "7.1.3"
version = "7.4.4"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
{file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
]
[package.dependencies]
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
py = ">=1.8.2"
tomli = ">=1.0.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "pytest-randomly"
version = "3.12.0"
description = "Pytest plugin to randomly order tests and control random.seed."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-randomly-3.12.0.tar.gz", hash = "sha256:d60c2db71ac319aee0fc6c4110a7597d611a8b94a5590918bfa8583f00caccb2"},
{file = "pytest_randomly-3.12.0-py3-none-any.whl", hash = "sha256:f4f2e803daf5d1ba036cc22bf4fe9dbbf99389ec56b00e5cba732fb5c1d07fdd"},
]
[package.dependencies]
pytest = "*"
@@ -217,9 +282,12 @@ pytest = "*"
name = "pytest-repeat"
version = "0.9.1"
description = "pytest plugin for repeating tests"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "pytest-repeat-0.9.1.tar.gz", hash = "sha256:5cd3289745ab3156d43eb9c8e7f7d00a926f3ae5c9cf425bec649b2fe15bad5b"},
{file = "pytest_repeat-0.9.1-py2.py3-none-any.whl", hash = "sha256:4474a7d9e9137f6d8cc8ae297f8c4168d33c56dd740aa78cfffe562557e6b96e"},
]
[package.dependencies]
pytest = ">=3.6"
@@ -228,17 +296,23 @@ pytest = ">=3.6"
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]]
name = "tox"
version = "4.6.3"
description = "tox is a generic virtualenv management and test command line tool"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "tox-4.6.3-py3-none-any.whl", hash = "sha256:2946a0bb38924c3a9f9575c7fb4ca1f4c11a7c69c61592f176778892155cb50c"},
{file = "tox-4.6.3.tar.gz", hash = "sha256:9e2c5091a117d03b583c57c4c40aecd068099c17d40520e7b165e85c19334534"},
]
[package.dependencies]
cachetools = ">=5.3.1"
@@ -253,16 +327,19 @@ tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
virtualenv = ">=20.23.1"
[package.extras]
docs = ["furo (>=2023.5.20)", "sphinx-argparse-cli (>=1.11.1)", "sphinx-autodoc-typehints (>=1.23.2,!=1.23.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinx (>=7.0.1)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.1.1)", "devpi-process (>=0.3.1)", "diff-cover (>=7.6)", "distlib (>=0.3.6)", "flaky (>=3.7)", "hatch-vcs (>=0.3)", "hatchling (>=1.17.1)", "psutil (>=5.9.5)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-xdist (>=3.3.1)", "pytest (>=7.3.2)", "re-assert (>=1.1)", "time-machine (>=2.10)", "wheel (>=0.40)"]
docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-argparse-cli (>=1.11.1)", "sphinx-autodoc-typehints (>=1.23.2,!=1.23.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.1.1)", "devpi-process (>=0.3.1)", "diff-cover (>=7.6)", "distlib (>=0.3.6)", "flaky (>=3.7)", "hatch-vcs (>=0.3)", "hatchling (>=1.17.1)", "psutil (>=5.9.5)", "pytest (>=7.3.2)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-xdist (>=3.3.1)", "re-assert (>=1.1)", "time-machine (>=2.10)", "wheel (>=0.40)"]
[[package]]
name = "virtualenv"
version = "20.23.1"
description = "Virtual Python Environment builder"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"},
{file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"},
]
[package.dependencies]
distlib = ">=0.3.6,<1"
@@ -270,35 +347,10 @@ filelock = ">=3.12,<4"
platformdirs = ">=3.5.1,<4"
[package.extras]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx-argparse (>=0.4)", "sphinx (>=7.0.1)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage-enable-subprocess (>=1)", "coverage (>=7.2.7)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "pytest (>=7.3.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"]
docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"]
[metadata]
lock-version = "1.1"
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "5d0edd070ea010edb4e2ade88dc37324b8b4b04f22db78e49db161185365849b"
[metadata.files]
attrs = []
black = []
cachetools = []
chardet = []
click = []
colorama = []
distlib = []
filelock = []
iniconfig = []
isort = []
mypy-extensions = []
packaging = []
pathspec = []
platformdirs = []
pluggy = []
py = []
pyproject-api = []
pytest = []
pytest-randomly = []
pytest-repeat = []
tomli = []
tox = []
virtualenv = []
content-hash = "e4b9a2c9555ff50df9595b0934d8d73e2d46539ffc29b579ae7a8721b7443f1f"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "vban-cmd"
version = "2.4.3"
version = "2.4.11"
description = "Python interface for the VBAN RT Packet Service (Sendtext)"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"
@@ -11,9 +11,8 @@ repository = "https://github.com/onyx-and-iris/vban-cmd-python"
python = "^3.10"
tomli = { version = "^2.0.1", python = "<3.11" }
[tool.poetry.dev-dependencies]
pytest = "^7.1.2"
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.4"
pytest-randomly = "^3.12.0"
pytest-repeat = "^0.9.1"
black = "^22.3.0"
@@ -28,12 +27,15 @@ build-backend = "poetry.core.masonry.api"
gui = "scripts:ex_gui"
obs = "scripts:ex_obs"
observer = "scripts:ex_observer"
test = "scripts:test"
basic = "scripts:test_basic"
banana = "scripts:test_banana"
potato = "scripts:test_potato"
all = "scripts:test_all"
[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py310,py311
envlist = py310,py311,py312
[testenv]
allowlist_externals = poetry

View File

@@ -1,3 +1,4 @@
import os
import subprocess
import sys
from pathlib import Path
@@ -18,5 +19,21 @@ def ex_observer():
subprocess.run([sys.executable, str(scriptpath)])
def test():
def test_basic():
os.environ["KIND"] = "basic"
subprocess.run(["tox"])
def test_banana():
os.environ["KIND"] = "banana"
subprocess.run(["tox"])
def test_potato():
os.environ["KIND"] = "potato"
subprocess.run(["tox"])
def test_all():
steps = [test_basic, test_banana, test_potato]
[step() for step in steps]

View File

@@ -1,3 +1,4 @@
import os
import random
import sys
from dataclasses import dataclass
@@ -6,8 +7,10 @@ import vban_cmd
from vban_cmd.kinds import KindId
from vban_cmd.kinds import request_kind_map as kindmap
# let's keep things random
KIND_ID = random.choice(tuple(kind_id.name.lower() for kind_id in KindId))
# get KIND_ID from env var, otherwise set to random
KIND_ID = os.environ.get(
"KIND", random.choice(tuple(kind_id.name.lower() for kind_id in KindId))
)
opts = {
"ip": "testing.local",

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 46"><title>tests: 46</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">46</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">46</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 49"><title>tests: 49</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">49</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">49</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 48"><title>tests: 48</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">48</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">48</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 51"><title>tests: 51</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">51</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">51</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 52"><title>tests: 52</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">52</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">52</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60" height="20" role="img" aria-label="tests: 59"><title>tests: 59</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="60" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="37" height="20" fill="#555"/><rect x="37" width="23" height="20" fill="#4c1"/><rect width="60" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="270">tests</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="270">tests</text><text aria-hidden="true" x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="130">59</text><text x="475" y="140" transform="scale(.1)" fill="#fff" textLength="130">59</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -11,7 +11,7 @@ Function RunTests {
$line | Tee-Object -FilePath $coverage -Append
}
}
Write-Output "$(Get-TimeStamp)" | Out-file $coverage -Append
Write-Output "$(Get-TimeStamp)" | Out-File $coverage -Append
Invoke-Expression "genbadge tests -t 90 -i ./tests/.coverage.xml -o ./tests/$kind.svg"
}
@@ -25,7 +25,10 @@ Function Get-TimeStamp {
if ($MyInvocation.InvocationName -ne ".") {
Invoke-Expression ".\.venv\Scripts\Activate.ps1"
RunTests
@("potato") | ForEach-Object {
$env:KIND = $_
RunTests
}
Invoke-Expression "deactivate"
}

View File

@@ -1,3 +1,5 @@
import time
import pytest
from tests import data, vban
@@ -11,11 +13,20 @@ class TestSetAndGetBoolHigher:
@classmethod
def setup_class(cls):
vban.apply_config("example")
time.sleep(0.1)
@pytest.mark.skipif(
"not config.getoption('--run-slow')",
reason="Only run when --run-slow is given",
)
def test_it_tests_config_string(self):
assert "PhysStrip" in vban.strip[data.phys_in].label
assert "VirtStrip" in vban.strip[data.virt_in].label
@pytest.mark.skipif(
"not config.getoption('--run-slow')",
reason="Only run when --run-slow is given",
)
def test_it_tests_config_bool(self):
assert vban.strip[0].A1 == True

37
tests/test_errors.py Normal file
View File

@@ -0,0 +1,37 @@
import re
import pytest
import vban_cmd
from tests import data, vban
class TestErrors:
__test__ = True
def test_it_tests_an_unknown_kind(self):
with pytest.raises(
vban_cmd.error.VBANCMDError,
match=f"Unknown Voicemeeter kind 'unknown_kind'",
):
vban_cmd.api("unknown_kind")
def test_it_tests_an_unknown_config_name(self):
EXPECTED_MSG = "\n".join(
(
f"No config with name 'unknown' is loaded into memory",
f"Known configs: {list(vban.configs.keys())}",
)
)
with pytest.raises(vban_cmd.error.VBANCMDError, match=re.escape(EXPECTED_MSG)):
vban.apply_config("unknown")
def test_it_tests_an_invalid_config_key(self):
CONFIG = {
"strip-0": {"A1": True, "B1": True, "gain": -6.0},
"bus-0": {"mute": True, "eq": {"on": True}},
"unknown-0": {"state": True},
"vban-out-1": {"name": "streamname"},
}
with pytest.raises(ValueError, match="invalid config key 'unknown-0'"):
vban.apply(CONFIG)

View File

@@ -1,5 +1,3 @@
import time
import pytest
from tests import data, vban
@@ -17,10 +15,6 @@ class TestPublicPacketLower:
)
@pytest.mark.skipif(
"not config.getoption('--run-slow')",
reason="Only run when --run-slow is given",
)
@pytest.mark.parametrize("value", [0, 1])
class TestSetRT:
__test__ = True
@@ -35,7 +29,6 @@ class TestSetRT:
],
)
def test_it_sends_a_text_request(self, kls, index, param, value):
vban._set_rt(f"{kls}[{index}]", param, value)
time.sleep(0.02)
vban._set_rt(f"{kls}[{index}].{param}", value)
target = getattr(vban, kls)[index]
assert getattr(target, param) == bool(value)

View File

@@ -26,7 +26,7 @@ class Bus(IRemote):
@property
def identifier(self) -> str:
return f"Bus[{self.index}]"
return f"bus[{self.index}]"
@property
def gain(self) -> float:
@@ -66,7 +66,7 @@ class BusEQ(IRemote):
@property
def identifier(self) -> str:
return f"Bus[{self.index}].eq"
return f"bus[{self.index}].eq"
class PhysicalBus(Bus):
@@ -116,7 +116,7 @@ class BusLevel(IRemote):
@property
def identifier(self) -> str:
return f"Bus[{self.index}]"
return f"bus[{self.index}]"
@property
def all(self) -> tuple:
@@ -138,7 +138,7 @@ def _make_bus_mode_mixin():
"""Creates a mixin of Bus Modes."""
def identifier(self) -> str:
return f"Bus[{self.index}].mode"
return f"bus[{self.index}].mode"
def get(self):
time.sleep(0.01)

View File

@@ -30,7 +30,7 @@ class Command(IRemote):
@property
def identifier(self) -> str:
return "Command"
return "command"
def set_showvbanchat(self, val: bool):
self.setter("DialogShow.VBANCHAT", 1 if val else 0)

View File

@@ -148,8 +148,13 @@ class Loader(metaclass=SingletonType):
self.logger.info(
f"config file with name {identifier} already in memory, skipping.."
)
return False
self.parser = dataextraction_factory(data)
return
try:
self.parser = dataextraction_factory(data)
except tomllib.TOMLDecodeError as e:
ERR_MSG = (str(e), f"When attempting to load {identifier}.toml")
self.logger.error(f"{type(e).__name__}: {' '.join(ERR_MSG)}")
return
return True
def register(self, identifier, data=None):

View File

@@ -1,5 +1,5 @@
class VBANCMDError(Exception):
"""Base VBANCMD Exception class. Raised when general errors occur"""
"""Base VBANCMD Exception class."""
class VBANCMDConnectionError(VBANCMDError):

View File

@@ -8,6 +8,8 @@ def channel_bool_prop(param):
@partial(cache_bool, param=param)
def fget(self):
cmd = self._cmd(param)
self.logger.debug(f"getter: {cmd}")
return (
not int.from_bytes(
getattr(
@@ -47,6 +49,8 @@ def strip_output_prop(param):
@partial(cache_bool, param=param)
def fget(self):
cmd = self._cmd(param)
self.logger.debug(f"getter: {cmd}")
return (
not int.from_bytes(self.public_packet.stripstate[self.index], "little")
& getattr(self._modes, f"_bus{param.lower()}")
@@ -64,6 +68,8 @@ def bus_mode_prop(param):
@partial(cache_bool, param=param)
def fget(self):
cmd = self._cmd(param)
self.logger.debug(f"getter: {cmd}")
modelist = {
"amix": (1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1),
"repeat": (0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2),

View File

@@ -265,7 +265,7 @@ class VbanRtPacketHeader:
@dataclass
class RequestHeader:
"""Represents the header of an REQUEST RT PACKET"""
"""Represents the header of a REQUEST RT PACKET"""
name: str
bps_index: int

View File

@@ -20,7 +20,7 @@ class Strip(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}]"
return f"strip[{self.index}]"
@property
def limit(self) -> int:
@@ -79,7 +79,7 @@ class PhysicalStrip(Strip):
class StripComp(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}].comp"
return f"strip[{self.index}].comp"
@property
def knob(self) -> float:
@@ -157,7 +157,7 @@ class StripComp(IRemote):
class StripGate(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}].gate"
return f"strip[{self.index}].gate"
@property
def knob(self) -> float:
@@ -219,7 +219,7 @@ class StripGate(IRemote):
class StripDenoiser(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}].denoiser"
return f"strip[{self.index}].denoiser"
@property
def knob(self) -> float:
@@ -233,7 +233,7 @@ class StripDenoiser(IRemote):
class StripEQ(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}].eq"
return f"strip[{self.index}].eq"
@property
def on(self):
@@ -312,7 +312,7 @@ class StripLevel(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}]"
return f"strip[{self.index}]"
@property
def prefader(self) -> tuple:
@@ -345,7 +345,7 @@ class GainLayer(IRemote):
@property
def identifier(self) -> str:
return f"Strip[{self.index}]"
return f"strip[{self.index}]"
@property
def gain(self) -> float:

View File

@@ -7,9 +7,8 @@ def cache_bool(func, param):
def wrapper(*args, **kwargs):
self, *rem = args
cmd = f"{self.identifier}.{param}"
if cmd in self._remote.cache:
return self._remote.cache.pop(cmd) == 1
if self._cmd(param) in self._remote.cache:
return self._remote.cache.pop(self._cmd(param)) == 1
if self._remote.sync:
self._remote.clear_dirty()
return func(*args, **kwargs)
@@ -22,9 +21,8 @@ def cache_string(func, param):
def wrapper(*args, **kwargs):
self, *rem = args
cmd = f"{self.identifier}.{param}"
if cmd in self._remote.cache:
return self._remote.cache.pop(cmd)
if self._cmd(param) in self._remote.cache:
return self._remote.cache.pop(self._cmd(param))
if self._remote.sync:
self._remote.clear_dirty()
return func(*args, **kwargs)

View File

@@ -172,32 +172,24 @@ class VbanMidiOutstream(VbanOutstream):
def _make_stream_pair(remote, kind):
num_instream, num_outstream, num_midi, num_text = kind.vban
def _generate_streams(i, dir):
"""generator function for creating instream/outstream tuples"""
if dir == "in":
if i < num_instream:
yield VbanAudioInstream
elif i < num_instream + num_midi:
yield VbanMidiInstream
else:
yield VbanTextInstream
else:
if i < num_outstream:
yield VbanAudioOutstream
else:
yield VbanMidiOutstream
def _make_cls(i, direction):
match direction:
case "in":
if i < num_instream:
return VbanAudioInstream(remote, i)
elif i < num_instream + num_midi:
return VbanMidiInstream(remote, i)
else:
return VbanTextInstream(remote, i)
case "out":
if i < num_outstream:
return VbanAudioOutstream(remote, i)
else:
return VbanMidiOutstream(remote, i)
return (
tuple(
cls(remote, i)
for i in range(num_instream + num_midi + num_text)
for cls in _generate_streams(i, "in")
),
tuple(
cls(remote, i)
for i in range(num_outstream + num_midi)
for cls in _generate_streams(i, "out")
),
tuple(_make_cls(i, "in") for i in range(num_instream + num_midi + num_text)),
tuple(_make_cls(i, "out") for i in range(num_outstream + num_midi)),
)

View File

@@ -50,6 +50,8 @@ class VbanCmd(metaclass=ABCMeta):
self._pdirty = False
self._ldirty = False
self._script = str()
self.stop_event = None
self.producer = None
@abstractmethod
def __str__(self):
@@ -109,7 +111,7 @@ class VbanCmd(metaclass=ABCMeta):
)
def stopped(self):
return self.stop_event.is_set()
return self.stop_event is None or self.stop_event.is_set()
def _set_rt(self, cmd: str, val: Union[str, float]):
"""Sends a string request command over a network."""
@@ -181,16 +183,25 @@ class VbanCmd(metaclass=ABCMeta):
minor delay between each recursion
"""
def param(key):
obj, m2, *rem = key.split("-")
index = int(m2) if m2.isnumeric() else int(*rem)
if obj in ("strip", "bus", "button"):
return getattr(self, obj)[index]
elif obj == "vban":
return getattr(getattr(self, obj), f"{m2}stream")[index]
raise ValueError(obj)
def target(key):
match key.split("-"):
case ["strip" | "bus" as kls, index] if index.isnumeric():
target = getattr(self, kls)
case [
"vban",
"in" | "instream" | "out" | "outstream" as direction,
index,
] if index.isnumeric():
target = getattr(
self.vban, f"{direction.removesuffix('stream')}stream"
)
case _:
ERR_MSG = f"invalid config key '{key}'"
self.logger.error(ERR_MSG)
raise ValueError(ERR_MSG)
return target[int(index)]
[param(key).apply(datum).then_wait() for key, datum in data.items()]
[target(key).apply(di).then_wait() for key, di in data.items()]
def apply_config(self, name):
"""applies a config from memory"""
@@ -221,7 +232,9 @@ class VbanCmd(metaclass=ABCMeta):
if not self.stopped():
self.logger.debug("events thread shutdown started")
self.stop_event.set()
self.subscriber.join() # wait for subscriber thread to complete cycle
if self.producer is not None:
for t in (self.producer, self.subscriber):
t.join()
[sock.close() for sock in self.socks]
self.logger.info(f"{type(self).__name__}: Successfully logged out of {self}")