3 Commits

Author SHA1 Message Date
3e68488231 bump deps 2023-07-08 18:19:06 +01:00
6d46d9a9a5 userconfigs now returns target.configs
patch bump
2023-07-08 00:22:07 +01:00
e4068277f7 ensure we don't attempt to delete a menu key twice
patch bump
2023-07-07 03:37:06 +01:00
5 changed files with 125 additions and 108 deletions

92
poetry.lock generated
View File

@@ -1,10 +1,25 @@
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
[[package]]
name = "black"
version = "22.12.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"},
{file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"},
{file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"},
{file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"},
{file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"},
{file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"},
{file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"},
{file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"},
{file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"},
{file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"},
{file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"},
{file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"},
]
[package.dependencies]
click = ">=8.0.0"
@@ -23,9 +38,12 @@ uvloop = ["uvloop (>=0.15.2)"]
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\""}
@@ -34,104 +52,118 @@ 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 = "isort"
version = "5.12.0"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
python-versions = ">=3.8.0"
files = [
{file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
{file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
]
[package.extras]
colors = ["colorama (>=0.4.3)"]
requirements-deprecated-finder = ["pip-api", "pipreqs"]
pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
plugins = ["setuptools"]
requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
description = "Type system extensions for programs checked with the mypy type checker."
category = "dev"
optional = false
python-versions = ">=3.5"
files = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "pathspec"
version = "0.11.1"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
{file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
]
[[package]]
name = "platformdirs"
version = "3.8.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.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"},
{file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"},
]
[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 = "sv-ttk"
version = "2.5.1"
description = "A gorgeous theme for Tkinter, based on Windows 11's UI"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "sv_ttk-2.5.1-py3-none-any.whl", hash = "sha256:c7388741e14316b4e9c3b9fd135e1e2e5b501f1b30c89b7af1e26286b38f2ccc"},
{file = "sv_ttk-2.5.1.tar.gz", hash = "sha256:e32d60587db7debe4d7d7438f66257ffcd9db5b8efbcb52151697fa8a662a4f5"},
]
[[package]]
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 = "vban-cmd"
version = "2.0.0"
version = "2.2.0"
description = "Python interface for the VBAN RT Packet Service (Sendtext)"
category = "main"
optional = false
python-versions = ">=3.10,<4.0"
files = [
{file = "vban_cmd-2.2.0-py3-none-any.whl", hash = "sha256:ad0bd848b5412004c4c14976e8a9a18d0fc727599e343db0fb67f9427c8541fa"},
{file = "vban_cmd-2.2.0.tar.gz", hash = "sha256:7bad6001504fd052df3192c7d817e604703353f57efa7648c1f1d6e425665006"},
]
[package.dependencies]
tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
[[package]]
name = "voicemeeter-api"
version = "2.0.2"
version = "2.1.2"
description = "A Python wrapper for the Voiceemeter API"
category = "main"
optional = false
python-versions = ">=3.10,<4.0"
files = [
{file = "voicemeeter_api-2.1.2-py3-none-any.whl", hash = "sha256:43a6e36282a89f2701b58f627bdd21c5e17f9f9044bf3337059d89e91f25fc09"},
{file = "voicemeeter_api-2.1.2.tar.gz", hash = "sha256:c24c643e868535786860420fe5775a10e2ace6f79ec4905a172a1c64712f3d6b"},
]
[package.dependencies]
tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
[metadata]
lock-version = "1.1"
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "3a59de3a76e4c0ca11c0166750fa1af7d7c887750f855b48c45359068ef04798"
[metadata.files]
black = []
click = []
colorama = []
isort = []
mypy-extensions = []
pathspec = []
platformdirs = []
sv-ttk = []
tomli = []
vban-cmd = []
voicemeeter-api = []

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "voicemeeter-compact"
version = "1.8.2"
version = "1.8.4"
description = "A Compact Voicemeeter Remote App"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"
@@ -14,8 +14,8 @@ include = ["vmcompact/img/cat.ico"]
python = "^3.10"
sv-ttk = "^2.5.1"
tomli = { version = "^2.0.1", python = "<3.11" }
voicemeeter-api = "^2.0.2"
vban-cmd = "^2.0.0"
voicemeeter-api = "^2.1.2"
vban-cmd = "^2.2.0"
[tool.poetry.dev-dependencies]
black = { version = "^22.6.0", allow-prereleases = true }

View File

@@ -145,7 +145,7 @@ class App(tk.Tk):
@cached_property
def userconfigs(self):
self._configs = loader(self.kind.name)
self._configs = loader(self.kind.name, self.target)
return self._configs

View File

@@ -10,28 +10,32 @@ logger = logging.getLogger(__name__)
configuration = {}
configpaths = [
Path.cwd() / "configs",
Path.home() / ".config" / "vm-compact" / "configs",
Path.home() / "Documents" / "Voicemeeter" / "configs",
]
for configpath in configpaths:
if configpath.is_dir():
filepaths = list(configpath.glob("*.toml"))
if any(f.stem in ("app", "vban") for f in filepaths):
configs = {}
for filepath in filepaths:
filename = filepath.with_suffix("").stem
if filename in ("app", "vban"):
try:
with open(filepath, "rb") as f:
configs[filename] = tomllib.load(f)
logger.info(f"configuration: {filename} loaded into memory")
except tomllib.TOMLDecodeError:
logger.error(f"Invalid TOML config: configs/{filename.stem}")
configuration |= configs
break
def get_configpath():
configpaths = [
Path.cwd() / "configs",
Path.home() / ".config" / "vm-compact" / "configs",
Path.home() / "Documents" / "Voicemeeter" / "configs",
]
for configpath in configpaths:
if configpath.exists():
return configpath
if configpath := get_configpath():
filepaths = list(configpath.glob("*.toml"))
if any(f.stem in ("app", "vban") for f in filepaths):
configs = {}
for filepath in filepaths:
filename = filepath.with_suffix("").stem
if filename in ("app", "vban"):
try:
with open(filepath, "rb") as f:
configs[filename] = tomllib.load(f)
logger.info(f"configuration: {filename} loaded into memory")
except tomllib.TOMLDecodeError:
logger.error(f"Invalid TOML config: configs/{filename.stem}")
configuration |= configs
_defaults = {
"configs": {
@@ -75,17 +79,20 @@ def get_configuration(key):
return configuration[key]
def loader(kind_id):
configs = {}
userconfigpath = Path.home() / ".config" / "vm-compact" / "configs" / kind_id
if userconfigpath.exists():
filepaths = list(userconfigpath.glob("*.toml"))
for filepath in filepaths:
identifier = filepath.with_suffix("").stem
try:
with open(filepath, "rb") as f:
configs[identifier] = tomllib.load(f)
logger.info(f"loader: {identifier} loaded into memory")
except tomllib.TOMLDecodeError:
logger.error(f"Invalid TOML config: configs/{filename.stem}")
return configs
def loader(kind_id, target):
configs = {"reset": target.configs["reset"]}
if configpath := get_configpath():
userconfigpath = configpath / kind_id
if userconfigpath.exists():
filepaths = list(userconfigpath.glob("*.toml"))
for filepath in filepaths:
identifier = filepath.with_suffix("").stem
try:
with open(filepath, "rb") as f:
configs[identifier] = tomllib.load(f)
logger.info(f"loader: {identifier} loaded into memory")
except tomllib.TOMLDecodeError:
logger.error(f"Invalid TOML config: configs/{filename.stem}")
target.configs = configs
return target.configs

View File

@@ -85,24 +85,16 @@ class Menus(tk.Menu):
self.menu_configs_load = tk.Menu(self.menu_configs, tearoff=0)
self.menu_configs.add_cascade(menu=self.menu_configs_load, label="Load config")
self.config_defaults = {"reset"}
if len(self.target.configs) > len(self.config_defaults) and all(
key in self.target.configs for key in self.config_defaults
if len(self.parent.userconfigs) > len(self.config_defaults) and all(
key in self.parent.userconfigs for key in self.config_defaults
):
[
self.menu_configs_load.add_command(
label=profile, command=partial(self.load_profile, profile)
)
for profile in self.target.configs.keys()
for profile in self.parent.userconfigs.keys()
if profile not in self.config_defaults
]
elif self.parent.userconfigs:
[
self.menu_configs_load.add_command(
label=name, command=partial(self.load_custom_profile, data)
)
for name, data in self.parent.userconfigs.items()
if name not in self.config_defaults
]
else:
self.menu_configs.entryconfig(0, state="disabled")
self.menu_configs.add_command(
@@ -315,16 +307,13 @@ class Menus(tk.Menu):
def menu_teardown(self, i):
# remove config load menus
[
self.menu_configs_load.delete(key)
for key in self.target.configs.keys()
if key not in self.config_defaults
]
[
self.menu_configs_load.delete(key)
for key in self.parent.userconfigs.keys()
if key not in self.config_defaults
]
if len(self.parent.userconfigs) > len(self.config_defaults):
for profile in self.parent.userconfigs:
if profile not in self.config_defaults:
try:
self.menu_configs_load.delete(profile)
except tk._tkinter.tclError as e:
self.logger.warning(f"{type(e).__name__}: {e}")
[
self.menu_vban.entryconfig(j, state="disabled")
@@ -333,24 +322,13 @@ class Menus(tk.Menu):
]
def menu_setup(self):
if len(self.target.configs) > len(self.config_defaults) and all(
key in self.target.configs for key in self.config_defaults
):
[
self.menu_configs_load.add_command(
label=profile, command=partial(self.load_profile, profile)
)
for profile in self.target.configs.keys()
if profile not in self.config_defaults
]
elif self.parent.userconfigs:
[
self.menu_configs_load.add_command(
label=name, command=partial(self.load_custom_profile, data)
)
for name, data in self.parent.userconfigs.items()
if name not in self.config_defaults
]
if len(self.parent.userconfigs) > len(self.config_defaults):
for profile in self.parent.userconfigs:
if profile not in self.config_defaults:
self.menu_configs_load.add_command(
label=profile, command=partial(self.load_profile, profile)
)
self.menu_configs.entryconfig(0, state="normal")
else:
self.menu_configs.entryconfig(0, state="disabled")