diff --git a/helpers/mic.py b/helpers/mic.py index 5101544..73aedb3 100644 --- a/helpers/mic.py +++ b/helpers/mic.py @@ -1,10 +1,17 @@ -import pyaudio import os import json +from pathlib import Path -CONFIG_FILE = "config\mic_config.json" +DEFAULT_CONFIG_FILE = Path(__file__).resolve().parents[1] / "mic_config.json" +CONFIG_FILE = Path(os.getenv("BONZI_MIC_CONFIG", DEFAULT_CONFIG_FILE)) + + +def _pyaudio(): + import pyaudio + return pyaudio def list_microphones(): + pyaudio = _pyaudio() p = pyaudio.PyAudio() info = p.get_host_api_info_by_index(0) num_devices = info.get('deviceCount') @@ -34,18 +41,20 @@ def get_device_index(num_devices, default_device_index, default_device_name): print("Invalid input. Please enter a valid number.") def load_config(): - if os.path.exists(CONFIG_FILE): - with open(CONFIG_FILE, "r") as f: + if CONFIG_FILE.exists(): + with CONFIG_FILE.open("r") as f: return json.load(f) return None def save_config(config): - with open(CONFIG_FILE, "w") as f: + CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True) + with CONFIG_FILE.open("w") as f: json.dump(config, f, indent=4) def configure_microphone(): print("Available microphones:") default_device_name = list_microphones() + pyaudio = _pyaudio() p = pyaudio.PyAudio() num_devices = p.get_host_api_info_by_index(0).get('deviceCount') default_device_index = p.get_default_input_device_info().get('index') @@ -57,4 +66,4 @@ def configure_microphone(): "prompt_every_time": prompt_every_time == 'y' } save_config(config) - return config \ No newline at end of file + return config diff --git a/tests/test_mic_config.py b/tests/test_mic_config.py new file mode 100644 index 0000000..323d83f --- /dev/null +++ b/tests/test_mic_config.py @@ -0,0 +1,42 @@ +import importlib +import json +import os +import tempfile +import unittest +from pathlib import Path + + +class MicConfigTests(unittest.TestCase): + def reload_mic_with_config(self, config_path): + os.environ["BONZI_MIC_CONFIG"] = str(config_path) + import helpers.mic as mic + return importlib.reload(mic) + + def tearDown(self): + os.environ.pop("BONZI_MIC_CONFIG", None) + + def test_load_config_returns_none_when_missing(self): + with tempfile.TemporaryDirectory() as tmp: + mic = self.reload_mic_with_config(Path(tmp) / "missing" / "mic_config.json") + self.assertIsNone(mic.load_config()) + + def test_save_config_creates_parent_directory_and_round_trips(self): + with tempfile.TemporaryDirectory() as tmp: + config_path = Path(tmp) / "config" / "mic_config.json" + mic = self.reload_mic_with_config(config_path) + + mic.save_config({"device_index": 3, "prompt_every_time": False}) + + self.assertTrue(config_path.exists()) + self.assertEqual( + json.loads(config_path.read_text()), + {"device_index": 3, "prompt_every_time": False}, + ) + self.assertEqual( + mic.load_config(), + {"device_index": 3, "prompt_every_time": False}, + ) + + +if __name__ == "__main__": + unittest.main()