diff --git a/src-python/config.py b/src-python/config.py index 3f1e24a3..9d5b3984 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -3,10 +3,10 @@ import inspect from os import path as os_path, makedirs as os_makedirs from json import load as json_load from json import dump as json_dump - +import threading from device_manager import device_manager from models.transcription.transcription_languages import transcription_lang -from utils import generatePercentageStringsList, isUniqueStrings +from utils import isUniqueStrings json_serializable_vars = {} def json_serializable(var_name): @@ -15,15 +15,11 @@ def json_serializable(var_name): return func return decorator -def saveJson(path, key, value): - with open(path, "r", encoding="utf-8") as fp: - json_data = json_load(fp) - json_data[key] = value - with open(path, "w", encoding="utf-8") as fp: - json_dump(json_data, fp, indent=4, ensure_ascii=False) - class Config: _instance = None + _config_data = {} + _timer = None + _debounce_time = 2 def __new__(cls): if cls._instance is None: @@ -32,6 +28,19 @@ class Config: cls._instance.load_config() return cls._instance + def saveConfigToFile(self): + with open(self.PATH_CONFIG, "w", encoding="utf-8") as fp: + json_dump(self._config_data, fp, indent=4, ensure_ascii=False) + + def saveConfig(self, key, value): + self._config_data[key] = value + + if isinstance(self._timer, threading.Timer) and self._timer.is_alive(): + self._timer.cancel() + self._timer = threading.Timer(self._debounce_time, self.saveConfigToFile) + self._timer.daemon = True + self._timer.start() + # Read Only @property def VERSION(self): @@ -78,8 +87,8 @@ class Config: return self._APPEARANCE_THEME_LIST @property - def UI_SCALING_LIST(self): - return self._UI_SCALING_LIST + def UI_SCALING_RANGE(self): + return self._UI_SCALING_RANGE @property def TEXTBOX_UI_SCALING_RANGE(self): @@ -90,12 +99,12 @@ class Config: return self._MESSAGE_BOX_RATIO_RANGE @property - def SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT(self): - return self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT + def SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_LIST(self): + return self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_LIST @property - def SELECTABLE_WHISPER_WEIGHT_TYPE_DICT(self): - return self._SELECTABLE_WHISPER_WEIGHT_TYPE_DICT + def SELECTABLE_WHISPER_WEIGHT_TYPE_LIST(self): + return self._SELECTABLE_WHISPER_WEIGHT_TYPE_LIST @property def MAX_MIC_THRESHOLD(self): @@ -224,7 +233,7 @@ class Config: def SELECTED_TAB_NO(self, value): if isinstance(value, str): self._SELECTED_TAB_NO = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_TRANSLATION_ENGINES') @@ -235,7 +244,7 @@ class Config: def SELECTED_TRANSLATION_ENGINES(self, value): if isinstance(value, dict): self._SELECTED_TRANSLATION_ENGINES = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_YOUR_LANGUAGES') @@ -256,7 +265,7 @@ class Config: self._SELECTED_YOUR_LANGUAGES = value except Exception: pass - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_TARGET_LANGUAGES') @@ -277,7 +286,7 @@ class Config: self._SELECTED_TARGET_LANGUAGES = value except Exception: pass - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_TRANSCRIPTION_ENGINE') @@ -288,7 +297,7 @@ class Config: def SELECTED_TRANSCRIPTION_ENGINE(self, value): if isinstance(value, str): self._SELECTED_TRANSCRIPTION_ENGINE = value - # saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + # self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MULTI_LANGUAGE_TRANSLATION') @@ -299,7 +308,7 @@ class Config: def MULTI_LANGUAGE_TRANSLATION(self, value): if isinstance(value, bool): self._MULTI_LANGUAGE_TRANSLATION = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('CONVERT_MESSAGE_TO_ROMAJI') @@ -310,7 +319,7 @@ class Config: def CONVERT_MESSAGE_TO_ROMAJI(self, value): if isinstance(value, bool): self._CONVERT_MESSAGE_TO_ROMAJI = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('CONVERT_MESSAGE_TO_HIRAGANA') @@ -321,7 +330,7 @@ class Config: def CONVERT_MESSAGE_TO_HIRAGANA(self, value): if isinstance(value, bool): self._CONVERT_MESSAGE_TO_HIRAGANA = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MAIN_WINDOW_SIDEBAR_COMPACT_MODE') @@ -332,7 +341,7 @@ class Config: def MAIN_WINDOW_SIDEBAR_COMPACT_MODE(self, value): if isinstance(value, bool): self._MAIN_WINDOW_SIDEBAR_COMPACT_MODE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) ## Config Window @property @@ -344,7 +353,7 @@ class Config: def TRANSPARENCY(self, value): if isinstance(value, int): self._TRANSPARENCY = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('APPEARANCE_THEME') @@ -355,7 +364,7 @@ class Config: def APPEARANCE_THEME(self, value): if value in self.APPEARANCE_THEME_LIST: self._APPEARANCE_THEME = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('UI_SCALING') @@ -366,7 +375,7 @@ class Config: def UI_SCALING(self, value): if isinstance(value, int): self._UI_SCALING = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('TEXTBOX_UI_SCALING') @@ -377,7 +386,7 @@ class Config: def TEXTBOX_UI_SCALING(self, value): if isinstance(value, int): self._TEXTBOX_UI_SCALING = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MESSAGE_BOX_RATIO') @@ -388,7 +397,7 @@ class Config: def MESSAGE_BOX_RATIO(self, value): if isinstance(value, (int, float)): self._MESSAGE_BOX_RATIO = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('FONT_FAMILY') @@ -399,7 +408,7 @@ class Config: def FONT_FAMILY(self, value): if isinstance(value, str): self._FONT_FAMILY = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('UI_LANGUAGE') @@ -410,7 +419,7 @@ class Config: def UI_LANGUAGE(self, value): if isinstance(value, str): self._UI_LANGUAGE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('RESTORE_MAIN_WINDOW_GEOMETRY') @@ -421,7 +430,7 @@ class Config: def RESTORE_MAIN_WINDOW_GEOMETRY(self, value): if isinstance(value, bool): self._RESTORE_MAIN_WINDOW_GEOMETRY = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MAIN_WINDOW_GEOMETRY') @@ -434,7 +443,7 @@ class Config: for key, value in value.items(): if isinstance(value, int): self._MAIN_WINDOW_GEOMETRY[key] = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.MAIN_WINDOW_GEOMETRY) + self.saveConfig(inspect.currentframe().f_code.co_name, self.MAIN_WINDOW_GEOMETRY) @property @json_serializable('AUTO_MIC_SELECT') @@ -445,7 +454,7 @@ class Config: def AUTO_MIC_SELECT(self, value): if isinstance(value, bool): self._AUTO_MIC_SELECT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_MIC_HOST') @@ -456,7 +465,7 @@ class Config: def SELECTED_MIC_HOST(self, value): if value in [host for host in device_manager.getMicDevices().keys()]: self._SELECTED_MIC_HOST = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_MIC_DEVICE') @@ -467,7 +476,7 @@ class Config: def SELECTED_MIC_DEVICE(self, value): if value in [device["name"] for device in device_manager.getMicDevices()[self.SELECTED_MIC_HOST]]: self._SELECTED_MIC_DEVICE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_THRESHOLD') @@ -478,7 +487,7 @@ class Config: def MIC_THRESHOLD(self, value): if isinstance(value, int): self._MIC_THRESHOLD = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_AUTOMATIC_THRESHOLD') @@ -489,7 +498,7 @@ class Config: def MIC_AUTOMATIC_THRESHOLD(self, value): if isinstance(value, bool): self._MIC_AUTOMATIC_THRESHOLD = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_RECORD_TIMEOUT') @@ -500,7 +509,7 @@ class Config: def MIC_RECORD_TIMEOUT(self, value): if isinstance(value, int): self._MIC_RECORD_TIMEOUT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_PHRASE_TIMEOUT') @@ -511,7 +520,7 @@ class Config: def MIC_PHRASE_TIMEOUT(self, value): if isinstance(value, int): self._MIC_PHRASE_TIMEOUT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_MAX_PHRASES') @@ -522,7 +531,7 @@ class Config: def MIC_MAX_PHRASES(self, value): if isinstance(value, int): self._MIC_MAX_PHRASES = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_WORD_FILTER') @@ -533,7 +542,7 @@ class Config: def MIC_WORD_FILTER(self, value): if isinstance(value, list): self._MIC_WORD_FILTER = sorted(set(value), key=value.index) - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_AVG_LOGPROB') @@ -544,7 +553,7 @@ class Config: def MIC_AVG_LOGPROB(self, value): if isinstance(value, (int, float)): self._MIC_AVG_LOGPROB = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('MIC_NO_SPEECH_PROB') @@ -555,7 +564,7 @@ class Config: def MIC_NO_SPEECH_PROB(self, value): if isinstance(value, (int, float)): self._MIC_NO_SPEECH_PROB = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('AUTO_SPEAKER_SELECT') @@ -566,7 +575,7 @@ class Config: def AUTO_SPEAKER_SELECT(self, value): if isinstance(value, bool): self._AUTO_SPEAKER_SELECT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_SPEAKER_DEVICE') @@ -577,7 +586,7 @@ class Config: def SELECTED_SPEAKER_DEVICE(self, value): if value in [device["name"] for device in device_manager.getSpeakerDevices()]: self._SELECTED_SPEAKER_DEVICE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_THRESHOLD') @@ -588,7 +597,7 @@ class Config: def SPEAKER_THRESHOLD(self, value): if isinstance(value, int): self._SPEAKER_THRESHOLD = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_AUTOMATIC_THRESHOLD') @@ -599,7 +608,7 @@ class Config: def SPEAKER_AUTOMATIC_THRESHOLD(self, value): if isinstance(value, bool): self._SPEAKER_AUTOMATIC_THRESHOLD = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_RECORD_TIMEOUT') @@ -610,7 +619,7 @@ class Config: def SPEAKER_RECORD_TIMEOUT(self, value): if isinstance(value, int): self._SPEAKER_RECORD_TIMEOUT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_PHRASE_TIMEOUT') @@ -621,7 +630,7 @@ class Config: def SPEAKER_PHRASE_TIMEOUT(self, value): if isinstance(value, int): self._SPEAKER_PHRASE_TIMEOUT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_MAX_PHRASES') @@ -632,7 +641,7 @@ class Config: def SPEAKER_MAX_PHRASES(self, value): if isinstance(value, int): self._SPEAKER_MAX_PHRASES = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_AVG_LOGPROB') @@ -643,7 +652,7 @@ class Config: def SPEAKER_AVG_LOGPROB(self, value): if isinstance(value, (int, float)): self._SPEAKER_AVG_LOGPROB = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SPEAKER_NO_SPEECH_PROB') @@ -654,7 +663,7 @@ class Config: def SPEAKER_NO_SPEECH_PROB(self, value): if isinstance(value, (int, float)): self._SPEAKER_NO_SPEECH_PROB = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('OSC_IP_ADDRESS') @@ -665,7 +674,7 @@ class Config: def OSC_IP_ADDRESS(self, value): if isinstance(value, str): self._OSC_IP_ADDRESS = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('OSC_PORT') @@ -676,7 +685,7 @@ class Config: def OSC_PORT(self, value): if isinstance(value, int): self._OSC_PORT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('AUTH_KEYS') @@ -689,7 +698,7 @@ class Config: for key, value in value.items(): if isinstance(value, str): self._AUTH_KEYS[key] = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.AUTH_KEYS) + self.saveConfig(inspect.currentframe().f_code.co_name, self.AUTH_KEYS) @property @json_serializable('USE_EXCLUDE_WORDS') @@ -700,7 +709,7 @@ class Config: def USE_EXCLUDE_WORDS(self, value): if isinstance(value, bool): self._USE_EXCLUDE_WORDS = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('USE_TRANSLATION_FEATURE') @@ -711,7 +720,7 @@ class Config: def USE_TRANSLATION_FEATURE(self, value): if isinstance(value, bool): self._USE_TRANSLATION_FEATURE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('USE_WHISPER_FEATURE') @@ -722,7 +731,7 @@ class Config: def USE_WHISPER_FEATURE(self, value): if isinstance(value, bool): self._USE_WHISPER_FEATURE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_TRANSLATION_COMPUTE_DEVICE') @@ -733,7 +742,7 @@ class Config: def SELECTED_TRANSLATION_COMPUTE_DEVICE(self, value): if isinstance(value, dict): self._SELECTED_TRANSLATION_COMPUTE_DEVICE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SELECTED_TRANSCRIPTION_COMPUTE_DEVICE') @@ -744,7 +753,7 @@ class Config: def SELECTED_TRANSCRIPTION_COMPUTE_DEVICE(self, value): if isinstance(value, dict): self._SELECTED_TRANSCRIPTION_COMPUTE_DEVICE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('CTRANSLATE2_WEIGHT_TYPE') @@ -753,10 +762,10 @@ class Config: @CTRANSLATE2_WEIGHT_TYPE.setter def CTRANSLATE2_WEIGHT_TYPE(self, value): - # if isinstance(value, str) and value in self.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT: + # if isinstance(value, str) and value in self.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_LIST: if isinstance(value, str): self._CTRANSLATE2_WEIGHT_TYPE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('WHISPER_WEIGHT_TYPE') @@ -767,7 +776,7 @@ class Config: def WHISPER_WEIGHT_TYPE(self, value): if isinstance(value, str): self._WHISPER_WEIGHT_TYPE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('AUTO_CLEAR_MESSAGE_BOX') @@ -778,7 +787,7 @@ class Config: def AUTO_CLEAR_MESSAGE_BOX(self, value): if isinstance(value, bool): self._AUTO_CLEAR_MESSAGE_BOX = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_ONLY_TRANSLATED_MESSAGES') @@ -789,7 +798,7 @@ class Config: def SEND_ONLY_TRANSLATED_MESSAGES(self, value): if isinstance(value, bool): self._SEND_ONLY_TRANSLATED_MESSAGES = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_MESSAGE_BUTTON_TYPE') @@ -800,7 +809,7 @@ class Config: def SEND_MESSAGE_BUTTON_TYPE(self, value): if isinstance(value, str): self._SEND_MESSAGE_BUTTON_TYPE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('OVERLAY_SETTINGS') @@ -813,7 +822,7 @@ class Config: for key, value in value.items(): if isinstance(value, (int, float)): self._OVERLAY_SETTINGS[key] = float(value) - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.OVERLAY_SETTINGS) + self.saveConfig(inspect.currentframe().f_code.co_name, self.OVERLAY_SETTINGS) @property @json_serializable('OVERLAY_SMALL_LOG') @@ -824,7 +833,7 @@ class Config: def OVERLAY_SMALL_LOG(self, value): if isinstance(value, bool): self._OVERLAY_SMALL_LOG = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('OVERLAY_SMALL_LOG_SETTINGS') @@ -842,7 +851,7 @@ class Config: case "display_duration" | "fadeout_duration": if isinstance(value, int): self._OVERLAY_SMALL_LOG_SETTINGS[key] = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.OVERLAY_SMALL_LOG_SETTINGS) + self.saveConfig(inspect.currentframe().f_code.co_name, self.OVERLAY_SMALL_LOG_SETTINGS) @property @json_serializable('OVERLAY_UI_TYPE') @@ -853,7 +862,7 @@ class Config: def OVERLAY_UI_TYPE(self, value): if isinstance(value, str): self._OVERLAY_UI_TYPE = value - # saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + # self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_MESSAGE_TO_VRC') @@ -864,7 +873,7 @@ class Config: def SEND_MESSAGE_TO_VRC(self, value): if isinstance(value, bool): self._SEND_MESSAGE_TO_VRC = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_MESSAGE_FORMAT') @@ -877,7 +886,7 @@ class Config: if isUniqueStrings(["[message]"], value) is False: value = "[message]" self._SEND_MESSAGE_FORMAT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_MESSAGE_FORMAT_WITH_T') @@ -890,7 +899,7 @@ class Config: if isUniqueStrings(["[message]", "[translation]"], value) is False: value = "[message]([translation])" self._SEND_MESSAGE_FORMAT_WITH_T = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('RECEIVED_MESSAGE_FORMAT') @@ -903,7 +912,7 @@ class Config: if isUniqueStrings(["[message]"], value) is False: value = "[message]" self._RECEIVED_MESSAGE_FORMAT = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('RECEIVED_MESSAGE_FORMAT_WITH_T') @@ -916,7 +925,7 @@ class Config: if isUniqueStrings(["[message]", "[translation]"], value) is False: value = "[message]([translation])" self._RECEIVED_MESSAGE_FORMAT_WITH_T = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('SEND_RECEIVED_MESSAGE_TO_VRC') @@ -927,7 +936,7 @@ class Config: def SEND_RECEIVED_MESSAGE_TO_VRC(self, value): if isinstance(value, bool): self._SEND_RECEIVED_MESSAGE_TO_VRC = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('LOGGER_FEATURE') @@ -938,7 +947,7 @@ class Config: def LOGGER_FEATURE(self, value): if isinstance(value, bool): self._LOGGER_FEATURE = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) @property @json_serializable('VRC_MIC_MUTE_SYNC') @@ -949,7 +958,7 @@ class Config: def VRC_MIC_MUTE_SYNC(self, value): if isinstance(value, bool): self._VRC_MIC_MUTE_SYNC = value - saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + self.saveConfig(inspect.currentframe().f_code.co_name, value) def init_config(self): # Read Only @@ -966,27 +975,25 @@ class Config: self._BOOTH_URL = "https://misyaguziya.booth.pm/" self._DOCUMENTS_URL = "https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246" self._DEEPL_AUTH_KEY_PAGE_URL = "https://www.deepl.com/ja/account/summary" - self._TRANSPARENCY_RANGE = (50, 100) + self._TRANSPARENCY_RANGE = (40, 100) self._APPEARANCE_THEME_LIST = ["Light", "Dark", "System"] - self._UI_SCALING_LIST = generatePercentageStringsList(start=40, end=200, step=10) - self._TEXTBOX_UI_SCALING_RANGE = (50, 200) + self._UI_SCALING_RANGE = (40, 200) + self._TEXTBOX_UI_SCALING_RANGE = (40, 200) self._MESSAGE_BOX_RATIO_RANGE = (1, 99) - self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = { - # {Save json str}: {i18n_placeholder} pairs - "Small": "Small", - "Large": "Large", - } + self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_LIST = [ + "Small", + "Large", + ] - self._SELECTABLE_WHISPER_WEIGHT_TYPE_DICT = { - # {Save json str}: {i18n_placeholder} pairs - "tiny": "tiny", - "base": "base", - "small": "small", - "medium": "medium", - "large-v1": "large-v1", - "large-v2": "large-v2", - "large-v3": "large-v3", - } + self._SELECTABLE_WHISPER_WEIGHT_TYPE_LIST = [ + "tiny", + "base", + "small", + "medium", + "large-v1", + "large-v2", + "large-v3", + ] self._MAX_MIC_THRESHOLD = 2000 self._MAX_SPEAKER_THRESHOLD = 4000 @@ -1163,21 +1170,16 @@ class Config: def load_config(self): if os_path.isfile(self.PATH_CONFIG) is not False: with open(self.PATH_CONFIG, 'r', encoding="utf-8") as fp: - config = json_load(fp) + if fp.readable() and fp.seek(0, 2) > 0: + fp.seek(0) + self._config_data = json_load(fp) - old_message_format = None - for key in config.keys(): - if key == "MESSAGE_FORMAT": - old_message_format = config[key] - setattr(self, key, config[key]) - - if old_message_format is not None: - setattr(self, "SEND_MESSAGE_FORMAT_WITH_T", old_message_format) + for key, value in self._config_data.items(): + setattr(self, key, value) with open(self.PATH_CONFIG, 'w', encoding="utf-8") as fp: - config = {} for var_name, var_func in json_serializable_vars.items(): - config[var_name] = var_func(self) - json_dump(config, fp, indent=4, ensure_ascii=False) + self._config_data[var_name] = var_func(self) + json_dump(self._config_data, fp, indent=4, ensure_ascii=False) config = Config() \ No newline at end of file diff --git a/src-python/models/transcription/transcription_whisper.py b/src-python/models/transcription/transcription_whisper.py index 5e6f00bf..398a7524 100644 --- a/src-python/models/transcription/transcription_whisper.py +++ b/src-python/models/transcription/transcription_whisper.py @@ -1,7 +1,6 @@ from os import path as os_path, makedirs as os_makedirs from requests import get as requests_get from typing import Callable -import torch import huggingface_hub from faster_whisper import WhisperModel import logging diff --git a/src-python/utils.py b/src-python/utils.py index fbf55c43..9ea1725e 100644 --- a/src-python/utils.py +++ b/src-python/utils.py @@ -22,12 +22,6 @@ def makeEven(number, minus:bool=False): return number if isEven(number) else number - 1 return number if isEven(number) else number + 1 -def generatePercentageStringsList(start:int, end:int, step:int): - strings = [] - for percent in range(start, end + 1, step): - strings.append(f"{percent}%") - return strings - def intToPctStr(value:int): return f"{value}%" diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index c707a775..9a9712e2 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -11,10 +11,14 @@ import torch class Controller: def __init__(self) -> None: + self.init_mapping = {} self.run_mapping = {} self.run = None self.device_access_status = True + def setInitMapping(self, init_mapping:dict) -> None: + self.init_mapping = init_mapping + def setRunMapping(self, run_mapping:dict) -> None: self.run_mapping = run_mapping @@ -43,6 +47,18 @@ class Controller: model.getListSpeakerDevice(), ) + def updateConfigSettings(self) -> None: + settings = {} + for endpoint, dict_data in self.init_mapping.items(): + response = dict_data["variable"](None) + result = response.get("result", None) + settings[endpoint] = result + self.run( + 200, + self.run_mapping["initialization_complete"], + settings, + ) + def restartAccessDevices(self) -> None: if config.ENABLE_TRANSCRIPTION_SEND is True: self.startThreadingTranscriptionSendMessage() @@ -353,8 +369,8 @@ class Controller: return {"status":200, "result":config.APPEARANCE_THEME_LIST} @staticmethod - def getUiScalingList(*args, **kwargs) -> dict: - return {"status":200, "result":config.UI_SCALING_LIST} + def getUiScalingRange(*args, **kwargs) -> dict: + return {"status":200, "result":config.UI_SCALING_RANGE} @staticmethod def getTextboxUiScalingRange(*args, **kwargs) -> dict: @@ -381,8 +397,8 @@ class Controller: return {"status":200,"result":config.SELECTED_TRANSLATION_COMPUTE_DEVICE} @staticmethod - def getSelectableCtranslate2WeightTypeDict(*args, **kwargs) -> dict: - return {"status":200, "result":config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT} + def getSelectableCtranslate2WeightTypeList(*args, **kwargs) -> dict: + return {"status":200, "result":config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_LIST} @staticmethod def getSelectedTranscriptionComputeDevice(*args, **kwargs) -> dict: @@ -395,8 +411,8 @@ class Controller: return {"status":200,"result":config.SELECTED_TRANSCRIPTION_COMPUTE_DEVICE} @staticmethod - def getSelectableWhisperModelTypeDict(*args, **kwargs) -> dict: - return {"status":200, "result":config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT} + def getSelectableWhisperWeightTypeList(*args, **kwargs) -> dict: + return {"status":200, "result":config.SELECTABLE_WHISPER_WEIGHT_TYPE_LIST} @staticmethod def getMaxMicThreshold(*args, **kwargs) -> dict: @@ -1704,6 +1720,8 @@ class Controller: if config.AUTO_SPEAKER_SELECT is True: self.setEnableAutoSpeakerSelect() + self.updateConfigSettings() + printLog("End Initialization") self.startWatchdog() \ No newline at end of file diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index f49872cf..1840014a 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -34,6 +34,8 @@ run_mapping = { "speaker_device_list":"/run/speaker_device_list", "update_software_flag":"/run/update_software_flag", + + "initialization_complete":"/run/initialization_complete", } controller.setRunMapping(run_mapping) @@ -94,11 +96,11 @@ mapping = { "/get/data/transparency": {"status": True, "variable":controller.getTransparency}, "/set/data/transparency": {"status": True, "variable":controller.setTransparency}, - "/get/data/appearance_theme_list": {"status": True, "variable":controller.getAppearanceThemesList}, - "/get/data/appearance_theme": {"status": True, "variable":controller.getAppearanceTheme}, - "/set/data/appearance_theme": {"status": True, "variable":controller.setAppearanceTheme}, + # "/get/data/appearance_theme_list": {"status": True, "variable":controller.getAppearanceThemesList}, + # "/get/data/appearance_theme": {"status": True, "variable":controller.getAppearanceTheme}, + # "/set/data/appearance_theme": {"status": True, "variable":controller.setAppearanceTheme}, - "/get/data/ui_scaling_list": {"status": True, "variable":controller.getUiScalingList}, + "/get/data/ui_scaling_range": {"status": True, "variable":controller.getUiScalingRange}, "/get/data/ui_scaling": {"status": True, "variable":controller.getUiScaling}, "/set/data/ui_scaling": {"status": True, "variable":controller.setUiScaling}, @@ -128,11 +130,11 @@ mapping = { "/set/enable/use_translation_feature": {"status": True, "variable":controller.setEnableUseTranslationFeature}, "/set/disable/use_translation_feature": {"status": True, "variable":controller.setDisableUseTranslationFeature}, - "/get/data/translation_compute_device_dict": {"status": True, "variable":controller.getComputeDeviceList}, + "/get/data/translation_compute_device_list": {"status": True, "variable":controller.getComputeDeviceList}, "/get/data/selected_translation_compute_device": {"status": True, "variable":controller.getSelectedTranslationComputeDevice}, "/set/data/selected_translation_compute_device": {"status": True, "variable":controller.setSelectedTranslationComputeDevice}, - "/get/data/selectable_ctranslate2_weight_type_dict": {"status": True, "variable":controller.getSelectableCtranslate2WeightTypeDict}, + "/get/data/selectable_ctranslate2_weight_type_list": {"status": True, "variable":controller.getSelectableCtranslate2WeightTypeList}, "/get/data/ctranslate2_weight_type": {"status": True, "variable":controller.getCtranslate2WeightType}, "/set/data/ctranslate2_weight_type": {"status": True, "variable":controller.setCtranslate2WeightType}, @@ -233,11 +235,11 @@ mapping = { "/set/enable/check_speaker_threshold": {"status": True, "variable":controller.setEnableCheckSpeakerThreshold}, "/set/disable/check_speaker_threshold": {"status": True, "variable":controller.setDisableCheckSpeakerThreshold}, - "/get/data/transcription_compute_device_dict": {"status": True, "variable":controller.getComputeDeviceList}, + "/get/data/transcription_compute_device_list": {"status": True, "variable":controller.getComputeDeviceList}, "/get/data/selected_transcription_compute_device": {"status": True, "variable":controller.getSelectedTranscriptionComputeDevice}, "/set/data/selected_transcription_compute_device": {"status": True, "variable":controller.setSelectedTranscriptionComputeDevice}, - "/get/data/selectable_whisper_weight_type_dict": {"status": True, "variable":controller.getSelectableWhisperModelTypeDict}, + "/get/data/selectable_whisper_weight_type_list": {"status": True, "variable":controller.getSelectableWhisperWeightTypeList}, "/get/data/whisper_weight_type": {"status": True, "variable":controller.getWhisperWeightType}, "/set/data/whisper_weight_type": {"status": True, "variable":controller.setWhisperWeightType}, @@ -315,6 +317,9 @@ mapping = { # "/run/stop_watchdog": {"status": True, "variable":controller.stopWatchdog}, } +init_mapping = {key:value for key, value in mapping.items() if key.startswith("/get/data/")} +controller.setInitMapping(init_mapping) + class Main: def __init__(self) -> None: self.queue = Queue() diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index 1e3b57a8..8ed648e8 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -33,45 +33,14 @@ import { } from "@logics_common"; import { - useSoftwareVersion, - useEnableAutoMicSelect, - useEnableAutoSpeakerSelect, - useSelectedMicHost, - useSelectedMicDevice, - useSelectedSpeakerDevice, - useMicThreshold, - useSpeakerThreshold, - useEnableAutoClearMessageInputBox, - useEnableSendOnlyTranslatedMessages, - useEnableAutoExportMessageLogs, - useEnableVrcMicMuteSync, - useEnableSendMessageToVrc, - useSendMessageButtonType, useUiLanguage, useUiScaling, - useMessageLogUiScaling, useSelectedFontFamily, useTransparency, - useMicHostList, - useMicDeviceList, - useSpeakerDeviceList, - useMicRecordTimeout, - useMicPhraseTimeout, - useMicMaxWords, - useMicWordFilterList, - useSpeakerRecordTimeout, - useSpeakerPhraseTimeout, - useSpeakerMaxWords, - useOscIpAddress, - useOscPort, } from "@logics_configs"; import { useMainFunction, - useIsMainPageCompactMode, - useLanguageSettings, - useSelectableLanguageList, - useMessageInputBoxRatio, } from "@logics_main"; const StartPythonFacadeComponent = () => { @@ -79,119 +48,11 @@ const StartPythonFacadeComponent = () => { const hasRunRef = useRef(false); const { asyncFetchFonts } = useAsyncFetchFonts(); - const { fetchAndUpdateWindowGeometry } = useWindow(); - - const { getMicHostList } = useMicHostList(); - const { getMicDeviceList } = useMicDeviceList(); - const { getSpeakerDeviceList } = useSpeakerDeviceList(); - - const { getIsMainPageCompactMode } = useIsMainPageCompactMode(); - const { getSoftwareVersion } = useSoftwareVersion(); - const { getEnableAutoMicSelect } = useEnableAutoMicSelect(); - const { getEnableAutoSpeakerSelect } = useEnableAutoSpeakerSelect(); - const { getSelectedMicHost } = useSelectedMicHost(); - const { getSelectedMicDevice } = useSelectedMicDevice(); - const { getSelectedSpeakerDevice } = useSelectedSpeakerDevice(); - const { getMicThreshold, getEnableAutomaticMicThreshold } = useMicThreshold(); - const { getSpeakerThreshold, getEnableAutomaticSpeakerThreshold } = useSpeakerThreshold(); - - const { getEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox(); - const { getEnableSendOnlyTranslatedMessages } = useEnableSendOnlyTranslatedMessages(); - const { getEnableAutoExportMessageLogs } = useEnableAutoExportMessageLogs(); - const { getEnableVrcMicMuteSync } = useEnableVrcMicMuteSync(); - const { getEnableSendMessageToVrc } = useEnableSendMessageToVrc(); - - const { getSendMessageButtonType } = useSendMessageButtonType(); - const { getUiLanguage } = useUiLanguage(); - const { getUiScaling } = useUiScaling(); - const { getMessageLogUiScaling } = useMessageLogUiScaling(); - const { getSelectedFontFamily } = useSelectedFontFamily(); - const { getTransparency } = useTransparency(); - - const { - getSelectedPresetTabNumber, - getEnableMultiTranslation, - getSelectedYourLanguages, - getSelectedTargetLanguages, - getTranslationEngines, - getSelectedTranslationEngines, - } = useLanguageSettings(); - const { getSelectableLanguageList } = useSelectableLanguageList(); - const { getMessageInputBoxRatio } = useMessageInputBoxRatio(); - - const { getMicRecordTimeout } = useMicRecordTimeout(); - const { getMicPhraseTimeout } = useMicPhraseTimeout(); - const { getMicMaxWords } = useMicMaxWords(); - const { getMicWordFilterList } = useMicWordFilterList(); - - const { getSpeakerRecordTimeout } = useSpeakerRecordTimeout(); - const { getSpeakerPhraseTimeout } = useSpeakerPhraseTimeout(); - const { getSpeakerMaxWords } = useSpeakerMaxWords(); - - const { getOscIpAddress } = useOscIpAddress(); - const { getOscPort } = useOscPort(); - useEffect(() => { if (!hasRunRef.current) { asyncStartPython().then(() => { startFeedingToWatchDog(); - - fetchAndUpdateWindowGeometry(); - - getUiLanguage(); - getUiScaling(); - getMessageLogUiScaling(); - getIsMainPageCompactMode(); - getMessageInputBoxRatio(); - getTransparency(); - asyncFetchFonts(); - getSelectedFontFamily(); - - getSoftwareVersion(); - - getSelectedPresetTabNumber(); - getEnableMultiTranslation(); - getSelectedYourLanguages(); - getSelectedTargetLanguages(); - getSelectableLanguageList(); - getTranslationEngines(); - getSelectedTranslationEngines(); - - getMicHostList(); - getMicDeviceList(); - getSpeakerDeviceList(); - - getEnableAutoMicSelect(); - getEnableAutoSpeakerSelect(); - getSelectedMicHost(); - getSelectedMicDevice(); - getSelectedSpeakerDevice(); - - getMicThreshold(); - getSpeakerThreshold(); - getEnableAutomaticMicThreshold(); - getEnableAutomaticSpeakerThreshold(); - - getMicRecordTimeout(); - getMicPhraseTimeout(); - getMicMaxWords(); - getMicWordFilterList(); - - getSpeakerRecordTimeout(); - getSpeakerPhraseTimeout(); - getSpeakerMaxWords(); - - getEnableAutoClearMessageInputBox(); - getSendMessageButtonType(); - - getEnableSendOnlyTranslatedMessages(); - getEnableAutoExportMessageLogs(); - getEnableVrcMicMuteSync(); - getEnableSendMessageToVrc(); - - getOscIpAddress(); - getOscPort(); }).catch((err) => { console.error(err); }); diff --git a/src-ui/logics/common/useWindow.js b/src-ui/logics/common/useWindow.js index 760e866b..9d2a7669 100644 --- a/src-ui/logics/common/useWindow.js +++ b/src-ui/logics/common/useWindow.js @@ -51,9 +51,6 @@ export const useWindow = () => { } }; - const fetchAndUpdateWindowGeometry = () => { - asyncStdoutToPython("/get/data/main_window_geometry"); - }; const WindowGeometryController = () => { useEffect(() => { @@ -86,7 +83,6 @@ export const useWindow = () => { return { WindowGeometryController, asyncSaveWindowGeometry, - fetchAndUpdateWindowGeometry, restoreWindowGeometry, }; }; diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 639edfd1..cd109e60 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -362,9 +362,21 @@ export const useReceiveRoutes = () => { "/set/data/speaker_max_phrases": updateSpeakerMaxWords, }; + const receiveRoutes = (parsed_data) => { + const initDataSyncProcess = (payload) => { + for (const [endpoint, value] of Object.entries(payload)) { + const route = routes[endpoint]; + (route) ? route(value) : console.error(`Invalid endpoint: ${endpoint}\vvalue: ${JSON.stringify(value)}`); + } + }; + switch (parsed_data.status) { case 200: + if (parsed_data.endpoint === "/run/initialization_complete") { + initDataSyncProcess(parsed_data.result); + break; + }; const route = routes[parsed_data.endpoint]; (route) ? route(parsed_data.result) : console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`); break;