diff --git a/config.py b/config.py index 1e5572c..5eae634 100644 --- a/config.py +++ b/config.py @@ -108,6 +108,14 @@ class AbstractJsonConfig(ABC): self._load_config() return self + def to_dict(self): + # Remove private fields: + without_private_fields = {} + for attr, value in self.__dict__.items(): + if not attr.startswith("_"): + without_private_fields[attr] = value + return without_private_fields + def _reload_on_change(self): # Check if config file has been modified and reload if needed if time.time() - self.__last_read_time >= self.__file_check_interval: @@ -132,15 +140,9 @@ class AbstractJsonConfig(ABC): def _save_file(self, path: Path | None | str, default = lambda o: o.__dict__, indent = 4): file_path = (Path(path) if type(path) is str else path) if path is not None else self.get_config_path() - # Remove private fields: - without_private_fields = {} - for attr, value in self.__dict__.items(): - if not attr.startswith("_"): - without_private_fields[attr] = value - def __save(): with open(file_path, "w") as file: - json.dump(without_private_fields, file, indent=indent, default=default) + json.dump(self.to_dict(), file, indent=indent, default=default) self.__with_lock_and_backup(file_path, True, __save) def __with_lock_and_backup(self, path: Path, backup: bool, callable: Callable[[], None]): diff --git a/test/test_config.py b/test/test_config.py index 3e935ce..895ffd8 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -122,36 +122,40 @@ class TestAlltalkConfig(unittest.TestCase): new_config = AlltalkConfig(tmp.name) self.assertEqual(new_config.branding, "foo") + def test_no_private_fields(self): + for attr in self.config.to_dict().keys(): + self.assertTrue(not attr.startswith("_")) + class TestAlltalkTTSEnginesConfig(unittest.TestCase): def setUp(self): - self.ttsEnginesConfig = AlltalkTTSEnginesConfig.get_instance() - self.ttsEnginesConfig.reload() + self.tts_engines_config = AlltalkTTSEnginesConfig.get_instance() + self.tts_engines_config.reload() def test_tts_engines(self): - self.assertEqual(self.ttsEnginesConfig.engine_loaded, "piper") - self.assertEqual(self.ttsEnginesConfig.selected_model, "piper") - self.assertListEqual(self.ttsEnginesConfig.get_engine_names_available(), ["parler", "piper", "vits", "xtts", "f5tts"]) + self.assertEqual(self.tts_engines_config.engine_loaded, "piper") + self.assertEqual(self.tts_engines_config.selected_model, "piper") + self.assertListEqual(self.tts_engines_config.get_engine_names_available(), ["parler", "piper", "vits", "xtts", "f5tts"]) def test_is_valid_engine(self): for engine in ["parler", "piper", "vits", "xtts", "f5tts"]: - self.assertTrue(self.ttsEnginesConfig.is_valid_engine(engine)) + self.assertTrue(self.tts_engines_config.is_valid_engine(engine)) - self.assertFalse(self.ttsEnginesConfig.is_valid_engine("foo")) + self.assertFalse(self.tts_engines_config.is_valid_engine("foo")) def test_change_tts_engine(self): - self.ttsEnginesConfig.change_engine("vits") - self.assertEqual(self.ttsEnginesConfig.engine_loaded, "vits") - self.assertEqual(self.ttsEnginesConfig.selected_model, "vits - tts_models--en--vctk--vits") + self.tts_engines_config.change_engine("vits") + self.assertEqual(self.tts_engines_config.engine_loaded, "vits") + self.assertEqual(self.tts_engines_config.selected_model, "vits - tts_models--en--vctk--vits") def test_tts_engines_default_config_path(self): expected_config_path = os.path.join(Path(__file__).parent.parent.resolve(), "system", "tts_engines", "tts_engines.json") - self.assertEqual(self.ttsEnginesConfig.get_config_path(), Path(expected_config_path)) + self.assertEqual(self.tts_engines_config.get_config_path(), Path(expected_config_path)) def test_tts_engines_save(self): with tempfile.NamedTemporaryFile(suffix=".json") as tmp: - self.ttsEnginesConfig.engine_loaded = "foo" - self.ttsEnginesConfig.save(tmp.name) + self.tts_engines_config.engine_loaded = "foo" + self.tts_engines_config.save(tmp.name) new_config = AlltalkTTSEnginesConfig(tmp.name) self.assertEqual(new_config.engine_loaded, "foo") self.assertListEqual(new_config.get_engine_names_available(), ["parler", "piper", "vits", "xtts", "f5tts"]) @@ -159,25 +163,33 @@ class TestAlltalkTTSEnginesConfig(unittest.TestCase): def test_merge_with_new_engines(self): with tempfile.NamedTemporaryFile(suffix=".json") as tmp: - self.ttsEnginesConfig.engines_available = [] - self.assertListEqual(self.ttsEnginesConfig.get_engine_names_available(), []) + self.tts_engines_config.engines_available = [] + self.assertListEqual(self.tts_engines_config.get_engine_names_available(), []) - self.ttsEnginesConfig.save(tmp.name) + self.tts_engines_config.save(tmp.name) new_config = AlltalkTTSEnginesConfig(tmp.name) self.assertEqual(new_config.get_engine_names_available(), ["parler", "xtts", "f5tts"]) self.assertEqual(len(new_config.engines_available), len(new_config.get_engine_names_available())) + def test_no_private_fields(self): + for attr in self.tts_engines_config.to_dict().keys(): + self.assertTrue(not attr.startswith("_")) + class TestAlltalkNewEnginesConfig(unittest.TestCase): def setUp(self): - self.newEnginesConfig = AlltalkNewEnginesConfig.get_instance() - self.newEnginesConfig.reload() + self.new_engines_config = AlltalkNewEnginesConfig.get_instance() + self.new_engines_config.reload() def test_engine_names(self): - self.assertListEqual(self.newEnginesConfig.get_engine_names_available(), ["parler", "xtts", "f5tts"]) + self.assertListEqual(self.new_engines_config.get_engine_names_available(), ["parler", "xtts", "f5tts"]) def test_get_engine_names_matching(self): - result = self.newEnginesConfig.get_engines_matching(lambda x: "tts" in x.name) + result = self.new_engines_config.get_engines_matching(lambda x: "tts" in x.name) self.assertEqual(len(result), 2) + + def test_no_private_fields(self): + for attr in self.new_engines_config.to_dict().keys(): + self.assertTrue(not attr.startswith("_")) diff --git a/tts_server.py b/tts_server.py index b47119f..5fefe03 100644 --- a/tts_server.py +++ b/tts_server.py @@ -1612,19 +1612,14 @@ app.mount("/static", StaticFiles(directory=str(this_dir / "system")), name="stat ######################################## # Setup logging logging.basicConfig(level=logging.DEBUG) -def get_json_data(): - with open(this_dir / "confignew.json", "r") as json_file: - data = json.load(json_file) - return data @app.get("/settings") async def get_settings(request: Request): - data = get_json_data() - return templates.TemplateResponse("admin.html", {"request": request, "data": data}) + return templates.TemplateResponse("admin.html", {"request": request, "data": config.to_dict()}) @app.get("/settings-json") async def get_settings_json(): - return get_json_data() + return config.to_dict() @app.post("/update-settings") async def update_settings( @@ -1634,24 +1629,24 @@ async def update_settings( gradio_port_number: int = Form(...), api_port_number: int = Form(...), ): - data = get_json_data() # Update the settings based on the form values - data["delete_output_wavs"] = delete_output_wavs - data["gradio_interface"] = gradio_interface.lower() == 'true' - data["gradio_port_number"] = gradio_port_number - data["api_def"]["api_port_number"] = api_port_number + config.delete_output_wavs = delete_output_wavs + config.gradio_interface = gradio_interface.lower() == 'true' + config.gradio_port_number = gradio_port_number + config.api_def.api_port_number = api_port_number + # Save the updated settings back to the JSON file - with open(this_dir / "confignew.json", "w") as json_file: - json.dump(data, json_file, indent=4) + config.save() + # Redirect to the settings page to display the updated settings - return templates.TemplateResponse("admin.html", {"request": request, "data": data}) + return templates.TemplateResponse("admin.html", {"request": request, "data": config.to_dict()}) # Create an instance of Jinja2Templates for rendering HTML templates templates = Jinja2Templates(directory=this_dir / "system") # Get the admin interface template template = templates.get_template("admin.html") # Render the template with the dynamic values -rendered_html = template.render(params=config.__dict__) +rendered_html = template.render(params=config.to_dict()) ################################################### #### Webserver Startup & Initial model Loading ####