👍[Update] Remove Unused Files
This commit is contained in:
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,20 +1,7 @@
|
|||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
config.json
|
config.json
|
||||||
VRC_ChatBox_translator.spec
|
|
||||||
memo.txt
|
memo.txt
|
||||||
app/
|
|
||||||
booth/
|
|
||||||
pyinstaller/
|
|
||||||
VRCT.build/
|
|
||||||
VRCT.dist/
|
|
||||||
VRCT.onefile-build/
|
|
||||||
VRCT.exe
|
|
||||||
VRCT.spec
|
VRCT.spec
|
||||||
deepl-translate/
|
|
||||||
translators/
|
|
||||||
test/
|
|
||||||
*.pyc
|
*.pyc
|
||||||
.vscode/
|
|
||||||
lib/
|
|
||||||
logs/
|
logs/
|
||||||
@@ -1,511 +0,0 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from json import load, dump
|
|
||||||
import inspect
|
|
||||||
from os import path as os_path
|
|
||||||
from json import load as json_load
|
|
||||||
from json import dump as json_dump
|
|
||||||
import tkinter as tk
|
|
||||||
from tkinter import font
|
|
||||||
from languages import selectable_languages
|
|
||||||
from models.translation.translation_languages import translatorEngine, translation_lang
|
|
||||||
from models.transcription.transcription_languages import transcription_lang
|
|
||||||
from models.transcription.transcription_utils import getInputDevices, getOutputDevices, getDefaultInputDevice, getDefaultOutputDevice
|
|
||||||
|
|
||||||
def saveJson(path, key, value):
|
|
||||||
with open(path, "r") as fp:
|
|
||||||
json_data = load(fp)
|
|
||||||
json_data[key] = value
|
|
||||||
with open(path, "w") as fp:
|
|
||||||
dump(json_data, fp, indent=4)
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
_instance = None
|
|
||||||
|
|
||||||
def __new__(cls):
|
|
||||||
if cls._instance is None:
|
|
||||||
cls._instance = super(Config, cls).__new__(cls)
|
|
||||||
cls._instance.init_config()
|
|
||||||
cls._instance.load_config()
|
|
||||||
return cls._instance
|
|
||||||
|
|
||||||
@property
|
|
||||||
def VERSION(self):
|
|
||||||
return self._VERSION
|
|
||||||
|
|
||||||
@property
|
|
||||||
def PATH_CONFIG(self):
|
|
||||||
return self._PATH_CONFIG
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_TRANSLATION(self):
|
|
||||||
return self._ENABLE_TRANSLATION
|
|
||||||
|
|
||||||
@ENABLE_TRANSLATION.setter
|
|
||||||
def ENABLE_TRANSLATION(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_TRANSLATION = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_TRANSCRIPTION_SEND(self):
|
|
||||||
return self._ENABLE_TRANSCRIPTION_SEND
|
|
||||||
|
|
||||||
@ENABLE_TRANSCRIPTION_SEND.setter
|
|
||||||
def ENABLE_TRANSCRIPTION_SEND(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_TRANSCRIPTION_SEND = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_TRANSCRIPTION_RECEIVE(self):
|
|
||||||
return self._ENABLE_TRANSCRIPTION_RECEIVE
|
|
||||||
|
|
||||||
@ENABLE_TRANSCRIPTION_RECEIVE.setter
|
|
||||||
def ENABLE_TRANSCRIPTION_RECEIVE(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_TRANSCRIPTION_RECEIVE = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_FOREGROUND(self):
|
|
||||||
return self._ENABLE_FOREGROUND
|
|
||||||
|
|
||||||
@ENABLE_FOREGROUND.setter
|
|
||||||
def ENABLE_FOREGROUND(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_FOREGROUND = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def TRANSPARENCY(self):
|
|
||||||
return self._TRANSPARENCY
|
|
||||||
|
|
||||||
@TRANSPARENCY.setter
|
|
||||||
def TRANSPARENCY(self, value):
|
|
||||||
if type(value) is int and 0 <= value <= 100:
|
|
||||||
self._TRANSPARENCY = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def APPEARANCE_THEME(self):
|
|
||||||
return self._APPEARANCE_THEME
|
|
||||||
|
|
||||||
@APPEARANCE_THEME.setter
|
|
||||||
def APPEARANCE_THEME(self, value):
|
|
||||||
if value in ["Light", "Dark", "System"]:
|
|
||||||
self._APPEARANCE_THEME = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def UI_SCALING(self):
|
|
||||||
return self._UI_SCALING
|
|
||||||
|
|
||||||
@UI_SCALING.setter
|
|
||||||
def UI_SCALING(self, value):
|
|
||||||
if value in ["80%", "90%", "100%", "110%", "120%"]:
|
|
||||||
self._UI_SCALING = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def FONT_FAMILY(self):
|
|
||||||
return self._FONT_FAMILY
|
|
||||||
|
|
||||||
@FONT_FAMILY.setter
|
|
||||||
def FONT_FAMILY(self, value):
|
|
||||||
root = tk.Tk()
|
|
||||||
root.withdraw()
|
|
||||||
if value in list(font.families()):
|
|
||||||
self._FONT_FAMILY = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
root.destroy()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def UI_LANGUAGE(self):
|
|
||||||
return self._UI_LANGUAGE
|
|
||||||
|
|
||||||
@UI_LANGUAGE.setter
|
|
||||||
def UI_LANGUAGE(self, value):
|
|
||||||
if value in list(selectable_languages.keys()):
|
|
||||||
self._UI_LANGUAGE = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def CHOICE_TRANSLATOR(self):
|
|
||||||
return self._CHOICE_TRANSLATOR
|
|
||||||
|
|
||||||
@CHOICE_TRANSLATOR.setter
|
|
||||||
def CHOICE_TRANSLATOR(self, value):
|
|
||||||
if value in translatorEngine:
|
|
||||||
self._CHOICE_TRANSLATOR = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SOURCE_LANG(self):
|
|
||||||
return self._INPUT_SOURCE_LANG
|
|
||||||
|
|
||||||
@INPUT_SOURCE_LANG.setter
|
|
||||||
def INPUT_SOURCE_LANG(self, value):
|
|
||||||
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
|
|
||||||
self._INPUT_SOURCE_LANG = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_TARGET_LANG(self):
|
|
||||||
return self._INPUT_TARGET_LANG
|
|
||||||
|
|
||||||
@INPUT_TARGET_LANG.setter
|
|
||||||
def INPUT_TARGET_LANG(self, value):
|
|
||||||
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
|
|
||||||
self._INPUT_TARGET_LANG = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def OUTPUT_SOURCE_LANG(self):
|
|
||||||
return self._OUTPUT_SOURCE_LANG
|
|
||||||
|
|
||||||
@OUTPUT_SOURCE_LANG.setter
|
|
||||||
def OUTPUT_SOURCE_LANG(self, value):
|
|
||||||
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
|
|
||||||
self._OUTPUT_SOURCE_LANG = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def OUTPUT_TARGET_LANG(self):
|
|
||||||
return self._OUTPUT_TARGET_LANG
|
|
||||||
|
|
||||||
@OUTPUT_TARGET_LANG.setter
|
|
||||||
def OUTPUT_TARGET_LANG(self, value):
|
|
||||||
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
|
|
||||||
self._OUTPUT_TARGET_LANG = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def CHOICE_MIC_HOST(self):
|
|
||||||
return self._CHOICE_MIC_HOST
|
|
||||||
|
|
||||||
@CHOICE_MIC_HOST.setter
|
|
||||||
def CHOICE_MIC_HOST(self, value):
|
|
||||||
if value in [host for host in getInputDevices().keys()]:
|
|
||||||
self._CHOICE_MIC_HOST = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def CHOICE_MIC_DEVICE(self):
|
|
||||||
return self._CHOICE_MIC_DEVICE
|
|
||||||
|
|
||||||
@CHOICE_MIC_DEVICE.setter
|
|
||||||
def CHOICE_MIC_DEVICE(self, value):
|
|
||||||
if value in [device["name"] for device in getInputDevices()[self.CHOICE_MIC_HOST]]:
|
|
||||||
self._CHOICE_MIC_DEVICE = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_VOICE_LANGUAGE(self):
|
|
||||||
return self._INPUT_MIC_VOICE_LANGUAGE
|
|
||||||
|
|
||||||
@INPUT_MIC_VOICE_LANGUAGE.setter
|
|
||||||
def INPUT_MIC_VOICE_LANGUAGE(self, value):
|
|
||||||
if value in list(transcription_lang.keys()):
|
|
||||||
self._INPUT_MIC_VOICE_LANGUAGE = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_ENERGY_THRESHOLD(self):
|
|
||||||
return self._INPUT_MIC_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
@INPUT_MIC_ENERGY_THRESHOLD.setter
|
|
||||||
def INPUT_MIC_ENERGY_THRESHOLD(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_MIC_ENERGY_THRESHOLD = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD(self):
|
|
||||||
return self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
@INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD.setter
|
|
||||||
def INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_RECORD_TIMEOUT(self):
|
|
||||||
return self._INPUT_MIC_RECORD_TIMEOUT
|
|
||||||
|
|
||||||
@INPUT_MIC_RECORD_TIMEOUT.setter
|
|
||||||
def INPUT_MIC_RECORD_TIMEOUT(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_MIC_RECORD_TIMEOUT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_PHRASE_TIMEOUT(self):
|
|
||||||
return self._INPUT_MIC_PHRASE_TIMEOUT
|
|
||||||
|
|
||||||
@INPUT_MIC_PHRASE_TIMEOUT.setter
|
|
||||||
def INPUT_MIC_PHRASE_TIMEOUT(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_MIC_PHRASE_TIMEOUT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_MAX_PHRASES(self):
|
|
||||||
return self._INPUT_MIC_MAX_PHRASES
|
|
||||||
|
|
||||||
@INPUT_MIC_MAX_PHRASES.setter
|
|
||||||
def INPUT_MIC_MAX_PHRASES(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_MIC_MAX_PHRASES = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_MIC_WORD_FILTER(self):
|
|
||||||
return self._INPUT_MIC_WORD_FILTER
|
|
||||||
|
|
||||||
@INPUT_MIC_WORD_FILTER.setter
|
|
||||||
def INPUT_MIC_WORD_FILTER(self, value):
|
|
||||||
if type(value) is list:
|
|
||||||
self._INPUT_MIC_WORD_FILTER = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def CHOICE_SPEAKER_DEVICE(self):
|
|
||||||
return self._CHOICE_SPEAKER_DEVICE
|
|
||||||
|
|
||||||
@CHOICE_SPEAKER_DEVICE.setter
|
|
||||||
def CHOICE_SPEAKER_DEVICE(self, value):
|
|
||||||
if value in [device["name"] for device in getOutputDevices()]:
|
|
||||||
speaker_device = [device for device in getOutputDevices() if device["name"] == value][0]
|
|
||||||
if getDefaultOutputDevice()["index"] == speaker_device["index"]:
|
|
||||||
self._CHOICE_SPEAKER_DEVICE = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_VOICE_LANGUAGE(self):
|
|
||||||
return self._INPUT_SPEAKER_VOICE_LANGUAGE
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_VOICE_LANGUAGE.setter
|
|
||||||
def INPUT_SPEAKER_VOICE_LANGUAGE(self, value):
|
|
||||||
if value in list(transcription_lang.keys()):
|
|
||||||
self._INPUT_SPEAKER_VOICE_LANGUAGE = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_ENERGY_THRESHOLD(self):
|
|
||||||
return self._INPUT_SPEAKER_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_ENERGY_THRESHOLD.setter
|
|
||||||
def INPUT_SPEAKER_ENERGY_THRESHOLD(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_SPEAKER_ENERGY_THRESHOLD = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD(self):
|
|
||||||
return self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.setter
|
|
||||||
def INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_RECORD_TIMEOUT(self):
|
|
||||||
return self._INPUT_SPEAKER_RECORD_TIMEOUT
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_RECORD_TIMEOUT.setter
|
|
||||||
def INPUT_SPEAKER_RECORD_TIMEOUT(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_SPEAKER_RECORD_TIMEOUT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_PHRASE_TIMEOUT(self):
|
|
||||||
return self._INPUT_SPEAKER_PHRASE_TIMEOUT
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_PHRASE_TIMEOUT.setter
|
|
||||||
def INPUT_SPEAKER_PHRASE_TIMEOUT(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_SPEAKER_PHRASE_TIMEOUT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def INPUT_SPEAKER_MAX_PHRASES(self):
|
|
||||||
return self._INPUT_SPEAKER_MAX_PHRASES
|
|
||||||
|
|
||||||
@INPUT_SPEAKER_MAX_PHRASES.setter
|
|
||||||
def INPUT_SPEAKER_MAX_PHRASES(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._INPUT_SPEAKER_MAX_PHRASES = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def OSC_IP_ADDRESS(self):
|
|
||||||
return self._OSC_IP_ADDRESS
|
|
||||||
|
|
||||||
@OSC_IP_ADDRESS.setter
|
|
||||||
def OSC_IP_ADDRESS(self, value):
|
|
||||||
if type(value) is str:
|
|
||||||
self._OSC_IP_ADDRESS = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def OSC_PORT(self):
|
|
||||||
return self._OSC_PORT
|
|
||||||
|
|
||||||
@OSC_PORT.setter
|
|
||||||
def OSC_PORT(self, value):
|
|
||||||
if type(value) is int:
|
|
||||||
self._OSC_PORT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def AUTH_KEYS(self):
|
|
||||||
return self._AUTH_KEYS
|
|
||||||
|
|
||||||
@AUTH_KEYS.setter
|
|
||||||
def AUTH_KEYS(self, value):
|
|
||||||
if type(value) is dict and set(value.keys()) == set(self.AUTH_KEYS.keys()):
|
|
||||||
for key, value in value.items():
|
|
||||||
if type(value) is str:
|
|
||||||
self._AUTH_KEYS[key] = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.AUTH_KEYS)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def MESSAGE_FORMAT(self):
|
|
||||||
return self._MESSAGE_FORMAT
|
|
||||||
|
|
||||||
@MESSAGE_FORMAT.setter
|
|
||||||
def MESSAGE_FORMAT(self, value):
|
|
||||||
if type(value) is str:
|
|
||||||
self._MESSAGE_FORMAT = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_AUTO_CLEAR_CHATBOX(self):
|
|
||||||
return self._ENABLE_AUTO_CLEAR_CHATBOX
|
|
||||||
|
|
||||||
@ENABLE_AUTO_CLEAR_CHATBOX.setter
|
|
||||||
def ENABLE_AUTO_CLEAR_CHATBOX(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_AUTO_CLEAR_CHATBOX = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_NOTICE_XSOVERLAY(self):
|
|
||||||
return self._ENABLE_NOTICE_XSOVERLAY
|
|
||||||
|
|
||||||
@ENABLE_NOTICE_XSOVERLAY.setter
|
|
||||||
def ENABLE_NOTICE_XSOVERLAY(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_NOTICE_XSOVERLAY = value
|
|
||||||
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ENABLE_OSC(self):
|
|
||||||
return self._ENABLE_OSC
|
|
||||||
|
|
||||||
@ENABLE_OSC.setter
|
|
||||||
def ENABLE_OSC(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._ENABLE_OSC = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def UPDATE_FLAG(self):
|
|
||||||
return self._UPDATE_FLAG
|
|
||||||
|
|
||||||
@UPDATE_FLAG.setter
|
|
||||||
def UPDATE_FLAG(self, value):
|
|
||||||
if type(value) is bool:
|
|
||||||
self._UPDATE_FLAG = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def GITHUB_URL(self):
|
|
||||||
return self._GITHUB_URL
|
|
||||||
|
|
||||||
@property
|
|
||||||
def BREAK_KEYSYM_LIST(self):
|
|
||||||
return self._BREAK_KEYSYM_LIST
|
|
||||||
|
|
||||||
@property
|
|
||||||
def MAX_MIC_ENERGY_THRESHOLD(self):
|
|
||||||
return self._MAX_MIC_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
@property
|
|
||||||
def MAX_SPEAKER_ENERGY_THRESHOLD(self):
|
|
||||||
return self._MAX_SPEAKER_ENERGY_THRESHOLD
|
|
||||||
|
|
||||||
def init_config(self):
|
|
||||||
self._VERSION = "1.3.2"
|
|
||||||
self._PATH_CONFIG = os.path.join(os.path.dirname(__file__), 'config.json')
|
|
||||||
self._ENABLE_TRANSLATION = False
|
|
||||||
self._ENABLE_TRANSCRIPTION_SEND = False
|
|
||||||
self._ENABLE_TRANSCRIPTION_RECEIVE = False
|
|
||||||
self._ENABLE_FOREGROUND = False
|
|
||||||
self._TRANSPARENCY = 100
|
|
||||||
self._APPEARANCE_THEME = "System"
|
|
||||||
self._UI_SCALING = "100%"
|
|
||||||
self._FONT_FAMILY = "Yu Gothic UI"
|
|
||||||
self._UI_LANGUAGE = "en"
|
|
||||||
self._CHOICE_TRANSLATOR = translatorEngine[0]
|
|
||||||
self._INPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[0]
|
|
||||||
self._INPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[1]
|
|
||||||
self._OUTPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[1]
|
|
||||||
self._OUTPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[0]
|
|
||||||
self._CHOICE_MIC_HOST = getDefaultInputDevice()["host"]["name"]
|
|
||||||
self._CHOICE_MIC_DEVICE = getDefaultInputDevice()["device"]["name"]
|
|
||||||
self._INPUT_MIC_VOICE_LANGUAGE = list(transcription_lang.keys())[0]
|
|
||||||
self._INPUT_MIC_ENERGY_THRESHOLD = 300
|
|
||||||
self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True
|
|
||||||
self._INPUT_MIC_RECORD_TIMEOUT = 3
|
|
||||||
self._INPUT_MIC_PHRASE_TIMEOUT = 3
|
|
||||||
self._INPUT_MIC_MAX_PHRASES = 10
|
|
||||||
self._INPUT_MIC_WORD_FILTER = []
|
|
||||||
self._CHOICE_SPEAKER_DEVICE = getDefaultOutputDevice()["name"]
|
|
||||||
self._INPUT_SPEAKER_VOICE_LANGUAGE = list(transcription_lang.keys())[1]
|
|
||||||
self._INPUT_SPEAKER_ENERGY_THRESHOLD = 300
|
|
||||||
self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = True
|
|
||||||
self._INPUT_SPEAKER_RECORD_TIMEOUT = 3
|
|
||||||
self._INPUT_SPEAKER_PHRASE_TIMEOUT = 3
|
|
||||||
self._INPUT_SPEAKER_MAX_PHRASES = 10
|
|
||||||
self._OSC_IP_ADDRESS = "127.0.0.1"
|
|
||||||
self._OSC_PORT = 9000
|
|
||||||
self._AUTH_KEYS = {
|
|
||||||
"DeepL(web)": None,
|
|
||||||
"DeepL(auth)": None,
|
|
||||||
"Bing(web)": None,
|
|
||||||
"Google(web)": None,
|
|
||||||
}
|
|
||||||
self._MESSAGE_FORMAT = "[message]([translation])"
|
|
||||||
self._ENABLE_AUTO_CLEAR_CHATBOX = False
|
|
||||||
self._ENABLE_NOTICE_XSOVERLAY = False
|
|
||||||
self._ENABLE_OSC = False
|
|
||||||
self._UPDATE_FLAG = False
|
|
||||||
self._GITHUB_URL = "https://api.github.com/repos/misyaguziya/VRCT/releases/latest"
|
|
||||||
self._BREAK_KEYSYM_LIST = [
|
|
||||||
"Delete", "Select", "Up", "Down", "Next", "End", "Print",
|
|
||||||
"Prior","Insert","Home", "Left", "Clear", "Right", "Linefeed"
|
|
||||||
]
|
|
||||||
self._MAX_MIC_ENERGY_THRESHOLD = 2000
|
|
||||||
self._MAX_SPEAKER_ENERGY_THRESHOLD = 4000
|
|
||||||
|
|
||||||
def load_config(self):
|
|
||||||
if os_path.isfile(self.PATH_CONFIG) is not False:
|
|
||||||
with open(self.PATH_CONFIG, 'r') as fp:
|
|
||||||
config = json_load(fp)
|
|
||||||
|
|
||||||
for key in config.keys():
|
|
||||||
setattr(self, key, config[key])
|
|
||||||
|
|
||||||
with open(self.PATH_CONFIG, 'w') as fp:
|
|
||||||
setter_methods = [
|
|
||||||
name for name, obj in vars(type(self)).items()
|
|
||||||
if isinstance(obj, property) and obj.fset is not None
|
|
||||||
]
|
|
||||||
config = {}
|
|
||||||
for method in setter_methods:
|
|
||||||
config[method] = getattr(self, method)
|
|
||||||
json_dump(config, fp, indent=4)
|
|
||||||
|
|
||||||
config = Config()
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,6 +0,0 @@
|
|||||||
selectable_languages = {
|
|
||||||
"en": "English",
|
|
||||||
"ja": "日本語",
|
|
||||||
"ko": "한국어"
|
|
||||||
# 新しい言語とキーを追加する場合はここに追記してください
|
|
||||||
}
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
en:
|
|
||||||
# main window
|
|
||||||
checkbox_translation: "Translation"
|
|
||||||
checkbox_transcription_send: "Voice2chatbox"
|
|
||||||
checkbox_transcription_receive: "Speaker2log"
|
|
||||||
checkbox_foreground: "Foreground"
|
|
||||||
|
|
||||||
# main tabview
|
|
||||||
main_tab_title_log: "Log"
|
|
||||||
main_tab_title_send: "Send"
|
|
||||||
main_tab_title_receive: "Receive"
|
|
||||||
main_tab_title_system: "System"
|
|
||||||
|
|
||||||
|
|
||||||
# configure window
|
|
||||||
# config tabview
|
|
||||||
config_tab_title_ui: "UI"
|
|
||||||
config_tab_title_translation: "Translation"
|
|
||||||
config_tab_title_transcription: "Transcription"
|
|
||||||
config_tab_title_parameter: "Parameter"
|
|
||||||
config_tab_title_others: "Others"
|
|
||||||
# tab UI
|
|
||||||
label_transparency: "Transparency"
|
|
||||||
label_appearance_theme: "Appearance Theme"
|
|
||||||
label_ui_scaling: "UI Scaling"
|
|
||||||
label_font_family: "Font Family"
|
|
||||||
label_ui_language: "UI Language"
|
|
||||||
|
|
||||||
# tab Translation
|
|
||||||
label_translation_translator: "Select Translator"
|
|
||||||
label_translation_input_language: "Send Language"
|
|
||||||
label_translation_output_language: "Receive Language"
|
|
||||||
|
|
||||||
# tab Transcription
|
|
||||||
label_input_mic_host: "Input Mic Host"
|
|
||||||
label_input_mic_device: "Input Mic Device"
|
|
||||||
label_input_mic_voice_language: "Input Mic Voice Language"
|
|
||||||
label_input_mic_energy_threshold: "Input Mic Energy Threshold"
|
|
||||||
checkbox_input_mic_threshold_check: "Check threshold point"
|
|
||||||
label_input_mic_dynamic_energy_threshold: "Input Mic Dynamic Energy Threshold"
|
|
||||||
label_input_mic_record_timeout: "Input Mic Record Timeout"
|
|
||||||
label_input_mic_phrase_timeout: "Input Mic Phrase Timeout"
|
|
||||||
label_input_mic_max_phrases: "Input Mic Max Phrases"
|
|
||||||
label_input_mic_word_filter: "Input Mic Word Filter"
|
|
||||||
|
|
||||||
label_input_speaker_device: "Input Speaker Device"
|
|
||||||
label_input_speaker_voice_language: "Input Speaker Voice Language"
|
|
||||||
label_input_speaker_energy_threshold: "Input Speaker Energy Threshold"
|
|
||||||
checkbox_input_speaker_threshold_check: "Check threshold point"
|
|
||||||
label_input_speaker_dynamic_energy_threshold: "Input Speaker Dynamic Energy Threshold"
|
|
||||||
label_input_speaker_record_timeout: "Input Speaker Record Timeout"
|
|
||||||
label_input_speaker_phrase_timeout: "Input Speaker Phrase Timeout"
|
|
||||||
label_input_speaker_max_phrases: "Input Speaker Max Phrases"
|
|
||||||
|
|
||||||
# tab Parameter
|
|
||||||
label_ip_address: "OSC IP address"
|
|
||||||
label_port: "OSC Port"
|
|
||||||
label_authkey: "DeepL Auth Key"
|
|
||||||
label_message_format: "Message Format"
|
|
||||||
|
|
||||||
# tab Others
|
|
||||||
label_checkbox_auto_clear_chatbox: "Auto clear chat box"
|
|
||||||
label_checkbox_notice_xsoverlay: "Notification XSOverlay"
|
|
||||||
|
|
||||||
|
|
||||||
ja:
|
|
||||||
# main window
|
|
||||||
checkbox_translation: "翻訳"
|
|
||||||
checkbox_transcription_send: "マイク->チャットボックス"
|
|
||||||
checkbox_transcription_receive: "スピーカー->ログ"
|
|
||||||
checkbox_foreground: "最前面表示"
|
|
||||||
|
|
||||||
# main tabview
|
|
||||||
main_tab_title_log: "ログ"
|
|
||||||
main_tab_title_send: "送信"
|
|
||||||
main_tab_title_receive: "受信"
|
|
||||||
main_tab_title_system: "システム"
|
|
||||||
|
|
||||||
|
|
||||||
# configure window
|
|
||||||
# config tabview
|
|
||||||
config_tab_title_ui: "UI"
|
|
||||||
config_tab_title_translation: "翻訳方法"
|
|
||||||
config_tab_title_transcription: "音声認識"
|
|
||||||
config_tab_title_parameter: "パラメーター"
|
|
||||||
config_tab_title_others: "その他"
|
|
||||||
|
|
||||||
# tab UI
|
|
||||||
label_transparency: "透過度"
|
|
||||||
label_appearance_theme: "外観テーマを選択"
|
|
||||||
label_ui_scaling: "UIの拡大縮小"
|
|
||||||
label_font_family: "使用フォントの変更"
|
|
||||||
label_ui_language: "UI 言語"
|
|
||||||
|
|
||||||
# tab Translation
|
|
||||||
label_translation_translator: "翻訳エンジンの選択"
|
|
||||||
label_translation_input_language: "送信言語-->翻訳言語"
|
|
||||||
label_translation_output_language: "受信言語-->翻訳言語"
|
|
||||||
|
|
||||||
# tab Transcription
|
|
||||||
label_input_mic_host: "マイク入力ホスト"
|
|
||||||
label_input_mic_device: "マイク入力デバイス"
|
|
||||||
label_input_mic_voice_language: "マイクで話す言語"
|
|
||||||
label_input_mic_energy_threshold: "音声取得のしきい値"
|
|
||||||
checkbox_input_mic_threshold_check: "音声取得のしきい値の視覚化"
|
|
||||||
label_input_mic_dynamic_energy_threshold: "音声取得のしきい値の自動調整"
|
|
||||||
label_input_mic_record_timeout: "マイク音声の区切りの無音時間"
|
|
||||||
label_input_mic_phrase_timeout: "文字起こしする音声時間の上限"
|
|
||||||
label_input_mic_max_phrases: "保留する単語の上限(マイク)"
|
|
||||||
label_input_mic_word_filter: "ワードフィルタ"
|
|
||||||
|
|
||||||
label_input_speaker_device: "スピーカー(聞き取りたいデバイス)"
|
|
||||||
label_input_speaker_voice_language: "聞き取る音声の言語"
|
|
||||||
label_input_speaker_energy_threshold: "音声取得のしきい値"
|
|
||||||
checkbox_input_speaker_threshold_check: "音声取得のしきい値の視覚化"
|
|
||||||
label_input_speaker_dynamic_energy_threshold: "音声取得のしきい値の自動調整"
|
|
||||||
label_input_speaker_record_timeout: "スピーカー音声の区切りの無音時間"
|
|
||||||
label_input_speaker_phrase_timeout: "文字起こしする音声時間の上限"
|
|
||||||
label_input_speaker_max_phrases: "保留する単語の上限(スピーカー)"
|
|
||||||
|
|
||||||
# tab Parameter
|
|
||||||
# label_ip_address: ""
|
|
||||||
# label_port: ""
|
|
||||||
# label_authkey: ""
|
|
||||||
label_message_format: "送信するメッセージのフォーマット"
|
|
||||||
|
|
||||||
# tab Others
|
|
||||||
label_checkbox_auto_clear_chatbox: "送信後はチャットボックスを空にする"
|
|
||||||
label_checkbox_notice_xsoverlay: "XSOverlayの通知機能を有効"
|
|
||||||
|
|
||||||
|
|
||||||
ko:
|
|
||||||
# main window
|
|
||||||
checkbox_translation: "번역"
|
|
||||||
checkbox_transcription_send: "마이크 -> 챗박스"
|
|
||||||
checkbox_transcription_receive: "스피커 -> 로그"
|
|
||||||
checkbox_foreground: "항상 위로"
|
|
||||||
|
|
||||||
# main tabview
|
|
||||||
main_tab_title_log: "로그"
|
|
||||||
main_tab_title_send: "전송"
|
|
||||||
main_tab_title_receive: "수신"
|
|
||||||
main_tab_title_system: "시스템"
|
|
||||||
|
|
||||||
|
|
||||||
# configure window
|
|
||||||
# config tabview
|
|
||||||
config_tab_title_ui: "UI"
|
|
||||||
config_tab_title_translation: "번역"
|
|
||||||
config_tab_title_transcription: "음성인식"
|
|
||||||
config_tab_title_parameter: "파라미터"
|
|
||||||
config_tab_title_others: "기타"
|
|
||||||
# tab UI
|
|
||||||
label_transparency: "투명도"
|
|
||||||
label_appearance_theme: "테마"
|
|
||||||
label_ui_scaling: "UI 크기"
|
|
||||||
label_font_family: "폰트"
|
|
||||||
label_ui_language: "UI 언어"
|
|
||||||
|
|
||||||
# tab Translation
|
|
||||||
label_translation_translator: "번역기 선택"
|
|
||||||
label_translation_input_language: "전송시 번역 언어"
|
|
||||||
label_translation_output_language: "수신시 번역 언어"
|
|
||||||
|
|
||||||
# tab Transcription
|
|
||||||
label_input_mic_host: "마이크 호스트"
|
|
||||||
label_input_mic_device: "마이크 장치"
|
|
||||||
label_input_mic_voice_language: "입력 언어"
|
|
||||||
label_input_mic_energy_threshold: "음성 입력 최소 볼륨"
|
|
||||||
checkbox_input_mic_threshold_check: "임계점 확인"
|
|
||||||
label_input_mic_dynamic_energy_threshold: "동적 임계값"
|
|
||||||
label_input_mic_record_timeout: "최대 무음 시간"
|
|
||||||
label_input_mic_phrase_timeout: "최대 인식 시간"
|
|
||||||
label_input_mic_max_phrases: "최대 입력 절(phrases) 수"
|
|
||||||
label_input_mic_word_filter: "단어 필터"
|
|
||||||
|
|
||||||
label_input_speaker_device: "스피커 장치"
|
|
||||||
label_input_speaker_voice_language: "입력 언어"
|
|
||||||
label_input_speaker_energy_threshold: "음성 입력 최소 볼륨"
|
|
||||||
checkbox_input_speaker_threshold_check: "임계점 확인"
|
|
||||||
label_input_speaker_dynamic_energy_threshold: "동적 임계값"
|
|
||||||
label_input_speaker_record_timeout: "최대 무음 시간"
|
|
||||||
label_input_speaker_phrase_timeout: "최대 인식 시간"
|
|
||||||
label_input_speaker_max_phrases: "최대 입력 절(phrases) 수"
|
|
||||||
|
|
||||||
# tab Parameter
|
|
||||||
label_ip_address: "OSC IP 주소"
|
|
||||||
label_port: "OSC 포트"
|
|
||||||
label_authkey: "DeepL 인증키"
|
|
||||||
label_message_format: "전송 형식"
|
|
||||||
|
|
||||||
# tab Others
|
|
||||||
label_checkbox_auto_clear_chatbox: "챗박스 자동 삭제"
|
|
||||||
@@ -1,503 +0,0 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from time import sleep
|
|
||||||
from os import path as os_path
|
|
||||||
|
|
||||||
import customtkinter
|
|
||||||
from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry
|
|
||||||
from PIL.Image import open as Image_open
|
|
||||||
|
|
||||||
from threading import Thread
|
|
||||||
from utils import print_textbox, get_localized_text, widget_main_window_label_setter
|
|
||||||
from window_config import ToplevelWindowConfig
|
|
||||||
from window_information import ToplevelWindowInformation
|
|
||||||
from config import config
|
|
||||||
from model import model
|
|
||||||
|
|
||||||
class App(CTk):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
## set UI theme
|
|
||||||
customtkinter.set_appearance_mode(config.APPEARANCE_THEME)
|
|
||||||
customtkinter.set_default_color_theme("blue")
|
|
||||||
|
|
||||||
# init main window
|
|
||||||
self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico"))
|
|
||||||
self.title("VRCT")
|
|
||||||
self.geometry(f"{400}x{175}")
|
|
||||||
self.minsize(400, 175)
|
|
||||||
self.grid_columnconfigure(1, weight=1)
|
|
||||||
self.grid_rowconfigure(0, weight=1)
|
|
||||||
self.wm_attributes("-alpha", config.TRANSPARENCY/100)
|
|
||||||
customtkinter.set_widget_scaling(int(config.UI_SCALING.replace("%", "")) / 100)
|
|
||||||
self.protocol("WM_DELETE_WINDOW", self.delete_window)
|
|
||||||
|
|
||||||
# add sidebar
|
|
||||||
self.add_sidebar()
|
|
||||||
|
|
||||||
# add entry message box
|
|
||||||
self.entry_message_box = CTkEntry(
|
|
||||||
self,
|
|
||||||
placeholder_text="message",
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY),
|
|
||||||
)
|
|
||||||
self.entry_message_box.grid(row=1, column=1, columnspan=2, padx=5, pady=(5, 10), sticky="nsew")
|
|
||||||
self.entry_message_box.bind("<Return>", self.entry_message_box_press_key_enter)
|
|
||||||
self.entry_message_box.bind("<Any-KeyPress>", self.entry_message_box_press_key_any)
|
|
||||||
self.entry_message_box.bind("<Leave>", self.entry_message_box_leave)
|
|
||||||
|
|
||||||
# add tabview textbox
|
|
||||||
self.add_tabview_logs(get_localized_text(f"{config.UI_LANGUAGE}"))
|
|
||||||
|
|
||||||
self.config_window = ToplevelWindowConfig(self)
|
|
||||||
self.information_window = ToplevelWindowInformation(self)
|
|
||||||
self.init_process()
|
|
||||||
|
|
||||||
def init_process(self):
|
|
||||||
# set translator
|
|
||||||
if model.authenticationTranslator() is False:
|
|
||||||
# error update Auth key
|
|
||||||
self.printLogAuthenticationError()
|
|
||||||
|
|
||||||
# set word filter
|
|
||||||
model.addKeywords()
|
|
||||||
|
|
||||||
# check OSC started
|
|
||||||
model.checkOSCStarted()
|
|
||||||
|
|
||||||
# check Software Updated
|
|
||||||
model.checkSoftwareUpdated()
|
|
||||||
|
|
||||||
def button_config_callback(self):
|
|
||||||
self.foreground_stop()
|
|
||||||
self.transcription_stop()
|
|
||||||
self.checkbox_translation.configure(state="disabled")
|
|
||||||
self.checkbox_transcription_send.configure(state="disabled")
|
|
||||||
self.checkbox_transcription_receive.configure(state="disabled")
|
|
||||||
self.checkbox_foreground.configure(state="disabled")
|
|
||||||
self.tabview_logs.configure(state="disabled")
|
|
||||||
self.textbox_message_log.configure(state="disabled")
|
|
||||||
self.textbox_message_send_log.configure(state="disabled")
|
|
||||||
self.textbox_message_receive_log.configure(state="disabled")
|
|
||||||
self.textbox_message_system_log.configure(state="disabled")
|
|
||||||
self.entry_message_box.configure(state="disabled")
|
|
||||||
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
|
|
||||||
self.button_information.configure(state="disabled", fg_color=["gray92", "gray14"])
|
|
||||||
self.config_window.deiconify()
|
|
||||||
self.config_window.focus_set()
|
|
||||||
self.config_window.focus()
|
|
||||||
self.config_window.grab_set()
|
|
||||||
|
|
||||||
def button_information_callback(self):
|
|
||||||
self.information_window.deiconify()
|
|
||||||
self.information_window.focus_set()
|
|
||||||
self.information_window.focus()
|
|
||||||
|
|
||||||
def checkbox_translation_callback(self):
|
|
||||||
config.ENABLE_TRANSLATION = self.checkbox_translation.get()
|
|
||||||
if config.ENABLE_TRANSLATION is True:
|
|
||||||
self.printLogStartTranslation()
|
|
||||||
else:
|
|
||||||
self.printLogStopTranslation()
|
|
||||||
|
|
||||||
def transcription_send_start(self):
|
|
||||||
model.startMicTranscript(self.sendMicMessage)
|
|
||||||
self.printLogStartVoice2chatbox()
|
|
||||||
self.checkbox_transcription_send.configure(state="normal")
|
|
||||||
self.checkbox_transcription_receive.configure(state="normal")
|
|
||||||
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
|
|
||||||
|
|
||||||
def transcription_send_stop(self):
|
|
||||||
model.stopMicTranscript()
|
|
||||||
self.printLogStopVoice2chatbox()
|
|
||||||
self.checkbox_transcription_send.configure(state="normal")
|
|
||||||
self.checkbox_transcription_receive.configure(state="normal")
|
|
||||||
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
|
|
||||||
|
|
||||||
def transcription_send_stop_for_config(self):
|
|
||||||
model.stopMicTranscript()
|
|
||||||
self.printLogStopVoice2chatbox()
|
|
||||||
|
|
||||||
def checkbox_transcription_send_callback(self):
|
|
||||||
config.ENABLE_TRANSCRIPTION_SEND = self.checkbox_transcription_send.get()
|
|
||||||
self.checkbox_transcription_send.configure(state="disabled")
|
|
||||||
self.checkbox_transcription_receive.configure(state="disabled")
|
|
||||||
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
|
|
||||||
if config.ENABLE_TRANSCRIPTION_SEND is True:
|
|
||||||
th_transcription_send_start = Thread(target=self.transcription_send_start)
|
|
||||||
th_transcription_send_start.daemon = True
|
|
||||||
th_transcription_send_start.start()
|
|
||||||
else:
|
|
||||||
th_transcription_send_stop = Thread(target=self.transcription_send_stop)
|
|
||||||
th_transcription_send_stop.daemon = True
|
|
||||||
th_transcription_send_stop.start()
|
|
||||||
|
|
||||||
def transcription_receive_start(self):
|
|
||||||
model.startSpeakerTranscript(self.receiveSpeakerMessage)
|
|
||||||
self.printLogStartSpeaker2log()
|
|
||||||
self.checkbox_transcription_send.configure(state="normal")
|
|
||||||
self.checkbox_transcription_receive.configure(state="normal")
|
|
||||||
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
|
|
||||||
|
|
||||||
def transcription_receive_stop(self):
|
|
||||||
model.stopSpeakerTranscript()
|
|
||||||
self.printLogStopSpeaker2log()
|
|
||||||
self.checkbox_transcription_send.configure(state="normal")
|
|
||||||
self.checkbox_transcription_receive.configure(state="normal")
|
|
||||||
self.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
|
|
||||||
|
|
||||||
def transcription_receive_stop_for_config(self):
|
|
||||||
model.stopSpeakerTranscript()
|
|
||||||
self.printLogStopSpeaker2log()
|
|
||||||
|
|
||||||
def checkbox_transcription_receive_callback(self):
|
|
||||||
config.ENABLE_TRANSCRIPTION_RECEIVE = self.checkbox_transcription_receive.get()
|
|
||||||
self.checkbox_transcription_send.configure(state="disabled")
|
|
||||||
self.checkbox_transcription_receive.configure(state="disabled")
|
|
||||||
self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
|
|
||||||
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
|
|
||||||
th_transcription_receive_start = Thread(target=self.transcription_receive_start)
|
|
||||||
th_transcription_receive_start.daemon = True
|
|
||||||
th_transcription_receive_start.start()
|
|
||||||
else:
|
|
||||||
th_transcription_receive_stop = Thread(target=self.transcription_receive_stop)
|
|
||||||
th_transcription_receive_stop.daemon = True
|
|
||||||
th_transcription_receive_stop.start()
|
|
||||||
|
|
||||||
def transcription_start(self):
|
|
||||||
if config.ENABLE_TRANSCRIPTION_SEND is True:
|
|
||||||
th_transcription_send_start = Thread(target=self.transcription_send_start)
|
|
||||||
th_transcription_send_start.daemon = True
|
|
||||||
th_transcription_send_start.start()
|
|
||||||
sleep(2)
|
|
||||||
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
|
|
||||||
th_transcription_receive_start = Thread(target=self.transcription_receive_start)
|
|
||||||
th_transcription_receive_start.daemon = True
|
|
||||||
th_transcription_receive_start.start()
|
|
||||||
|
|
||||||
def transcription_stop(self):
|
|
||||||
if config.ENABLE_TRANSCRIPTION_SEND is True:
|
|
||||||
th_transcription_send_stop = Thread(target=self.transcription_send_stop_for_config)
|
|
||||||
th_transcription_send_stop.daemon = True
|
|
||||||
th_transcription_send_stop.start()
|
|
||||||
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
|
|
||||||
th_transcription_receive_stop = Thread(target=self.transcription_receive_stop_for_config)
|
|
||||||
th_transcription_receive_stop.daemon = True
|
|
||||||
th_transcription_receive_stop.start()
|
|
||||||
|
|
||||||
def checkbox_foreground_callback(self):
|
|
||||||
config.ENABLE_FOREGROUND = self.checkbox_foreground.get()
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", True)
|
|
||||||
self.printLogStartForeground()
|
|
||||||
else:
|
|
||||||
self.attributes("-topmost", False)
|
|
||||||
self.printLogStopForeground()
|
|
||||||
|
|
||||||
def foreground_start(self):
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", True)
|
|
||||||
self.printLogStartForeground()
|
|
||||||
|
|
||||||
def foreground_stop(self):
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", False)
|
|
||||||
self.printLogStopForeground()
|
|
||||||
|
|
||||||
def entry_message_box_press_key_enter(self, event):
|
|
||||||
# osc stop send typing
|
|
||||||
model.oscStopSendTyping()
|
|
||||||
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", True)
|
|
||||||
|
|
||||||
message = self.entry_message_box.get()
|
|
||||||
self.sendChatMessage(message)
|
|
||||||
|
|
||||||
def entry_message_box_press_key_any(self, event):
|
|
||||||
# osc start send typing
|
|
||||||
model.oscStartSendTyping()
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", False)
|
|
||||||
|
|
||||||
if event.keysym != "??":
|
|
||||||
if len(event.char) != 0 and event.keysym in config.BREAK_KEYSYM_LIST:
|
|
||||||
self.entry_message_box.insert("end", event.char)
|
|
||||||
return "break"
|
|
||||||
|
|
||||||
def entry_message_box_leave(self, event):
|
|
||||||
# osc stop send typing
|
|
||||||
model.oscStopSendTyping()
|
|
||||||
if config.ENABLE_FOREGROUND:
|
|
||||||
self.attributes("-topmost", True)
|
|
||||||
|
|
||||||
def delete_window(self):
|
|
||||||
self.quit()
|
|
||||||
self.destroy()
|
|
||||||
|
|
||||||
def add_sidebar(self):
|
|
||||||
init_lang_text = "Loading..."
|
|
||||||
self.sidebar_frame = CTkFrame(master=self, corner_radius=0)
|
|
||||||
|
|
||||||
# add checkbox translation
|
|
||||||
self.checkbox_translation = CTkCheckBox(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=init_lang_text,
|
|
||||||
onvalue=True,
|
|
||||||
offvalue=False,
|
|
||||||
command=self.checkbox_translation_callback,
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add checkbox transcription send
|
|
||||||
self.checkbox_transcription_send = CTkCheckBox(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=init_lang_text,
|
|
||||||
onvalue=True,
|
|
||||||
offvalue=False,
|
|
||||||
command=self.checkbox_transcription_send_callback,
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add checkbox transcription receive
|
|
||||||
self.checkbox_transcription_receive = CTkCheckBox(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=init_lang_text,
|
|
||||||
onvalue=True,
|
|
||||||
offvalue=False,
|
|
||||||
command=self.checkbox_transcription_receive_callback,
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add checkbox foreground
|
|
||||||
self.checkbox_foreground = CTkCheckBox(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=init_lang_text,
|
|
||||||
onvalue=True,
|
|
||||||
offvalue=False,
|
|
||||||
command=self.checkbox_foreground_callback,
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add button information
|
|
||||||
self.button_information = CTkButton(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=None,
|
|
||||||
width=36,
|
|
||||||
command=self.button_information_callback,
|
|
||||||
image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "info-icon-white.png")))
|
|
||||||
)
|
|
||||||
|
|
||||||
# add button config
|
|
||||||
self.button_config = CTkButton(
|
|
||||||
self.sidebar_frame,
|
|
||||||
text=None,
|
|
||||||
width=36,
|
|
||||||
command=self.button_config_callback,
|
|
||||||
image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "config-icon-white.png")))
|
|
||||||
)
|
|
||||||
|
|
||||||
self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsw")
|
|
||||||
self.sidebar_frame.grid_rowconfigure(5, weight=1)
|
|
||||||
self.checkbox_translation.grid(row=0, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
|
|
||||||
self.checkbox_transcription_send.grid(row=1, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
|
|
||||||
self.checkbox_transcription_receive.grid(row=2, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
|
|
||||||
self.checkbox_foreground.grid(row=3, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
|
|
||||||
self.button_information.grid(row=5, column=0, padx=(10, 5), pady=(5, 5), sticky="wse")
|
|
||||||
self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse")
|
|
||||||
|
|
||||||
def delete_tabview_logs(self, pre_language_yaml_data):
|
|
||||||
self.tabview_logs.delete(pre_language_yaml_data["main_tab_title_log"])
|
|
||||||
self.tabview_logs.delete(pre_language_yaml_data["main_tab_title_send"])
|
|
||||||
self.tabview_logs.delete(pre_language_yaml_data["main_tab_title_receive"])
|
|
||||||
self.tabview_logs.delete(pre_language_yaml_data["main_tab_title_system"])
|
|
||||||
|
|
||||||
def add_tabview_logs(self, language_yaml_data):
|
|
||||||
main_tab_title_log = language_yaml_data["main_tab_title_log"]
|
|
||||||
main_tab_title_send = language_yaml_data["main_tab_title_send"]
|
|
||||||
main_tab_title_receive = language_yaml_data["main_tab_title_receive"]
|
|
||||||
main_tab_title_system = language_yaml_data["main_tab_title_system"]
|
|
||||||
|
|
||||||
# add tabview textbox
|
|
||||||
self.tabview_logs = CTkTabview(master=self)
|
|
||||||
self.tabview_logs.add(main_tab_title_log)
|
|
||||||
self.tabview_logs.add(main_tab_title_send)
|
|
||||||
self.tabview_logs.add(main_tab_title_receive)
|
|
||||||
self.tabview_logs.add(main_tab_title_system)
|
|
||||||
self.tabview_logs.grid(row=0, column=1, padx=0, pady=0, sticky="nsew")
|
|
||||||
self.tabview_logs._segmented_button.configure(font=CTkFont(family=config.FONT_FAMILY))
|
|
||||||
self.tabview_logs._segmented_button.grid(sticky="W")
|
|
||||||
self.tabview_logs.tab(main_tab_title_log).grid_rowconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_log).grid_columnconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_send).grid_rowconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_send).grid_columnconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_receive).grid_rowconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_receive).grid_columnconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_system).grid_rowconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.tab(main_tab_title_system).grid_columnconfigure(0, weight=1)
|
|
||||||
self.tabview_logs.configure(fg_color="transparent")
|
|
||||||
|
|
||||||
# add textbox message log
|
|
||||||
self.textbox_message_log = CTkTextbox(
|
|
||||||
self.tabview_logs.tab(main_tab_title_log),
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add textbox message send log
|
|
||||||
self.textbox_message_send_log = CTkTextbox(
|
|
||||||
self.tabview_logs.tab(main_tab_title_send),
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add textbox message receive log
|
|
||||||
self.textbox_message_receive_log = CTkTextbox(
|
|
||||||
self.tabview_logs.tab(main_tab_title_receive),
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
# add textbox message system log
|
|
||||||
self.textbox_message_system_log = CTkTextbox(
|
|
||||||
self.tabview_logs.tab(main_tab_title_system),
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.textbox_message_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
|
|
||||||
self.textbox_message_send_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
|
|
||||||
self.textbox_message_receive_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
|
|
||||||
self.textbox_message_system_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
|
|
||||||
self.textbox_message_log.configure(state='disabled')
|
|
||||||
self.textbox_message_send_log.configure(state='disabled')
|
|
||||||
self.textbox_message_receive_log.configure(state='disabled')
|
|
||||||
self.textbox_message_system_log.configure(state='disabled')
|
|
||||||
|
|
||||||
widget_main_window_label_setter(self, language_yaml_data)
|
|
||||||
|
|
||||||
def printLogAuthenticationError(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
|
|
||||||
|
|
||||||
def printLogStartTranslation(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Start translation", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Start translation", "INFO")
|
|
||||||
|
|
||||||
def printLogStopTranslation(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Stop translation", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Stop translation", "INFO")
|
|
||||||
|
|
||||||
def printLogStartVoice2chatbox(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Start voice2chatbox", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Start voice2chatbox", "INFO")
|
|
||||||
|
|
||||||
def printLogStopVoice2chatbox(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Stop voice2chatbox", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Stop voice2chatbox", "INFO")
|
|
||||||
|
|
||||||
def printLogStartSpeaker2log(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Start speaker2log", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Start speaker2log", "INFO")
|
|
||||||
|
|
||||||
def printLogStopSpeaker2log(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Stop speaker2log", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Stop speaker2log", "INFO")
|
|
||||||
|
|
||||||
def printLogStartForeground(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Start foreground", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Start foreground", "INFO")
|
|
||||||
|
|
||||||
def printLogStopForeground(self):
|
|
||||||
print_textbox(self.textbox_message_log, "Stop foreground", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
|
|
||||||
|
|
||||||
def printLogDetectWordFilter(self, message):
|
|
||||||
print_textbox(self.textbox_message_log, f"Detect WordFilter :{message}", "INFO")
|
|
||||||
print_textbox(self.textbox_message_system_log, f"Detect WordFilter :{message}", "INFO")
|
|
||||||
|
|
||||||
def printLogOSCError(self):
|
|
||||||
print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
|
|
||||||
print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
|
|
||||||
|
|
||||||
def printLogSendMessage(self, message):
|
|
||||||
print_textbox(self.textbox_message_log, f"{message}", "SEND")
|
|
||||||
print_textbox(self.textbox_message_send_log, f"{message}", "SEND")
|
|
||||||
|
|
||||||
def printLogReceiveMessage(self, message):
|
|
||||||
print_textbox(self.textbox_message_log, f"{message}", "RECEIVE")
|
|
||||||
print_textbox(self.textbox_message_receive_log, f"{message}", "RECEIVE")
|
|
||||||
|
|
||||||
def sendChatMessage(self, message):
|
|
||||||
if len(message) > 0:
|
|
||||||
# translate
|
|
||||||
if config.ENABLE_TRANSLATION is False:
|
|
||||||
chat_message = f"{message}"
|
|
||||||
elif model.getTranslatorStatus() is False:
|
|
||||||
self.printLogAuthenticationError()
|
|
||||||
chat_message = f"{message}"
|
|
||||||
else:
|
|
||||||
chat_message = model.getInputTranslate(message)
|
|
||||||
|
|
||||||
# send OSC message
|
|
||||||
if config.ENABLE_OSC is True:
|
|
||||||
model.oscSendMessage(chat_message)
|
|
||||||
else:
|
|
||||||
self.printLogOSCError()
|
|
||||||
|
|
||||||
# update textbox message log
|
|
||||||
self.printLogSendMessage(chat_message)
|
|
||||||
|
|
||||||
# delete message in entry message box
|
|
||||||
if config.ENABLE_AUTO_CLEAR_CHATBOX is True:
|
|
||||||
self.entry_message_box.delete(0, customtkinter.END)
|
|
||||||
|
|
||||||
def sendMicMessage(self, message):
|
|
||||||
if len(message) > 0:
|
|
||||||
# word filter
|
|
||||||
if model.checkKeywords(message):
|
|
||||||
self.printLogDetectWordFilter(message)
|
|
||||||
return
|
|
||||||
|
|
||||||
# translate
|
|
||||||
if config.ENABLE_TRANSLATION is False:
|
|
||||||
voice_message = f"{message}"
|
|
||||||
elif model.getTranslatorStatus() is False:
|
|
||||||
self.printLogAuthenticationError()
|
|
||||||
voice_message = f"{message}"
|
|
||||||
else:
|
|
||||||
voice_message = model.getInputTranslate(message)
|
|
||||||
|
|
||||||
if config.ENABLE_TRANSCRIPTION_SEND is True:
|
|
||||||
if config.ENABLE_OSC is True:
|
|
||||||
# osc send message
|
|
||||||
model.oscSendMessage(voice_message)
|
|
||||||
else:
|
|
||||||
self.printLogOSCError()
|
|
||||||
# update textbox message log
|
|
||||||
self.printLogSendMessage(voice_message)
|
|
||||||
|
|
||||||
def receiveSpeakerMessage(self, message):
|
|
||||||
if len(message) > 0:
|
|
||||||
# translate
|
|
||||||
if config.ENABLE_TRANSLATION is False:
|
|
||||||
voice_message = f"{message}"
|
|
||||||
elif model.getTranslatorStatus() is False:
|
|
||||||
self.printLogAuthenticationError()
|
|
||||||
voice_message = f"{message}"
|
|
||||||
else:
|
|
||||||
voice_message = model.getOutputTranslate(message)
|
|
||||||
|
|
||||||
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
|
|
||||||
# update textbox message receive log
|
|
||||||
self.printLogReceiveMessage(voice_message)
|
|
||||||
if config.ENABLE_NOTICE_XSOVERLAY is True:
|
|
||||||
model.notificationXsoverlay(voice_message)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
app = App()
|
|
||||||
app.mainloop()
|
|
||||||
except Exception as e:
|
|
||||||
import traceback
|
|
||||||
with open(os.path.join(os.path.dirname(__file__), 'error.log'), 'a') as f:
|
|
||||||
traceback.print_exc(file=f)
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
from os import path as os_path
|
|
||||||
import yaml
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
def print_textbox(textbox, message, tags=None):
|
|
||||||
now = datetime.now()
|
|
||||||
now = now.strftime('%H:%M:%S')
|
|
||||||
|
|
||||||
textbox.tag_config("ERROR", foreground="#FF0000")
|
|
||||||
textbox.tag_config("INFO", foreground="#1BFF00")
|
|
||||||
textbox.tag_config("SEND", foreground="#0378e2")
|
|
||||||
textbox.tag_config("RECEIVE", foreground="#ffa500")
|
|
||||||
|
|
||||||
textbox.configure(state='normal')
|
|
||||||
textbox.insert("end", f"[{now}][")
|
|
||||||
textbox.insert("end", f"{tags}", tags)
|
|
||||||
textbox.insert("end", f"]{message}\n")
|
|
||||||
textbox.configure(state='disabled')
|
|
||||||
textbox.see("end")
|
|
||||||
|
|
||||||
def get_localized_text(language):
|
|
||||||
file_path = os_path.join(os_path.dirname(__file__), "locales.yml")
|
|
||||||
|
|
||||||
with open(file_path, encoding="utf-8") as file:
|
|
||||||
languages_yaml_data = yaml.safe_load(file)
|
|
||||||
default_language = "en"
|
|
||||||
if language in languages_yaml_data:
|
|
||||||
localized_text = languages_yaml_data[language]
|
|
||||||
if default_language in languages_yaml_data:
|
|
||||||
default_text = languages_yaml_data[default_language]
|
|
||||||
merged_text = {**default_text, **localized_text}
|
|
||||||
return merged_text
|
|
||||||
else:
|
|
||||||
return localized_text
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_key_by_value(dictionary, value):
|
|
||||||
for key, val in dictionary.items():
|
|
||||||
if val == value:
|
|
||||||
return key
|
|
||||||
return None
|
|
||||||
|
|
||||||
def widget_config_window_label_setter(self, language_yaml_data):
|
|
||||||
widget_names = [
|
|
||||||
# tab UI
|
|
||||||
"label_transparency",
|
|
||||||
"label_appearance_theme",
|
|
||||||
"label_ui_scaling",
|
|
||||||
"label_font_family",
|
|
||||||
"label_ui_language",
|
|
||||||
|
|
||||||
# tab Translation
|
|
||||||
"label_translation_translator",
|
|
||||||
"label_translation_input_language",
|
|
||||||
"label_translation_output_language",
|
|
||||||
|
|
||||||
# tab Transcription
|
|
||||||
"label_input_mic_host",
|
|
||||||
"label_input_mic_device",
|
|
||||||
"label_input_mic_voice_language",
|
|
||||||
"label_input_mic_energy_threshold",
|
|
||||||
"checkbox_input_mic_threshold_check",
|
|
||||||
"label_input_mic_dynamic_energy_threshold",
|
|
||||||
"label_input_mic_record_timeout",
|
|
||||||
"label_input_mic_phrase_timeout",
|
|
||||||
"label_input_mic_max_phrases",
|
|
||||||
"label_input_mic_word_filter",
|
|
||||||
|
|
||||||
"label_input_speaker_device",
|
|
||||||
"label_input_speaker_voice_language",
|
|
||||||
"label_input_speaker_energy_threshold",
|
|
||||||
"checkbox_input_speaker_threshold_check",
|
|
||||||
"label_input_speaker_dynamic_energy_threshold",
|
|
||||||
"label_input_speaker_record_timeout",
|
|
||||||
"label_input_speaker_phrase_timeout",
|
|
||||||
"label_input_speaker_max_phrases",
|
|
||||||
|
|
||||||
# tab Parameter
|
|
||||||
"label_ip_address",
|
|
||||||
"label_port",
|
|
||||||
"label_authkey",
|
|
||||||
"label_message_format",
|
|
||||||
|
|
||||||
# tab Others
|
|
||||||
"label_checkbox_auto_clear_chatbox",
|
|
||||||
"label_checkbox_notice_xsoverlay",
|
|
||||||
]
|
|
||||||
for name in widget_names:
|
|
||||||
widget = getattr(self, name)
|
|
||||||
text_value = language_yaml_data.get(name)
|
|
||||||
if widget is not None and text_value is not None:
|
|
||||||
widget.configure(text=text_value + ":")
|
|
||||||
|
|
||||||
def widget_main_window_label_setter(self, language_yaml_data):
|
|
||||||
widget_names = [
|
|
||||||
"checkbox_translation",
|
|
||||||
"checkbox_transcription_send",
|
|
||||||
"checkbox_transcription_receive",
|
|
||||||
"checkbox_foreground",
|
|
||||||
]
|
|
||||||
for name in widget_names:
|
|
||||||
widget = getattr(self, name)
|
|
||||||
text_value = language_yaml_data.get(name)
|
|
||||||
if widget is not None and text_value is not None:
|
|
||||||
widget.configure(text=text_value)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
|||||||
import os
|
|
||||||
from customtkinter import CTkToplevel, CTkTextbox, CTkFont
|
|
||||||
from config import config
|
|
||||||
|
|
||||||
class ToplevelWindowInformation(CTkToplevel):
|
|
||||||
def __init__(self, parent, *args, **kwargs):
|
|
||||||
super().__init__(parent, *args, **kwargs)
|
|
||||||
self.withdraw()
|
|
||||||
self.parent = parent
|
|
||||||
self.grid_columnconfigure(0, weight=1)
|
|
||||||
self.grid_rowconfigure(0, weight=1)
|
|
||||||
# self.geometry(f"{500}x{300}")
|
|
||||||
self.minsize(500, 300)
|
|
||||||
|
|
||||||
self.after(200, lambda: self.iconbitmap(os.path.join(os.path.dirname(__file__), "img", "app.ico")))
|
|
||||||
self.title("Information")
|
|
||||||
# create textbox information
|
|
||||||
self.textbox_information = CTkTextbox(
|
|
||||||
self,
|
|
||||||
font=CTkFont(family=config.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew")
|
|
||||||
textbox_information_message = """VRCT(v1.3.2)
|
|
||||||
|
|
||||||
# 概要
|
|
||||||
VRChatで使用されるChatBoxをOSC経由でメッセージを送信するツールになります。
|
|
||||||
翻訳エンジンを使用してメッセージとその翻訳部分を同時に送信することができます。
|
|
||||||
(翻訳エンジンはDeepL,Google,Bingに対応)
|
|
||||||
|
|
||||||
# 使用方法
|
|
||||||
初期設定時
|
|
||||||
0. VRChatのOSCを有効にする(重要)
|
|
||||||
|
|
||||||
(任意)
|
|
||||||
1. DeepLのAPIを使用するためにアカウント登録し、認証キーを取得する
|
|
||||||
2. ギアアイコンのボタンでconfigウィンドウを開く
|
|
||||||
3. ParameterタブのDeepL Auth Keyに認証キーを記載
|
|
||||||
4. configウィンドウを閉じる
|
|
||||||
|
|
||||||
通常使用時
|
|
||||||
1. メッセージボックスにメッセージを記入
|
|
||||||
2. Enterキーを押し、メッセージを送信する
|
|
||||||
|
|
||||||
# その他の設定
|
|
||||||
translation チェックボックス: 翻訳の有効無効
|
|
||||||
voice2chatbox チェックボックス : マイクの音声を文字起こししてチャットボックスに送信する
|
|
||||||
speaker2log チェックボックス : スピーカーの音声から文字起こししてログに表示する
|
|
||||||
foreground チェックボックス: 最前面表示の有効無効
|
|
||||||
|
|
||||||
テキストボックス
|
|
||||||
logタブ
|
|
||||||
すべてのログを表示
|
|
||||||
sendタブ
|
|
||||||
送信したメッセージを表示
|
|
||||||
receiveタブ
|
|
||||||
受信したメッセージを表示
|
|
||||||
systemタブ
|
|
||||||
機能についてのメッセージを表示
|
|
||||||
|
|
||||||
configウィンドウ
|
|
||||||
UIタブ
|
|
||||||
Transparency: ウィンドウの透過度の調整
|
|
||||||
Appearance Theme: ウィンドウテーマを選択
|
|
||||||
UI Scaling: UIサイズを調整
|
|
||||||
Font Family: 表示フォントを選択
|
|
||||||
UI Language: UIの表示言語を選択
|
|
||||||
Translationタブ
|
|
||||||
Select Translator: 翻訳エンジンの変更
|
|
||||||
Send Language: 送信するメッセージに対して翻訳する言語[source, target]を選択
|
|
||||||
Receive Language: 受信したメッセージに対して翻訳する言語[source, target]を選択
|
|
||||||
Transcriptionタブ
|
|
||||||
Input Mic Host: マイクのホストAPIを選択
|
|
||||||
Input Mic Device: マイクを選択
|
|
||||||
Input Mic Voice Language: 入力する音声の言語
|
|
||||||
Input Mic Energy Threshold: 音声取得のしきい値
|
|
||||||
Check threshold point: Input Mic Energy Thresholdのしきい値を視覚化
|
|
||||||
Input Mic Dynamic Energy Threshold: 音声取得のしきい値の自動調整
|
|
||||||
Input Mic Record Timeout: 音声の区切りの無音時間
|
|
||||||
Input Mic Phase Timeout: 文字起こしする音声時間の上限
|
|
||||||
Input Mic Max Phrases: 保留する単語の上限
|
|
||||||
Input Mic Word Filter: MICの文字起こし時にWord Filterで設定した文字が入っていた場合にChatboxに表示しない (ex AAA,BBB,CCC)
|
|
||||||
Input Speaker Device: スピーカーを選択
|
|
||||||
Input Speaker Voice Language: 受信する音声の言語
|
|
||||||
Input Speaker Energy Threshold: 音声取得のしきい値
|
|
||||||
Check threshold point: Input Speaker Energy Thresholdのしきい値を視覚化
|
|
||||||
Input Speaker Dynamic Energy Threshold: 音声取得のしきい値の自動調整
|
|
||||||
Input Speaker Record Timeout: 音声の区切りの無音時間
|
|
||||||
Input Speaker Phase Timeout: 文字起こしする音声時間の上限
|
|
||||||
Input Speaker Max Phrases: 保留する単語の上限
|
|
||||||
Parameterタブ
|
|
||||||
OSC IP address: 変更不要
|
|
||||||
OSC port: 変更不要
|
|
||||||
DeepL Auth key: DeepLの認証キーの設定
|
|
||||||
Message Format: 送信するメッセージのデコレーションの設定
|
|
||||||
[message]がメッセージボックスに記入したメッセージに置換される
|
|
||||||
[translation]が翻訳されたメッセージに置換される
|
|
||||||
初期フォーマット:"[message]([translation])"
|
|
||||||
Othersタブ
|
|
||||||
Auto clear chat box: メッセージ送信後に書き込んだメッセージを空にする
|
|
||||||
(New!) Notification XSOverlay: XSOverlayの通知機能を有効(VR only)
|
|
||||||
|
|
||||||
設定の初期化
|
|
||||||
config.jsonを削除
|
|
||||||
|
|
||||||
# お問い合わせ
|
|
||||||
要望などはTwitterまで
|
|
||||||
https://twitter.com/misya_ai
|
|
||||||
|
|
||||||
# アップデート履歴
|
|
||||||
[2023-05-29: v0.1b] v0.1b リリース
|
|
||||||
[2023-05-30: v0.2b]
|
|
||||||
- configボタンをギアアイコンに変更
|
|
||||||
- 詳細情報のボタンを追加
|
|
||||||
- 翻訳機能有効無効のチェックボックスを追加
|
|
||||||
- 最前面表示の有効無効のチェックボックスを追加
|
|
||||||
- いくつかのバグを修正
|
|
||||||
[2023-06-03: v0.3b]
|
|
||||||
- 全体的にUIを刷新
|
|
||||||
- 透過機能を追加
|
|
||||||
- テーマのLight/Dark/Systemのモードの変更機能を追加
|
|
||||||
- UIのスケール変更機能を追加
|
|
||||||
- フォントの変更機能を追加
|
|
||||||
[2023-06-06: v0.4b]
|
|
||||||
- 翻訳エンジンを追加
|
|
||||||
- 入力と出力の翻訳言語を選択できるように変更
|
|
||||||
[2023-06-20: v1.0]
|
|
||||||
- マイクからの音声の文字起こし機能を追加
|
|
||||||
- スピーカーからの音声の文字起こし機能を追加
|
|
||||||
[2023-06-28: v1.1]
|
|
||||||
- いくつかのバクを修正
|
|
||||||
- 翻訳/文字起こし言語の表記を略称からわかりやすい文字に変更
|
|
||||||
- 文字起こしの処理の軽量化
|
|
||||||
[2023-07-05: v1.2]
|
|
||||||
- 文字起こし精度の向上
|
|
||||||
[2023-07-21: v1.3]
|
|
||||||
- UIの表示言語を日本語/英語を選択できる機能を追加
|
|
||||||
- Energy Thresholdの視覚化機能を追加
|
|
||||||
- 文字起こしの誤認識対策のため、Word Filterを追加
|
|
||||||
- WASAPI以外のHostAPIでもマイクとして使用できるようにHostAPIを選択できる機能を追加
|
|
||||||
- メッセージ送信後に書き込んだメッセージを空にするか選択できる機能を追加
|
|
||||||
- バグ対策のため、translation/voice2chatbox/speaker2log/foregroundは起動時はOFFになるように変更
|
|
||||||
- バグ対策のため、スピーカーについて既定デバイス以外を選択した時にERRORが出るように変更
|
|
||||||
- 半角入力時に一部の文字が書き込めないバグを修正
|
|
||||||
[2023-07-22: v1.3.1]
|
|
||||||
- UIの表示言語選択に韓国語を追加
|
|
||||||
[2023-07-30: v1.3.2]
|
|
||||||
- 試験的にXSOverlayへの通知機能を追加
|
|
||||||
- checkbox ONの状態でもConfigを開けるように変更
|
|
||||||
- 文字起こし言語の表示を修正
|
|
||||||
- いくつかのバグを修正
|
|
||||||
|
|
||||||
# 注意事項
|
|
||||||
再配布とかはやめてね
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.textbox_information.insert("end", textbox_information_message)
|
|
||||||
self.textbox_information.configure(state='disabled')
|
|
||||||
self.protocol("WM_DELETE_WINDOW", self.delete_window)
|
|
||||||
|
|
||||||
def delete_window(self):
|
|
||||||
self.withdraw()
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
import os
|
|
||||||
from customtkinter import CTkToplevel, CTkTextbox, CTkFont
|
|
||||||
|
|
||||||
class ToplevelWindowInformation(CTkToplevel):
|
|
||||||
def __init__(self, parent, *args, **kwargs):
|
|
||||||
super().__init__(parent, *args, **kwargs)
|
|
||||||
self.withdraw()
|
|
||||||
self.parent = parent
|
|
||||||
self.grid_columnconfigure(0, weight=1)
|
|
||||||
self.grid_rowconfigure(0, weight=1)
|
|
||||||
# self.geometry(f"{500}x{300}")
|
|
||||||
self.minsize(500, 300)
|
|
||||||
|
|
||||||
self.after(200, lambda: self.iconbitmap(os.path.join(os.path.dirname(__file__), "img", "app.ico")))
|
|
||||||
self.title("Information")
|
|
||||||
# create textbox information
|
|
||||||
self.textbox_information = CTkTextbox(
|
|
||||||
self,
|
|
||||||
font=CTkFont(family=self.parent.FONT_FAMILY)
|
|
||||||
)
|
|
||||||
self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew")
|
|
||||||
textbox_information_message = """VRCT(v1.3.1)
|
|
||||||
|
|
||||||
# 概要
|
|
||||||
VRChatで使用されるChatBoxをOSC経由でメッセージを送信するツールになります。
|
|
||||||
翻訳エンジンを使用してメッセージとその翻訳部分を同時に送信することができます。
|
|
||||||
(翻訳エンジンはDeepL,Google,Bingに対応)
|
|
||||||
|
|
||||||
# 使用方法
|
|
||||||
初期設定時
|
|
||||||
0. VRChatのOSCを有効にする(重要)
|
|
||||||
|
|
||||||
(任意)
|
|
||||||
1. DeepLのAPIを使用するためにアカウント登録し、認証キーを取得する
|
|
||||||
2. ギアアイコンのボタンでconfigウィンドウを開く
|
|
||||||
3. ParameterタブのDeepL Auth Keyに認証キーを記載
|
|
||||||
4. configウィンドウを閉じる
|
|
||||||
|
|
||||||
通常使用時
|
|
||||||
1. メッセージボックスにメッセージを記入
|
|
||||||
2. Enterキーを押し、メッセージを送信する
|
|
||||||
|
|
||||||
# その他の設定
|
|
||||||
translation チェックボックス: 翻訳の有効無効
|
|
||||||
voice2chatbox チェックボックス : マイクの音声を文字起こししてチャットボックスに送信する
|
|
||||||
speaker2log チェックボックス : スピーカーの音声から文字起こししてログに表示する
|
|
||||||
foreground チェックボックス: 最前面表示の有効無効
|
|
||||||
|
|
||||||
テキストボックス
|
|
||||||
logタブ
|
|
||||||
すべてのログを表示
|
|
||||||
sendタブ
|
|
||||||
送信したメッセージを表示
|
|
||||||
receiveタブ
|
|
||||||
受信したメッセージを表示
|
|
||||||
systemタブ
|
|
||||||
機能についてのメッセージを表示
|
|
||||||
|
|
||||||
configウィンドウ
|
|
||||||
UIタブ
|
|
||||||
Transparency: ウィンドウの透過度の調整
|
|
||||||
Appearance Theme: ウィンドウテーマを選択
|
|
||||||
UI Scaling: UIサイズを調整
|
|
||||||
Font Family: 表示フォントを選択
|
|
||||||
(New!) UI Language: UIの表示言語を選択
|
|
||||||
Translationタブ
|
|
||||||
Select Translator: 翻訳エンジンの変更
|
|
||||||
Send Language: 送信するメッセージに対して翻訳する言語[source, target]を選択
|
|
||||||
Receive Language: 受信したメッセージに対して翻訳する言語[source, target]を選択
|
|
||||||
Transcriptionタブ
|
|
||||||
(New!) Input Mic Host: マイクのホストAPIを選択
|
|
||||||
Input Mic Device: マイクを選択
|
|
||||||
Input Mic Voice Language: 入力する音声の言語
|
|
||||||
Input Mic Energy Threshold: 音声取得のしきい値
|
|
||||||
(New!) Check threshold point: Input Mic Energy Thresholdのしきい値を視覚化
|
|
||||||
Input Mic Dynamic Energy Threshold: 音声取得のしきい値の自動調整
|
|
||||||
Input Mic Record Timeout: 音声の区切りの無音時間
|
|
||||||
Input Mic Phase Timeout: 文字起こしする音声時間の上限
|
|
||||||
Input Mic Max Phrases: 保留する単語の上限
|
|
||||||
(New!) Input Mic Word Filter: MICの文字起こし時にWord Filterで設定した文字が入っていた場合にChatboxに表示しない (ex AAA,BBB,CCC)
|
|
||||||
Input Speaker Device: スピーカーを選択
|
|
||||||
Input Speaker Voice Language: 受信する音声の言語
|
|
||||||
Input Speaker Energy Threshold: 音声取得のしきい値
|
|
||||||
(New!) Check threshold point: (New!)Input Speaker Energy Thresholdのしきい値を視覚化
|
|
||||||
Input Speaker Dynamic Energy Threshold: 音声取得のしきい値の自動調整
|
|
||||||
Input Speaker Record Timeout: 音声の区切りの無音時間
|
|
||||||
Input Speaker Phase Timeout: 文字起こしする音声時間の上限
|
|
||||||
Input Speaker Max Phrases: 保留する単語の上限
|
|
||||||
Parameterタブ
|
|
||||||
OSC IP address: 変更不要
|
|
||||||
OSC port: 変更不要
|
|
||||||
DeepL Auth key: DeepLの認証キーの設定
|
|
||||||
Message Format: 送信するメッセージのデコレーションの設定
|
|
||||||
[message]がメッセージボックスに記入したメッセージに置換される
|
|
||||||
[translation]が翻訳されたメッセージに置換される
|
|
||||||
初期フォーマット:"[message]([translation])"
|
|
||||||
Othersタブ
|
|
||||||
(New!) Auto clear chat box: メッセージ送信後に書き込んだメッセージを空にする
|
|
||||||
|
|
||||||
設定の初期化
|
|
||||||
config.jsonを削除
|
|
||||||
|
|
||||||
# お問い合わせ
|
|
||||||
要望などはTwitterまで
|
|
||||||
https://twitter.com/misya_ai
|
|
||||||
|
|
||||||
# アップデート履歴
|
|
||||||
[2023-05-29: v0.1b] v0.1b リリース
|
|
||||||
[2023-05-30: v0.2b]
|
|
||||||
- configボタンをギアアイコンに変更
|
|
||||||
- 詳細情報のボタンを追加
|
|
||||||
- 翻訳機能有効無効のチェックボックスを追加
|
|
||||||
- 最前面表示の有効無効のチェックボックスを追加
|
|
||||||
- いくつかのバグを修正
|
|
||||||
[2023-06-03: v0.3b]
|
|
||||||
- 全体的にUIを刷新
|
|
||||||
- 透過機能を追加
|
|
||||||
- テーマのLight/Dark/Systemのモードの変更機能を追加
|
|
||||||
- UIのスケール変更機能を追加
|
|
||||||
- フォントの変更機能を追加
|
|
||||||
[2023-06-06: v0.4b]
|
|
||||||
- 翻訳エンジンを追加
|
|
||||||
- 入力と出力の翻訳言語を選択できるように変更
|
|
||||||
[2023-06-20: v1.0]
|
|
||||||
- マイクからの音声の文字起こし機能を追加
|
|
||||||
- スピーカーからの音声の文字起こし機能を追加
|
|
||||||
[2023-06-28: v1.1]
|
|
||||||
- いくつかのバクを修正
|
|
||||||
- 翻訳/文字起こし言語の表記を略称からわかりやすい文字に変更
|
|
||||||
- 文字起こしの処理の軽量化
|
|
||||||
[2023-07-05: v1.2]
|
|
||||||
- 文字起こし精度の向上
|
|
||||||
[2023-07-21: v1.3]
|
|
||||||
- UIの表示言語を日本語/英語を選択できる機能を追加
|
|
||||||
- Energy Thresholdの視覚化機能を追加
|
|
||||||
- 文字起こしの誤認識対策のため、Word Filterを追加
|
|
||||||
- WASAPI以外のHostAPIでもマイクとして使用できるようにHostAPIを選択できる機能を追加
|
|
||||||
- メッセージ送信後に書き込んだメッセージを空にするか選択できる機能を追加
|
|
||||||
- バグ対策のため、translation/voice2chatbox/speaker2log/foregroundは起動時はOFFになるように変更
|
|
||||||
- バグ対策のため、スピーカーについて既定デバイス以外を選択した時にERRORが出るように変更
|
|
||||||
- 半角入力時に一部の文字が書き込めないバグを修正
|
|
||||||
[2023-07-22: v1.3.1]
|
|
||||||
- UIの表示言語選択に韓国語を追加
|
|
||||||
|
|
||||||
# 注意事項
|
|
||||||
再配布とかはやめてね
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.textbox_information.insert("end", textbox_information_message)
|
|
||||||
self.textbox_information.configure(state='disabled')
|
|
||||||
self.protocol("WM_DELETE_WINDOW", self.delete_window)
|
|
||||||
|
|
||||||
def delete_window(self):
|
|
||||||
self.withdraw()
|
|
||||||
Reference in New Issue
Block a user