diff --git a/config.example.toml b/config.example.toml new file mode 100644 index 0000000..282e2d2 --- /dev/null +++ b/config.example.toml @@ -0,0 +1,14 @@ +# ~/.config/whisper-local/config.toml + +[hotkey] +key = "KEY_F12" + +[whisper] +model = "small" +language = "de" +compute_type = "int8" + +[audio] +sample_rate = 16000 +channels = 1 +min_duration = 0.5 diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..a73a14b --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,59 @@ +from pathlib import Path +import tomllib + +from whisper_local.config import Config, load_config + + +class TestConfigDefaults: + def test_default_hotkey(self): + config = Config() + assert config.hotkey == "KEY_F12" + + def test_default_whisper_model(self): + config = Config() + assert config.whisper_model == "small" + + def test_default_language(self): + config = Config() + assert config.language == "de" + + def test_default_compute_type(self): + config = Config() + assert config.compute_type == "int8" + + def test_default_sample_rate(self): + config = Config() + assert config.sample_rate == 16000 + + def test_default_channels(self): + config = Config() + assert config.channels == 1 + + def test_default_min_duration(self): + config = Config() + assert config.min_duration == 0.5 + + +class TestLoadConfig: + def test_load_from_toml(self, tmp_path): + config_file = tmp_path / "config.toml" + config_file.write_text( + '[hotkey]\nkey = "KEY_F8"\n\n' + '[whisper]\nmodel = "tiny"\nlanguage = "en"\n' + ) + config = load_config(config_file) + assert config.hotkey == "KEY_F8" + assert config.whisper_model == "tiny" + assert config.language == "en" + # Defaults bleiben erhalten + assert config.compute_type == "int8" + + def test_load_nonexistent_returns_defaults(self, tmp_path): + config = load_config(tmp_path / "nope.toml") + assert config.hotkey == "KEY_F12" + + def test_load_empty_file(self, tmp_path): + config_file = tmp_path / "config.toml" + config_file.write_text("") + config = load_config(config_file) + assert config.hotkey == "KEY_F12" diff --git a/whisper_local/config.py b/whisper_local/config.py new file mode 100644 index 0000000..17c0e94 --- /dev/null +++ b/whisper_local/config.py @@ -0,0 +1,52 @@ +"""Konfiguration aus TOML-Datei mit sinnvollen Defaults.""" + +from dataclasses import dataclass +from pathlib import Path +import tomllib + + +DEFAULT_CONFIG_PATH = Path.home() / ".config" / "whisper-local" / "config.toml" + + +@dataclass +class Config: + hotkey: str = "KEY_F12" + whisper_model: str = "small" + language: str = "de" + compute_type: str = "int8" + sample_rate: int = 16000 + channels: int = 1 + min_duration: float = 0.5 + + +def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: + """Lädt Config aus TOML-Datei. Gibt Defaults zurück wenn Datei fehlt.""" + config = Config() + + if not path.exists(): + return config + + with open(path, "rb") as f: + data = tomllib.load(f) + + hotkey_section = data.get("hotkey", {}) + if "key" in hotkey_section: + config.hotkey = hotkey_section["key"] + + whisper_section = data.get("whisper", {}) + if "model" in whisper_section: + config.whisper_model = whisper_section["model"] + if "language" in whisper_section: + config.language = whisper_section["language"] + if "compute_type" in whisper_section: + config.compute_type = whisper_section["compute_type"] + + audio_section = data.get("audio", {}) + if "sample_rate" in audio_section: + config.sample_rate = audio_section["sample_rate"] + if "channels" in audio_section: + config.channels = audio_section["channels"] + if "min_duration" in audio_section: + config.min_duration = audio_section["min_duration"] + + return config