diff --git a/CHANGELOG.md b/CHANGELOG.md index c7405ba..5903804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ Before any major/minor/patch bump all unit tests will be run to verify they pass - [x] +## [2.3.0] - 2023-07-11 + +### Added + +- user configs may now extend other user configs. check `config extends` section in README. + ## [2.2.0] - 2023-07-10 ### Added diff --git a/README.md b/README.md index 3792aa4..d835689 100644 --- a/README.md +++ b/README.md @@ -701,7 +701,7 @@ vm.vban.outstream[0].apply(on: True, name: 'streamname', bit: 24) You may load config files in TOML format. Three example configs have been included with the package. Remember to save -current settings before loading a user config. To set one you may do: +current settings before loading a user config. To load one you may do: ```python import voicemeeterlib @@ -709,7 +709,26 @@ with voicemeeterlib.api('banana') as vm: vm.apply_config('example') ``` -will load a user config file at configs/banana/example.toml for Voicemeeter Banana. +Your configs may be located in one of the following paths: +- \ / "configs" / kind_id +- \ / ".config" / "voicemeeter" / kind_id +- \ / "Documents" / "Voicemeeter" / "configs" / kind_id + +If a config with the same name is located in multiple locations, only the first one found is loaded into memory, in the above order. + +#### `config extends` + +You may also load a config that extends another config with overrides or additional parameters. + +You just need to define a key `extends` in the config TOML, that names the config to be extended. + +Three example 'extender' configs are included with the repo. You may load them with: + +```python +import voicemeeterlib +with voicemeeterlib.api('banana') as vm: + vm.apply_config('extender') +``` ## Events diff --git a/configs/banana/extender.toml b/configs/banana/extender.toml new file mode 100644 index 0000000..c71d26c --- /dev/null +++ b/configs/banana/extender.toml @@ -0,0 +1,9 @@ +extends = "example" +[strip-0] +label = "strip0_extended" +A1 = false +gain = 0.0 + +[bus-0] +label = "bus0_extended" +mute = false diff --git a/configs/basic/extender.toml b/configs/basic/extender.toml new file mode 100644 index 0000000..c71d26c --- /dev/null +++ b/configs/basic/extender.toml @@ -0,0 +1,9 @@ +extends = "example" +[strip-0] +label = "strip0_extended" +A1 = false +gain = 0.0 + +[bus-0] +label = "bus0_extended" +mute = false diff --git a/configs/potato/extender.toml b/configs/potato/extender.toml new file mode 100644 index 0000000..c71d26c --- /dev/null +++ b/configs/potato/extender.toml @@ -0,0 +1,9 @@ +extends = "example" +[strip-0] +label = "strip0_extended" +A1 = false +gain = 0.0 + +[bus-0] +label = "bus0_extended" +mute = false diff --git a/pyproject.toml b/pyproject.toml index e22a7fa..5dfc835 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "voicemeeter-api" -version = "2.2.1" +version = "2.3.0" description = "A Python wrapper for the Voiceemeter API" authors = ["onyx-and-iris "] license = "MIT" diff --git a/voicemeeterlib/remote.py b/voicemeeterlib/remote.py index 76c68f0..8bd8a03 100644 --- a/voicemeeterlib/remote.py +++ b/voicemeeterlib/remote.py @@ -301,16 +301,24 @@ class Remote(CBindings): def apply_config(self, name): """applies a config from memory""" - error_msg = ( + ERR_MSG = ( f"No config with name '{name}' is loaded into memory", f"Known configs: {list(self.configs.keys())}", ) try: - self.apply(self.configs[name]) - self.logger.info(f"Profile '{name}' applied!") + config = self.configs[name].copy() except KeyError as e: - self.logger.error(("\n").join(error_msg)) - raise VMError(("\n").join(error_msg)) from e + self.logger.error(("\n").join(ERR_MSG)) + raise VMError(("\n").join(ERR_MSG)) from e + + if "extends" in config: + extended = config.pop("extends") + config = self.configs[extended] | config + self.logger.debug( + f"profile '{name}' extends '{extended}', profiles merged.." + ) + self.apply(config) + self.logger.info(f"Profile '{name}' applied!") def logout(self) -> NoReturn: """Wait for dirty parameters to clear, then logout of the API"""