Updated config.py
This commit is contained in:
1 parent
18b580db04
commit
fff2fac88d
1 file changed
+166
-76
@@ -18,74 +18,80 @@ class AlltalkConfigTheme:
|
||||
|
||||
@dataclass
|
||||
class AlltalkConfigRvcSettings:
|
||||
rvc_enabled = False
|
||||
rvc_char_model_file = ""
|
||||
rvc_narr_model_file = ""
|
||||
split_audio = False
|
||||
autotune = False
|
||||
pitch = 0
|
||||
filter_radius = 0
|
||||
index_rate = 0.0
|
||||
rms_mix_rate = 0
|
||||
protect = 0
|
||||
hop_length = 0
|
||||
f0method = ""
|
||||
embedder_model = ""
|
||||
training_data_size = 0
|
||||
rvc_enabled: bool = False
|
||||
rvc_char_model_file: str = "Disabled"
|
||||
rvc_narr_model_file: str = "Disabled"
|
||||
split_audio: bool = True
|
||||
autotune: bool = False
|
||||
pitch: int = 0
|
||||
filter_radius: int = 3
|
||||
index_rate: float = 0.75
|
||||
rms_mix_rate: int = 1
|
||||
protect: float = 0.5
|
||||
hop_length: int = 130
|
||||
f0method: str = "fcpe"
|
||||
embedder_model: str = "hubert"
|
||||
training_data_size: int = 45000
|
||||
|
||||
@dataclass
|
||||
@dataclass
|
||||
class AlltalkConfigTgwUi:
|
||||
tgwui_activate_tts = False
|
||||
tgwui_autoplay_tts = False
|
||||
tgwui_narrator_enabled = ""
|
||||
tgwui_non_quoted_text_is = ""
|
||||
tgwui_deepspeed_enabled = False
|
||||
tgwui_language = ""
|
||||
tgwui_lowvram_enabled = False
|
||||
tgwui_pitch_set = 0
|
||||
tgwui_temperature_set = 0.0
|
||||
tgwui_repetitionpenalty_set = 0
|
||||
tgwui_generationspeed_set = 0
|
||||
tgwui_narrator_voice = ""
|
||||
tgwui_show_text = False
|
||||
tgwui_character_voice = ""
|
||||
tgwui_rvc_char_voice = ""
|
||||
tgwui_rvc_narr_voice = ""
|
||||
tgwui_activate_tts: bool = True
|
||||
tgwui_autoplay_tts: bool = True
|
||||
tgwui_narrator_enabled: str = "false"
|
||||
tgwui_non_quoted_text_is: str = "character"
|
||||
tgwui_deepspeed_enabled: bool = False
|
||||
tgwui_language: str = "English"
|
||||
tgwui_lowvram_enabled: bool = False
|
||||
tgwui_pitch_set: int = 0
|
||||
tgwui_temperature_set: float = 0.75
|
||||
tgwui_repetitionpenalty_set: int = 10
|
||||
tgwui_generationspeed_set: int = 1
|
||||
tgwui_narrator_voice: str = "female_01.wav"
|
||||
tgwui_show_text: bool = True
|
||||
tgwui_character_voice: str = "female_01.wav"
|
||||
tgwui_rvc_char_voice: str = "Disabled"
|
||||
tgwui_rvc_char_pitch: int = 0
|
||||
tgwui_rvc_narr_voice: str = "Disabled"
|
||||
tgwui_rvc_narr_pitch: int = 0
|
||||
|
||||
@dataclass
|
||||
class AlltalkConfigApiDef:
|
||||
api_port_number = 0
|
||||
api_allowed_filter = ""
|
||||
api_length_stripping = 0
|
||||
api_max_characters = 0
|
||||
api_use_legacy_api = False
|
||||
api_legacy_ip_address = ""
|
||||
api_text_filtering = ""
|
||||
api_narrator_enabled = ""
|
||||
api_text_not_inside = ""
|
||||
api_language = ""
|
||||
api_output_file_name = ""
|
||||
api_output_file_timestamp = False
|
||||
api_autoplay = False
|
||||
api_autoplay_volume = 0.0
|
||||
api_port_number: int = 7851
|
||||
api_allowed_filter: str = "[^a-zA-Z0-9\\s.,;:!?\\-\\'\"$\\u0400-\\u04FF\\u00C0-\\u017F\\u0150\\u0151\\u0170\\u0171\\u011E\\u011F\\u0130\\u0131\\u0900-\\u097F\\u2018\\u2019\\u201C\\u201D\\u3001\\u3002\\u3040-\\u309F\\u30A0-\\u30FF\\u4E00-\\u9FFF\\u3400-\\u4DBF\\uF900-\\uFAFF\\u0600-\\u06FF\\u0750-\\u077F\\uFB50-\\uFDFF\\uFE70-\\uFEFF\\uAC00-\\uD7A3\\u1100-\\u11FF\\u3130-\\u318F\\uFF01\\uFF0c\\uFF1A\\uFF1B\\uFF1F]"
|
||||
api_length_stripping: int = 3
|
||||
api_max_characters: int = 2000
|
||||
api_use_legacy_api: bool = False
|
||||
api_legacy_ip_address: str = "127.0.0.1"
|
||||
api_text_filtering: str = "standard"
|
||||
api_narrator_enabled: str = "false"
|
||||
api_text_not_inside: str = "character"
|
||||
api_language: str = "en"
|
||||
api_output_file_name: str = "myoutputfile"
|
||||
api_output_file_timestamp: bool = True
|
||||
api_autoplay: bool = False
|
||||
api_autoplay_volume: float = 0.5
|
||||
|
||||
@dataclass
|
||||
class AlltalkConfigDebug:
|
||||
debug_transcode = False
|
||||
debug_tts = False
|
||||
debug_openai = False
|
||||
debug_concat = False
|
||||
debug_tts_variables = False
|
||||
debug_rvc = False
|
||||
debug_transcode: bool = False
|
||||
debug_tts: bool = False
|
||||
debug_openai: bool = False
|
||||
debug_concat: bool = False
|
||||
debug_tts_variables: bool = False
|
||||
debug_rvc: bool = False
|
||||
debug_func: bool = False
|
||||
debug_api: bool = False
|
||||
debug_fullttstext: bool = False
|
||||
debug_narrator: bool = True
|
||||
|
||||
@dataclass
|
||||
class AlltalkConfigGradioPages:
|
||||
Generate_Help_page = False
|
||||
Voice2RVC_page = False
|
||||
TTS_Generator_page = False
|
||||
TTS_Engines_Settings_page = False
|
||||
alltalk_documentation_page = False
|
||||
api_documentation_page = False
|
||||
Generate_Help_page: bool = True
|
||||
Voice2RVC_page: bool = True
|
||||
TTS_Generator_page: bool = True
|
||||
TTS_Engines_Settings_page: bool = True
|
||||
alltalk_documentation_page: bool = True
|
||||
api_documentation_page: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -137,16 +143,29 @@ class AbstractJsonConfig(ABC):
|
||||
def _object_hook(self) -> Callable[[dict[Any, Any]], Any] | None:
|
||||
return lambda d: SimpleNamespace(**d)
|
||||
|
||||
def _save_file(self, path: Path | None | str, default = lambda o: o.__dict__, indent = 4):
|
||||
def _save_file(self, path: Path | None | str, default=None, indent=4):
|
||||
file_path = (Path(path) if type(path) is str else path) if path is not None else self.get_config_path()
|
||||
|
||||
|
||||
def custom_default(o):
|
||||
if isinstance(o, Path):
|
||||
return str(o) # Convert Path objects to strings
|
||||
elif hasattr(o, '__dict__'):
|
||||
return o.__dict__ # Use the object's __dict__ if it exists
|
||||
else:
|
||||
raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")
|
||||
|
||||
default = default or custom_default
|
||||
|
||||
def __save():
|
||||
with open(file_path, "w") as file:
|
||||
with open(file_path, 'w') as file:
|
||||
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]):
|
||||
lock_path = path.with_suffix('.lock')
|
||||
backup_path = None
|
||||
try:
|
||||
with FileLock(lock_path):
|
||||
# Create backup:
|
||||
@@ -157,15 +176,22 @@ class AbstractJsonConfig(ABC):
|
||||
try:
|
||||
callable()
|
||||
except Exception as e:
|
||||
if backup_path.exists():
|
||||
if backup_path and backup_path.exists():
|
||||
shutil.copy(backup_path, path)
|
||||
raise Exception(f"Failed to save config: {e}")
|
||||
finally:
|
||||
# Cleanup lock and backup files:
|
||||
lock_path.unlink()
|
||||
if backup and backup_path.exists():
|
||||
backup_path.unlink()
|
||||
|
||||
if lock_path.exists(): # Only try to delete if it exists
|
||||
try:
|
||||
lock_path.unlink()
|
||||
except FileNotFoundError:
|
||||
pass # Ignore if file doesn't exist
|
||||
|
||||
if backup and backup_path and backup_path.exists():
|
||||
try:
|
||||
backup_path.unlink()
|
||||
except FileNotFoundError:
|
||||
pass # Ignore if file doesn't exist
|
||||
|
||||
@abstractmethod
|
||||
def _handle_loaded_config(self, data):
|
||||
@@ -258,7 +284,7 @@ class AlltalkTTSEnginesConfig(AbstractJsonConfig):
|
||||
return self
|
||||
return self
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlltalkConfig(AbstractJsonConfig):
|
||||
__instance = None
|
||||
__this_dir = Path(__file__).parent.resolve()
|
||||
@@ -282,10 +308,6 @@ class AlltalkConfig(AbstractJsonConfig):
|
||||
self.gradio_pages = AlltalkConfigGradioPages()
|
||||
self._load_config()
|
||||
|
||||
@staticmethod
|
||||
def default_config_path():
|
||||
return AlltalkConfig.__this_dir / "confignew.json"
|
||||
|
||||
@staticmethod
|
||||
def get_instance(force_reload = False):
|
||||
if AlltalkConfig.__instance is None:
|
||||
@@ -305,13 +327,81 @@ class AlltalkConfig(AbstractJsonConfig):
|
||||
self._save_file(path)
|
||||
|
||||
def _handle_loaded_config(self, data):
|
||||
# Copy those fields for which there are members in this class:
|
||||
from dataclasses import fields, is_dataclass, asdict
|
||||
debug_me =False
|
||||
if debug_me:
|
||||
print("=== Loading Config ===")
|
||||
print(f"Initial data state: {vars(data)}")
|
||||
|
||||
# Create new instances with defaults
|
||||
default_instances = {
|
||||
'debugging': AlltalkConfigDebug(),
|
||||
'rvc_settings': AlltalkConfigRvcSettings(),
|
||||
'tgwui': AlltalkConfigTgwUi(),
|
||||
'api_def': AlltalkConfigApiDef(),
|
||||
'theme': AlltalkConfigTheme(),
|
||||
'gradio_pages': AlltalkConfigGradioPages()
|
||||
}
|
||||
if debug_me:
|
||||
print("\nDefault values for each class:")
|
||||
for name, instance in default_instances.items():
|
||||
if debug_me:
|
||||
print(f"{name}: {asdict(instance)}")
|
||||
# Show actual default values from dataclass
|
||||
print(f"Default values: {[(f.name, getattr(instance, f.name)) for f in fields(instance)]}")
|
||||
if hasattr(data, name):
|
||||
source = getattr(data, name)
|
||||
if debug_me:
|
||||
print(f"Source data: {vars(source) if hasattr(source, '__dict__') else source}")
|
||||
|
||||
for field in fields(instance):
|
||||
if hasattr(source, field.name):
|
||||
setattr(instance, field.name, getattr(source, field.name))
|
||||
if debug_me:
|
||||
print(f"Field {field.name}: {getattr(instance, field.name)}")
|
||||
|
||||
setattr(self, name, instance)
|
||||
|
||||
# Handle non-dataclass fields
|
||||
for n, v in inspect.getmembers(data):
|
||||
if hasattr(self, n) and not n.startswith("__"):
|
||||
if hasattr(self, n) and not n.startswith("__") and not is_dataclass(type(getattr(self, n))):
|
||||
setattr(self, n, v)
|
||||
|
||||
# Special properties (cannot use 'class' as property name):
|
||||
self.theme.clazz = data.theme.__dict__["class"]
|
||||
|
||||
# As a side effect, create the output directory:
|
||||
self.theme.clazz = data.theme.__dict__.get("class", data.theme.__dict__.get("clazz", ""))
|
||||
self.get_output_directory().mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def to_dict(self):
|
||||
from dataclasses import is_dataclass, asdict
|
||||
debug_me =False
|
||||
if debug_me:
|
||||
print("=== Converting to dict ===")
|
||||
result = {}
|
||||
|
||||
for key, value in vars(self).items():
|
||||
if not key.startswith('_'):
|
||||
# print(f"\nProcessing {key}:")
|
||||
if is_dataclass(value):
|
||||
# print(f"Dataclass value before conversion: {vars(value)}")
|
||||
result[key] = asdict(value)
|
||||
# print(f"Converted to dict: {result[key]}")
|
||||
elif isinstance(value, SimpleNamespace):
|
||||
# print(f"SimpleNamespace value: {value.__dict__}")
|
||||
result[key] = value.__dict__
|
||||
else:
|
||||
# print(f"Regular value: {value}")
|
||||
result[key] = value
|
||||
|
||||
if 'theme' in result:
|
||||
if debug_me:
|
||||
print("\nProcessing theme:")
|
||||
print(f"Before class handling: {result['theme']}")
|
||||
result['theme']['class'] = self.theme.clazz
|
||||
result['theme'].pop('clazz', None)
|
||||
if debug_me:
|
||||
print(f"After class handling: {result['theme']}")
|
||||
if debug_me:
|
||||
print(f"\nFinal dict: {result}")
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user