Updated config.py

This commit is contained in:
erew123 authored and GitHub committed 2024-11-20 00:50:19 +00:00
1 parent 18b580db04
commit fff2fac88d
1 file changed
+166 -76
+166 -76
View File
@@ -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