mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-07 22:38:21 +03:00
Refactor translation
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -34,13 +34,6 @@ __all__ = ['CoreManager']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Unable to connect',
|
||||
'Routing option with direct rules is not allowed in VPN mode',
|
||||
)
|
||||
|
||||
|
||||
def fixLogObjectPath(config: ConfigurationFactory, attr: str, value: str, log=True):
|
||||
try:
|
||||
|
||||
Vendored
+45
-30
@@ -4,8 +4,8 @@ TRANSLATION = {
|
||||
"Furious.QtFramework.QtWidgets",
|
||||
"Furious.Widget.UserServersQTableWidget",
|
||||
"Furious.Widget.UserSubsQTableWidget",
|
||||
"Furious.Window.UserSubsWindow",
|
||||
"Furious.Widget.XrayAssetViewerQListWidget"
|
||||
"Furious.Widget.XrayAssetViewerQListWidget",
|
||||
"Furious.Window.UserSubsWindow"
|
||||
],
|
||||
"RU": "Удалить",
|
||||
"ZH": "删除",
|
||||
@@ -252,8 +252,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Save As...": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Сохранить как...",
|
||||
"ZH": "另存为...",
|
||||
@@ -261,7 +261,7 @@ TRANSLATION = {
|
||||
},
|
||||
"Close Window": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Закрыть окно",
|
||||
"ZH": "关闭窗口",
|
||||
@@ -269,8 +269,8 @@ TRANSLATION = {
|
||||
},
|
||||
"File": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.XrayAssetViewerWindow"
|
||||
],
|
||||
"RU": "Файл",
|
||||
@@ -303,8 +303,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Copy": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Копировать",
|
||||
"ZH": "复制",
|
||||
@@ -320,9 +320,9 @@ TRANSLATION = {
|
||||
},
|
||||
"Select All": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Widget.UserServersQTableWidget",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Выбрать все",
|
||||
"ZH": "全选",
|
||||
@@ -338,8 +338,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Edit": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Редактировать",
|
||||
"ZH": "编辑",
|
||||
@@ -347,8 +347,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Zoom In": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Увеличить маштаб",
|
||||
"ZH": "变大",
|
||||
@@ -356,8 +356,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Zoom Out": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Уменьшить маштаб",
|
||||
"ZH": "变小",
|
||||
@@ -365,8 +365,8 @@ TRANSLATION = {
|
||||
},
|
||||
"View": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Вид",
|
||||
"ZH": "显示",
|
||||
@@ -382,8 +382,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Save File": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.Window.LogViewerWindow"
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Сохранить файл",
|
||||
"ZH": "保存文件",
|
||||
@@ -399,8 +399,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Invalid server configuration": {
|
||||
"source": [
|
||||
"Furious.Window.TextEditorWindow",
|
||||
"Furious.TrayActions.Connect"
|
||||
"Furious.TrayActions.Connect",
|
||||
"Furious.Window.TextEditorWindow"
|
||||
],
|
||||
"RU": "Неверная конфигурация сервера",
|
||||
"ZH": "无效的服务器配置",
|
||||
@@ -418,8 +418,11 @@ TRANSLATION = {
|
||||
"source": [
|
||||
"Furious.Widget.GuiHysteria1",
|
||||
"Furious.Widget.GuiHysteria2",
|
||||
"Furious.Widget.UserServersQTableWidget",
|
||||
"Furious.Widget.UserSubsQTableWidget"
|
||||
"Furious.Widget.GuiShadowsocks",
|
||||
"Furious.Widget.GuiTrojan",
|
||||
"Furious.Widget.GuiVLESS",
|
||||
"Furious.Widget.GuiVMess",
|
||||
"Furious.Widget.UserServersQTableWidget"
|
||||
],
|
||||
"RU": "Примечание",
|
||||
"ZH": "别名",
|
||||
@@ -567,7 +570,8 @@ TRANSLATION = {
|
||||
},
|
||||
"New Empty Configuration": {
|
||||
"source": [
|
||||
"Furious.Widget.UserServersQTableWidget"
|
||||
"Furious.Widget.UserServersQTableWidget",
|
||||
"Furious.Window.AppMainWindow"
|
||||
],
|
||||
"RU": "Создать новую пустую конфигурацию",
|
||||
"ZH": "新建空白配置",
|
||||
@@ -599,8 +603,8 @@ TRANSLATION = {
|
||||
},
|
||||
"Connecting": {
|
||||
"source": [
|
||||
"Furious.Widget.UserServersQTableWidget",
|
||||
"Furious.TrayActions.Connect"
|
||||
"Furious.TrayActions.Connect",
|
||||
"Furious.Widget.UserServersQTableWidget"
|
||||
],
|
||||
"RU": "Подключение",
|
||||
"ZH": "正在连接",
|
||||
@@ -672,9 +676,9 @@ TRANSLATION = {
|
||||
},
|
||||
"Exit": {
|
||||
"source": [
|
||||
"Furious.TrayActions.Exit",
|
||||
"Furious.Window.LogViewerWindow",
|
||||
"Furious.Window.XrayAssetViewerWindow",
|
||||
"Furious.TrayActions.Exit"
|
||||
"Furious.Window.XrayAssetViewerWindow"
|
||||
],
|
||||
"RU": "Выход",
|
||||
"ZH": "退出",
|
||||
@@ -864,7 +868,7 @@ TRANSLATION = {
|
||||
],
|
||||
"RU": "Открыть папку приложения",
|
||||
"ZH": "打开应用程序文件夹",
|
||||
"isReviewed": "True",
|
||||
"isReviewed": "True"
|
||||
},
|
||||
"Check For Updates": {
|
||||
"source": [
|
||||
@@ -1360,5 +1364,16 @@ TRANSLATION = {
|
||||
"RU": "Режим энергосбережения",
|
||||
"ZH": "省电模式",
|
||||
"isReviewed": "True"
|
||||
},
|
||||
"OK": {
|
||||
"source": [
|
||||
"Furious.__main__",
|
||||
"Furious.QtFramework.GuiEditorXXX",
|
||||
"Furious.Widget.IndentSpinBox",
|
||||
"Furious.Window.UserSubsWindow"
|
||||
],
|
||||
"RU": "OK",
|
||||
"ZH": "OK",
|
||||
"isReviewed": "True"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,9 @@ import functools
|
||||
|
||||
__all__ = [
|
||||
'gettext',
|
||||
'needTransFn',
|
||||
'LANGUAGE_TO_ABBR',
|
||||
'ABBR_TO_LANGUAGE',
|
||||
'SUPPORTED_LANGUAGE',
|
||||
'TranslationPool',
|
||||
]
|
||||
|
||||
|
||||
@@ -74,9 +72,11 @@ def installTranslation(translation):
|
||||
|
||||
def gettext(source, locale=None):
|
||||
if locale is None:
|
||||
assert APP() is not None
|
||||
|
||||
return translator.translate(source, AppSettings.get('Language'))
|
||||
if APP() is None:
|
||||
# Normally should not reach here if performing a translation
|
||||
return source
|
||||
else:
|
||||
return translator.translate(source, AppSettings.get('Language'))
|
||||
else:
|
||||
assert locale in SUPPORTED_LANGUAGE
|
||||
|
||||
@@ -95,19 +95,3 @@ ABBR_TO_LANGUAGE = {value: key for key, value in LANGUAGE_TO_ABBR.items()}
|
||||
SUPPORTED_LANGUAGE = list(LANGUAGE_TO_ABBR.values())
|
||||
|
||||
installTranslation(TRANSLATION)
|
||||
|
||||
|
||||
class TranslatorHelper:
|
||||
TranslationPool = list()
|
||||
|
||||
@staticmethod
|
||||
def appendText(*texts, **kwargs):
|
||||
source = kwargs.pop('source', '')
|
||||
|
||||
for text in texts:
|
||||
if isinstance(text, str):
|
||||
TranslatorHelper.TranslationPool.append([text, source])
|
||||
|
||||
|
||||
needTransFn = functools.partial(TranslatorHelper.appendText)
|
||||
TranslationPool = TranslatorHelper.TranslationPool
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Interface import *
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _, needTransFn
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _
|
||||
from Furious.QtFramework.QtWidgets import *
|
||||
from Furious.Utility import *
|
||||
|
||||
@@ -40,8 +40,6 @@ __all__ = [
|
||||
'GuiEditorWidgetQDialog',
|
||||
]
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class GuiEditorItemTextInput(GuiEditorItemWidgetContainer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -309,9 +307,6 @@ class GuiEditorWidgetQGroupBox(GuiEditorWidget, AppQGroupBox):
|
||||
# self.setLayout(layout)
|
||||
|
||||
|
||||
needTrans('Cancel')
|
||||
|
||||
|
||||
class GuiEditorWidgetQDialog(GuiEditorItemFactory, AppQDialog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
tabText = kwargs.pop('tabText', '')
|
||||
@@ -330,6 +325,7 @@ class GuiEditorWidgetQDialog(GuiEditorItemFactory, AppQDialog):
|
||||
self.groupBoxes = self.groupBoxSequence()
|
||||
|
||||
for index, groupBox in enumerate(self.groupBoxes):
|
||||
# TODO: Layout
|
||||
self.tabCentralWidgetLayout.addWidget(groupBox, index // 2, index % 2)
|
||||
|
||||
self.tabCentralWidget.setLayout(self.tabCentralWidgetLayout)
|
||||
|
||||
@@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.QtFramework.Ancestors import *
|
||||
from Furious.QtFramework.DynamicTheme import AppHue
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _, needTransFn
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _
|
||||
from Furious.QtFramework.QtGui import AppQAction, AppQSeperator
|
||||
from Furious.PyFramework import *
|
||||
from Furious.Utility import *
|
||||
@@ -55,8 +55,6 @@ __all__ = [
|
||||
'showUnrecognizedConfigMBox',
|
||||
]
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def moveToCenter(widget, parent=None):
|
||||
geometry = widget.geometry()
|
||||
@@ -550,13 +548,6 @@ class AppQToolBar(QTranslatable, QToolBar):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
|
||||
needTrans(
|
||||
'Delete',
|
||||
'Delete these items?',
|
||||
'Delete this item?',
|
||||
)
|
||||
|
||||
|
||||
class QuestionDeleteMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -584,9 +575,6 @@ class QuestionDeleteMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans('New changes will take effect next time')
|
||||
|
||||
|
||||
class NewChangesNextTimeMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -613,11 +601,6 @@ def showNewChangesNextTimeMBox(**kwargs):
|
||||
pass
|
||||
|
||||
|
||||
needTrans(
|
||||
'Unrecognized Configuration. Please modify it in the editor',
|
||||
)
|
||||
|
||||
|
||||
class UnrecognizedConfigMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
|
||||
from Furious.QtFramework.QtNetwork import *
|
||||
from Furious.QtFramework.QtWidgets import *
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _, needTransFn
|
||||
from Furious.QtFramework.DynamicTranslate import gettext as _
|
||||
from Furious.Utility import *
|
||||
from Furious.Library import *
|
||||
|
||||
@@ -37,10 +37,6 @@ __all__ = ['UpdatesManager']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans('New version available')
|
||||
|
||||
|
||||
class QuestionUpdateMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -65,13 +61,6 @@ class QuestionUpdateMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Check for updates failed',
|
||||
'Go to download page?',
|
||||
f'{APPLICATION_NAME} is already the latest version',
|
||||
)
|
||||
|
||||
|
||||
class UpdatesManager(AppQNetworkAccessManager):
|
||||
API_URL = (
|
||||
f'https://api.github.com/repos/'
|
||||
|
||||
@@ -38,27 +38,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
registerAppSettings('Connect', isBinary=True)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Connect',
|
||||
'Connecting',
|
||||
'Disconnect',
|
||||
'Unable to connect',
|
||||
'Server configuration empty. Please configure your server first',
|
||||
'Select and press Enter to activate configuration and connect',
|
||||
f'{APPLICATION_NAME} cannot find any valid http proxy '
|
||||
f'endpoint in the configuration',
|
||||
'Please complete your server configuration',
|
||||
'Connected',
|
||||
'Unknown error',
|
||||
'Invalid server configuration',
|
||||
'Failed to start core',
|
||||
'Connection to server has been lost',
|
||||
'Core terminated unexpectedly',
|
||||
'Disconnected',
|
||||
)
|
||||
|
||||
|
||||
def validateProxyServer(server) -> bool:
|
||||
try:
|
||||
@@ -237,8 +216,7 @@ class ConnectAction(AppQAction):
|
||||
mbox.setWindowTitle(_('Unable to connect'))
|
||||
mbox.setText(
|
||||
_(
|
||||
f'{APPLICATION_NAME} cannot find any valid http proxy '
|
||||
f'endpoint in the configuration'
|
||||
f'{APPLICATION_NAME} cannot find any valid http proxy endpoint in the configuration'
|
||||
)
|
||||
)
|
||||
mbox.setInformativeText(_('Please complete your server configuration'))
|
||||
|
||||
@@ -23,10 +23,6 @@ import functools
|
||||
|
||||
__all__ = ['EditConfigurationAction']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans('Edit Configuration...')
|
||||
|
||||
|
||||
class EditConfigurationAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
@@ -23,10 +23,6 @@ import functools
|
||||
|
||||
__all__ = ['ExitAction']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans('Exit')
|
||||
|
||||
|
||||
class ExitAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
@@ -36,13 +36,6 @@ __all__ = [
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Invalid data',
|
||||
'Invalid data. The content of the clipboard is:',
|
||||
)
|
||||
|
||||
|
||||
def showImportErrorMBox(clipboard: str):
|
||||
mbox = ImportErrorMBox(icon=AppQMessageBox.Icon.Critical)
|
||||
@@ -75,9 +68,6 @@ def importItemFromClipboard(clipboard: str):
|
||||
mbox.open()
|
||||
|
||||
|
||||
needTrans('Import')
|
||||
|
||||
|
||||
class ImportErrorMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -93,13 +83,6 @@ class ImportErrorMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Import',
|
||||
'Import share link success',
|
||||
'Imported to row',
|
||||
)
|
||||
|
||||
|
||||
class ImportMultiSuccessMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -139,12 +122,6 @@ class ImportMultiSuccessMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Import',
|
||||
'Import success',
|
||||
)
|
||||
|
||||
|
||||
class ImportSuccessMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -167,16 +144,6 @@ class ImportSuccessMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Import From File...',
|
||||
'Import File',
|
||||
'Text files (*.json);;All files (*)',
|
||||
'Error opening file',
|
||||
'Invalid configuration file',
|
||||
'Invalid data',
|
||||
)
|
||||
|
||||
|
||||
class ImportFromFileAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
@@ -227,9 +194,6 @@ class ImportFromFileAction(AppQAction):
|
||||
mbox.open()
|
||||
|
||||
|
||||
needTrans('Import Share Link From Clipboard')
|
||||
|
||||
|
||||
class ImportURIFromClipboardAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Import Share Link From Clipboard'), **kwargs)
|
||||
@@ -276,9 +240,6 @@ class ImportURIFromClipboardAction(AppQAction):
|
||||
mbox.open()
|
||||
|
||||
|
||||
needTrans('Import JSON Configuration From Clipboard')
|
||||
|
||||
|
||||
class ImportJSONFromClipboardAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Import JSON Configuration From Clipboard'), **kwargs)
|
||||
@@ -289,9 +250,6 @@ class ImportJSONFromClipboardAction(AppQAction):
|
||||
importItemFromClipboard(clipboard)
|
||||
|
||||
|
||||
needTrans('Import')
|
||||
|
||||
|
||||
class ImportAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
|
||||
@@ -35,8 +35,6 @@ registerAppSettings(
|
||||
'Language', validRange=SUPPORTED_LANGUAGE, default=SMART_CHOSEN_LANGUAGE
|
||||
)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class LanguageChildAction(AppQAction):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -57,9 +55,6 @@ class LanguageChildAction(AppQAction):
|
||||
pass
|
||||
|
||||
|
||||
needTrans('Language')
|
||||
|
||||
|
||||
class LanguageAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
|
||||
@@ -27,9 +27,12 @@ BUILTIN_ROUTING = ['Bypass Mainland China', 'Global', 'Custom']
|
||||
|
||||
registerAppSettings('Routing', validRange=BUILTIN_ROUTING)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(*BUILTIN_ROUTING)
|
||||
# ALL BUILTIN ROUTING VALUE
|
||||
TRANSLATABLE_BUILTIN_ROUTING = [
|
||||
_('Bypass Mainland China'),
|
||||
_('Global'),
|
||||
_('Custom'),
|
||||
]
|
||||
|
||||
|
||||
class RoutingChildAction(AppQAction):
|
||||
@@ -47,9 +50,6 @@ class RoutingChildAction(AppQAction):
|
||||
APP().systemTray.ConnectAction.trigger()
|
||||
|
||||
|
||||
needTrans('Routing')
|
||||
|
||||
|
||||
class RoutingAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
if AppSettings.get('Routing') == 'Bypass':
|
||||
|
||||
@@ -35,13 +35,11 @@ registerAppSettings(
|
||||
)
|
||||
registerAppSettings('ShowTabAndSpacesInEditor', isBinary=True)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'VPN Mode',
|
||||
'VPN Mode Disabled (Administrator)',
|
||||
'VPN Mode Disabled (root)',
|
||||
)
|
||||
# Administrator, root
|
||||
TRANSLATABLE_VPN_MODE = [
|
||||
_('VPN Mode Disabled (Administrator)'),
|
||||
_('VPN Mode Disabled (root)'),
|
||||
]
|
||||
|
||||
|
||||
class VPNModeAction(AppQAction):
|
||||
@@ -134,17 +132,6 @@ class SettingsChildAction(AppQAction):
|
||||
AppSettings.turnOFF('ShowTabAndSpacesInEditor')
|
||||
|
||||
|
||||
needTrans(
|
||||
'Settings',
|
||||
'Dark Mode',
|
||||
'Use Monochrome Tray Icon',
|
||||
'Startup On Boot',
|
||||
'Power Save Mode',
|
||||
'Show Progress Bar When Connecting',
|
||||
'Show Tab And Spaces In Editor',
|
||||
)
|
||||
|
||||
|
||||
class SettingsAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
if PLATFORM == 'Windows' or PLATFORM == 'Darwin':
|
||||
|
||||
@@ -27,8 +27,6 @@ BUILTIN_PROXY_MODE = ['Auto', 'NoChanges']
|
||||
|
||||
registerAppSettings('SystemProxyMode', validRange=BUILTIN_PROXY_MODE)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class SystemProxyChildAction(AppQAction):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -41,13 +39,6 @@ class SystemProxyChildAction(AppQAction):
|
||||
AppSettings.set('SystemProxyMode', 'NoChanges')
|
||||
|
||||
|
||||
needTrans(
|
||||
'System Proxy',
|
||||
'Automatically Configure System Proxy',
|
||||
'Do Not Change System Proxy',
|
||||
)
|
||||
|
||||
|
||||
class SystemProxyAction(AppQAction):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(
|
||||
|
||||
@@ -53,10 +53,11 @@ GOLDEN_RATIO = (math.sqrt(5) + 1) / 2
|
||||
PROXY_OUTBOUND_USER_EMAIL = f'user@{ORGANIZATION_DOMAIN}'
|
||||
|
||||
ROOT_DIR = pathlib.Path(__file__).resolve().parent.parent.parent
|
||||
DATA_DIR = ROOT_DIR / APPLICATION_NAME / 'Data'
|
||||
PACKAGE_DIR = ROOT_DIR / APPLICATION_NAME
|
||||
DATA_DIR = PACKAGE_DIR / 'Data'
|
||||
XRAY_ASSET_DIR = DATA_DIR / 'xray'
|
||||
CRASH_LOG_DIR = ROOT_DIR / APPLICATION_NAME / 'CrashLog'
|
||||
GEN_TRANSLATION_FILE = ROOT_DIR / APPLICATION_NAME / 'Externals' / 'GenTranslation.py'
|
||||
CRASH_LOG_DIR = PACKAGE_DIR / 'CrashLog'
|
||||
GEN_TRANSLATION_FILE = PACKAGE_DIR / 'Externals' / 'GenTranslation.py'
|
||||
|
||||
PROXY_SERVER_BYPASS = (
|
||||
'localhost;*.local;127.*;10.*;172.16.*;172.17.*;'
|
||||
|
||||
@@ -47,8 +47,6 @@ registerAppSettings('AppLogViewerWidgetPointSize')
|
||||
registerAppSettings('CoreLogViewerWidgetPointSize')
|
||||
registerAppSettings('TunLogViewerWidgetPointSize')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def rateLimited(maxCallPerSecond):
|
||||
"""
|
||||
@@ -158,14 +156,6 @@ class ApplicationThemeDetector(QtCore.QObject):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
needTrans(
|
||||
'Already started',
|
||||
'Furious Log',
|
||||
'Core Log',
|
||||
'Tun2socks Log',
|
||||
)
|
||||
|
||||
|
||||
class Application(ApplicationFactory, SingletonApplication):
|
||||
def __init__(self, argv):
|
||||
super().__init__(argv)
|
||||
|
||||
@@ -33,8 +33,6 @@ __all__ = ['GuiHysteria1']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class GuiHy1ItemTextInput(GuiEditorItemTextInput):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -217,9 +215,6 @@ class GuiHy1ItemTLSInsecure(GuiEditorItemTextCheckBox):
|
||||
self.setChecked(checked)
|
||||
|
||||
|
||||
needTrans('Project Website')
|
||||
|
||||
|
||||
class GuiHy1ProjectWebsiteURL(AppQLabel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -247,14 +242,6 @@ class GuiHy1ProjectWebsiteURL(AppQLabel):
|
||||
self.setWebsiteURL()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Remark',
|
||||
'Server',
|
||||
'Protocol',
|
||||
)
|
||||
|
||||
|
||||
class GuiHy1GroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -269,9 +256,6 @@ class GuiHy1GroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiHy1GroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
@@ -283,9 +267,6 @@ class GuiHy1GroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Speed')
|
||||
|
||||
|
||||
class GuiHy1GroupBoxSpeed(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Speed'), **kwargs)
|
||||
@@ -312,9 +293,6 @@ class GuiHy1GroupBoxTLS(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Other')
|
||||
|
||||
|
||||
class GuiHy1GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Other'), **kwargs)
|
||||
|
||||
@@ -33,8 +33,6 @@ __all__ = ['GuiHysteria2']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class GuiHy2ItemBasicServer(GuiEditorItemTextInput):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -355,13 +353,6 @@ class GuiHy2ItemTLSInsecure(GuiEditorItemTextCheckBox):
|
||||
self.setChecked(checked)
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Remark',
|
||||
'Server',
|
||||
)
|
||||
|
||||
|
||||
class GuiHy2GroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -374,9 +365,6 @@ class GuiHy2GroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiHy2GroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
@@ -418,9 +406,6 @@ class GuiHy2GroupBoxTLS(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Project Website')
|
||||
|
||||
|
||||
class GuiHy2ProjectWebsiteURL(AppQLabel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -448,9 +433,6 @@ class GuiHy2ProjectWebsiteURL(AppQLabel):
|
||||
self.setWebsiteURL()
|
||||
|
||||
|
||||
needTrans('Other')
|
||||
|
||||
|
||||
class GuiHy2GroupBoxOther(GuiEditorItemFactory, AppQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Other'), **kwargs)
|
||||
|
||||
@@ -26,8 +26,6 @@ from Furious.Widget.GuiVTLS import *
|
||||
|
||||
__all__ = ['GuiShadowsocks']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def getProxyOutboundObject(config: ConfigurationFactory) -> dict:
|
||||
if not isinstance(config.get('outbounds'), list):
|
||||
@@ -213,15 +211,6 @@ class GuiSSItemBasicMethod(GuiEditorItemTextComboBox):
|
||||
self.setText('')
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Address',
|
||||
'Port',
|
||||
'Encryption',
|
||||
'Password',
|
||||
)
|
||||
|
||||
|
||||
class GuiSSGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -236,9 +225,6 @@ class GuiSSGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiSSGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
|
||||
@@ -26,8 +26,6 @@ from Furious.Widget.GuiVTLS import *
|
||||
|
||||
__all__ = ['GuiTrojan']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def getProxyOutboundObject(config: ConfigurationFactory) -> dict:
|
||||
if not isinstance(config.get('outbounds'), list):
|
||||
@@ -161,14 +159,6 @@ class GuiTrojanItemBasicPort(GuiEditorItemTextSpinBox):
|
||||
self.setValue(0)
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Address',
|
||||
'Port',
|
||||
'Password',
|
||||
)
|
||||
|
||||
|
||||
class GuiTrojanGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -182,9 +172,6 @@ class GuiTrojanGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiTrojanGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
|
||||
@@ -26,8 +26,6 @@ from Furious.Widget.GuiVTLS import *
|
||||
|
||||
__all__ = ['GuiVLESS']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def getProxyOutboundObject(config: ConfigurationFactory) -> dict:
|
||||
if not isinstance(config.get('outbounds'), list):
|
||||
@@ -292,15 +290,6 @@ class GuiVLESSItemBasicFlow(GuiEditorItemTextComboBox):
|
||||
self.setText('')
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Address',
|
||||
'Port',
|
||||
'Encryption',
|
||||
'Flow',
|
||||
)
|
||||
|
||||
|
||||
class GuiVLESSGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -316,9 +305,6 @@ class GuiVLESSGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiVLESSGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
|
||||
@@ -26,8 +26,6 @@ from Furious.Widget.GuiVTLS import *
|
||||
|
||||
__all__ = ['GuiVMess']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def getProxyOutboundObject(config: ConfigurationFactory) -> dict:
|
||||
if not isinstance(config.get('outbounds'), list):
|
||||
@@ -293,13 +291,6 @@ class GuiVMessItemBasicSecurity(GuiEditorItemTextComboBox):
|
||||
self.setText('')
|
||||
|
||||
|
||||
needTrans(
|
||||
'Basic Configuration',
|
||||
'Address',
|
||||
'Port',
|
||||
)
|
||||
|
||||
|
||||
class GuiVMessGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Basic Configuration'), **kwargs)
|
||||
@@ -315,9 +306,6 @@ class GuiVMessGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
]
|
||||
|
||||
|
||||
needTrans('Proxy')
|
||||
|
||||
|
||||
class GuiVMessGroupBoxProxy(GuiEditorWidgetQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Proxy'), **kwargs)
|
||||
|
||||
@@ -28,8 +28,6 @@ from typing import Callable
|
||||
|
||||
__all__ = ['GuiVTLSQGroupBox']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
STREAM_SECURITY = [
|
||||
'',
|
||||
'none',
|
||||
|
||||
@@ -30,8 +30,6 @@ from typing import Callable
|
||||
|
||||
__all__ = ['GuiVTransportQGroupBox']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
STREAM_NETWORK = [
|
||||
'tcp',
|
||||
'kcp',
|
||||
@@ -1440,11 +1438,6 @@ class GuiVTransportPageStackedWidget(QStackedWidget):
|
||||
page.connectActivated(func)
|
||||
|
||||
|
||||
needTrans(
|
||||
'Transport',
|
||||
)
|
||||
|
||||
|
||||
class GuiVTransportQGroupBox(GuiEditorItemFactory, AppQGroupBox):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(_('Transport'), **kwargs)
|
||||
|
||||
@@ -27,14 +27,6 @@ import functools
|
||||
|
||||
__all__ = ['IndentSpinBox']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Set Indent',
|
||||
'Indent:',
|
||||
'Cancel',
|
||||
)
|
||||
|
||||
|
||||
class IndentSpinBox(AppQDialog):
|
||||
def __init__(self, parent=None):
|
||||
|
||||
@@ -53,8 +53,6 @@ logger = logging.getLogger(__name__)
|
||||
registerAppSettings('ActivatedItemIndex')
|
||||
registerAppSettings('ServerWidgetSectionSizeTable')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class SubscriptionManager(AppQNetworkAccessManager):
|
||||
def __init__(self, parent):
|
||||
@@ -584,35 +582,18 @@ class UserServersQTableWidgetHeaders:
|
||||
return self.name
|
||||
|
||||
|
||||
needTrans(
|
||||
'Remark',
|
||||
'Protocol',
|
||||
'Address',
|
||||
'Port',
|
||||
'Transport',
|
||||
'TLS',
|
||||
'Subscription',
|
||||
'Latency',
|
||||
'Speed',
|
||||
'Customize JSON Configuration...',
|
||||
'Move Up',
|
||||
'Move Down',
|
||||
'Duplicate',
|
||||
'Delete',
|
||||
'Select All',
|
||||
'Scroll To Activated Server',
|
||||
'Test Ping Latency',
|
||||
'Test Tcping Latency',
|
||||
'Test Download Speed',
|
||||
'Clear Test Results',
|
||||
'New Empty Configuration',
|
||||
'Export Share Link To Clipboard',
|
||||
'Export As QR Code',
|
||||
'Export JSON Configuration To Clipboard',
|
||||
'Connecting',
|
||||
'Connecting. Please wait',
|
||||
'Untitled',
|
||||
)
|
||||
# ALL Headers VALUE
|
||||
TRANSLATABLE_HEADERS = [
|
||||
_('Remark'),
|
||||
_('Protocol'),
|
||||
_('Address'),
|
||||
_('Port'),
|
||||
_('Transport'),
|
||||
_('TLS'),
|
||||
_('Subscription'),
|
||||
_('Latency'),
|
||||
_('Speed'),
|
||||
]
|
||||
|
||||
|
||||
class UserServersQTableWidget(QTranslatable, AppQTableWidget):
|
||||
@@ -857,7 +838,7 @@ class UserServersQTableWidget(QTranslatable, AppQTableWidget):
|
||||
if APP().systemTray.ConnectAction.isConnecting():
|
||||
mbox = AppQMessageBox(icon=AppQMessageBox.Icon.Information)
|
||||
mbox.setWindowTitle(_('Connecting'))
|
||||
mbox.setText(_('Connecting. Please wait'))
|
||||
mbox.setText(_('Connecting. Please wait...'))
|
||||
|
||||
if PLATFORM != 'Darwin':
|
||||
# Show the MessageBox asynchronously
|
||||
|
||||
@@ -36,8 +36,6 @@ __all__ = ['UserSubsQTableWidget']
|
||||
|
||||
registerAppSettings('SubscriptionWidgetSectionSizeTable')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class UserSubsQTableWidgetHorizontalHeader(AppQHeaderView):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -67,12 +65,6 @@ class UserSubsQTableWidgetHeaders:
|
||||
return self.name
|
||||
|
||||
|
||||
needTrans(
|
||||
'Remark',
|
||||
'Delete',
|
||||
)
|
||||
|
||||
|
||||
class UserSubsQTableWidget(QTranslatable, AppQTableWidget):
|
||||
Headers = [
|
||||
UserSubsQTableWidgetHeaders('Remark', lambda item: item.get('remark', '')),
|
||||
|
||||
@@ -37,8 +37,6 @@ __all__ = ['XrayAssetViewerQListWidget']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
class AssetExistsMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -57,15 +55,6 @@ class AssetExistsMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Delete',
|
||||
'Import',
|
||||
'Asset file already exists. Overwrite?',
|
||||
'Error import asset file',
|
||||
'Import asset file success',
|
||||
)
|
||||
|
||||
|
||||
class XrayAssetViewerQListWidget(SupportThemeChangedCallback, AppQListWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -44,8 +44,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
registerAppSettings('ServerWidgetWindowSize')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
|
||||
def connectedHttpProxyEndpoint() -> Union[str, None]:
|
||||
try:
|
||||
@@ -129,32 +127,6 @@ class AppNetworkStateManager(NetworkStateManager):
|
||||
self.stopTest()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Server',
|
||||
'Add VMess Server...',
|
||||
'Add VLESS Server...',
|
||||
'Add Shadowsocks Server...',
|
||||
'Add Trojan Server...',
|
||||
'Add Hysteria1 Server...',
|
||||
'Add Hysteria2 Server...',
|
||||
'Subscription',
|
||||
'Update Subscription (Use Current Proxy)',
|
||||
'Update Subscription (Force Proxy)',
|
||||
'Update Subscription (No Proxy)',
|
||||
'Edit Subscription...',
|
||||
'Log',
|
||||
'Show Furious Log',
|
||||
'Show Core Log',
|
||||
'Show Tun2socks Log',
|
||||
'Tools',
|
||||
'Manage Xray-core Asset File...',
|
||||
'Open Application Folder',
|
||||
'Check For Updates',
|
||||
'About',
|
||||
'Help',
|
||||
)
|
||||
|
||||
|
||||
class AppMainWindow(AppQMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -393,6 +365,15 @@ class AppMainWindow(AppQMainWindow):
|
||||
],
|
||||
}
|
||||
|
||||
# Corresponds to menus defined above
|
||||
TRANSLATABLE_MENU_NAME = [
|
||||
_('Log'),
|
||||
_('Server'),
|
||||
_('Subscription'),
|
||||
_('Tools'),
|
||||
_('Help'),
|
||||
]
|
||||
|
||||
# Menus
|
||||
for menuDict in (logMenu, serverMenu, subsMenu, toolsMenu, helpMenu):
|
||||
menuName = menuDict['name']
|
||||
|
||||
@@ -27,10 +27,6 @@ import functools
|
||||
|
||||
__all__ = ['LogViewerWindow']
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans('Unable to save log')
|
||||
|
||||
|
||||
class SaveErrorMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -53,13 +49,6 @@ class SaveErrorMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Save File',
|
||||
'Text files (*.txt);;All files (*)',
|
||||
'Error saving log',
|
||||
)
|
||||
|
||||
|
||||
def saveAsFile(content: str):
|
||||
filename, selectedFilter = QFileDialog.getSaveFileName(
|
||||
None, _('Save File'), filter=_('Text files (*.txt);;All files (*)')
|
||||
@@ -81,20 +70,6 @@ def saveAsFile(content: str):
|
||||
mbox.open()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Log Viewer',
|
||||
'Save As...',
|
||||
'Exit',
|
||||
'File',
|
||||
'Copy',
|
||||
'Select All',
|
||||
'Edit',
|
||||
'Zoom In',
|
||||
'Zoom Out',
|
||||
'View',
|
||||
)
|
||||
|
||||
|
||||
class LogViewerWindow(AppQMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
tabTitle = kwargs.pop('tabTitle', '')
|
||||
|
||||
@@ -34,16 +34,6 @@ __all__ = ['TextEditorWindow']
|
||||
|
||||
registerAppSettings('ServerWidgetPointSize')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Save Changes',
|
||||
'The content has been modified. Save changes?',
|
||||
'Save',
|
||||
'Cancel',
|
||||
'Discard',
|
||||
)
|
||||
|
||||
|
||||
class QuestionSaveMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -61,9 +51,6 @@ class QuestionSaveMBox(AppQMessageBox):
|
||||
self.setDefaultButton(self.button0)
|
||||
|
||||
|
||||
needTrans('Please check if the configuration is in valid JSON format')
|
||||
|
||||
|
||||
class JSONDecodeErrorMBox(AppQMessageBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -85,31 +72,6 @@ class JSONDecodeErrorMBox(AppQMessageBox):
|
||||
self.moveToCenter()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Save',
|
||||
'Save As...',
|
||||
'Close Window',
|
||||
'File',
|
||||
'Undo',
|
||||
'Redo',
|
||||
'Cut',
|
||||
'Copy',
|
||||
'Paste',
|
||||
'Select All',
|
||||
'Indent...',
|
||||
'Edit',
|
||||
'Zoom In',
|
||||
'Zoom Out',
|
||||
'View',
|
||||
'Error saving configuration',
|
||||
'Save File',
|
||||
'Text files (*.json);;All files (*)',
|
||||
'Error Saving File',
|
||||
'Invalid server configuration',
|
||||
'Error setting indent',
|
||||
)
|
||||
|
||||
|
||||
class TextEditorWindow(AppQMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -33,15 +33,6 @@ __all__ = ['UserSubsWindow']
|
||||
|
||||
registerAppSettings('SubscriptionWidgetWindowSize')
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Add Subscription',
|
||||
'Enter subscription remark:',
|
||||
'Enter subscription URL:',
|
||||
'Cancel',
|
||||
)
|
||||
|
||||
|
||||
class AddSubsDialog(AppQDialog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -83,14 +74,6 @@ class AddSubsDialog(AppQDialog):
|
||||
return self.webURLEdit.text()
|
||||
|
||||
|
||||
needTrans(
|
||||
'Edit Subscription',
|
||||
'Subscription List',
|
||||
'Add',
|
||||
'Delete',
|
||||
)
|
||||
|
||||
|
||||
class UserSubsWindow(AppQMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
callback = kwargs.pop('deleteUniqueCallback', None)
|
||||
|
||||
@@ -34,19 +34,6 @@ __all__ = ['XrayAssetViewerWindow']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
'Xray-core Asset File',
|
||||
'Refresh',
|
||||
'Open Asset Directory',
|
||||
'Import From File...',
|
||||
'Exit',
|
||||
'File',
|
||||
'Import File',
|
||||
'All files (*)',
|
||||
)
|
||||
|
||||
|
||||
class XrayAssetViewerWindow(AppQMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -34,17 +34,6 @@ __all__ = ['main']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
needTrans = functools.partial(needTransFn, source=__name__)
|
||||
|
||||
needTrans(
|
||||
f'{APPLICATION_NAME} is not able to run on this operating system',
|
||||
'Operating system information',
|
||||
f'{APPLICATION_NAME} encountered an internal error and needs to be stopped',
|
||||
f'{APPLICATION_NAME} stopped unexpectedly due to an unknown exception',
|
||||
'Crash log has been saved to',
|
||||
'Open crash log',
|
||||
)
|
||||
|
||||
|
||||
def runAppMain():
|
||||
appMainProcess = AppMainProcess(functools.partial(Application, sys.argv))
|
||||
|
||||
+83
-37
@@ -17,23 +17,20 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from Furious.Core import *
|
||||
from Furious.Interface import *
|
||||
from Furious.Library import *
|
||||
from Furious.Utility import *
|
||||
from Furious.PyFramework import *
|
||||
from Furious.QtFramework import *
|
||||
from Furious.Storage import *
|
||||
from Furious.TrayActions import *
|
||||
from Furious.Widget import *
|
||||
from Furious.Window import *
|
||||
from Furious.__main__ import *
|
||||
from Furious.Externals import *
|
||||
|
||||
import os
|
||||
import re
|
||||
import copy
|
||||
import deepl
|
||||
|
||||
# import deepl
|
||||
import logging
|
||||
import argparse
|
||||
import functools
|
||||
|
||||
import Furious
|
||||
|
||||
logging.basicConfig(
|
||||
format='[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s',
|
||||
@@ -44,9 +41,32 @@ logging.raiseExceptions = False
|
||||
logger = logging.getLogger('Translation')
|
||||
|
||||
|
||||
@functools.lru_cache(None)
|
||||
def getAppSourceCodePath(path):
|
||||
# Walk through the directory tree
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
# Check if __init__.py exists in the current directory
|
||||
if '__init__.py' in filenames:
|
||||
for filename in filenames:
|
||||
yield os.path.join(dirpath, filename)
|
||||
|
||||
|
||||
@functools.lru_cache(None)
|
||||
def getMagicNameFromPath(path):
|
||||
return os.path.relpath(path, ROOT_DIR).removesuffix('.py').replace(os.sep, '.')
|
||||
|
||||
|
||||
@functools.lru_cache(None)
|
||||
def getAppConstantsByName(name):
|
||||
return getattr(Furious.Utility.Constants, name)
|
||||
|
||||
|
||||
APPLICATION_SOURCE_CODE_PATH = getAppSourceCodePath(PACKAGE_DIR)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-k', '--key', help='DeepL auth key', required=True)
|
||||
# parser.add_argument('-k', '--key', help='DeepL auth key', required=True)
|
||||
parser.add_argument(
|
||||
'-t', '--target', help='Target translation language', required=True
|
||||
)
|
||||
@@ -68,14 +88,40 @@ def main():
|
||||
# Reset source
|
||||
translation[key]['source'] = []
|
||||
|
||||
for text, source in TranslationPool:
|
||||
if text not in translation:
|
||||
translation[text] = {'source': [source]}
|
||||
else:
|
||||
unit = translation[text]
|
||||
for sourceCodePath in APPLICATION_SOURCE_CODE_PATH:
|
||||
with open(sourceCodePath, 'r', encoding='utf-8') as file:
|
||||
content = file.read()
|
||||
|
||||
if source not in unit['source']:
|
||||
unit['source'].append(source)
|
||||
magicName = getMagicNameFromPath(sourceCodePath)
|
||||
|
||||
pattern = r"(?<![a-zA-Z])_\(\s*f?\s*(?:'([^']*)'|\"([^\"]*)\")\s*\)"
|
||||
matches = re.findall(pattern, content)
|
||||
|
||||
if matches:
|
||||
match = [m[0] or m[1] for m in matches]
|
||||
|
||||
for source in match:
|
||||
foundBraces = True
|
||||
|
||||
while foundBraces:
|
||||
lBraceIndex = source.find('{')
|
||||
rBraceIndex = source.find('}')
|
||||
|
||||
if lBraceIndex >= 0 and rBraceIndex >= 0:
|
||||
parsed = source[lBraceIndex + 1 : rBraceIndex]
|
||||
|
||||
source = source.replace(
|
||||
source[lBraceIndex : rBraceIndex + 1],
|
||||
getAppConstantsByName(parsed),
|
||||
)
|
||||
else:
|
||||
foundBraces = False
|
||||
|
||||
if source not in translation:
|
||||
translation[source] = {'source': [magicName]}
|
||||
else:
|
||||
if magicName not in translation[source]['source']:
|
||||
translation[source]['source'].append(magicName)
|
||||
|
||||
nonexist = []
|
||||
|
||||
@@ -88,7 +134,7 @@ def main():
|
||||
# Key with no source, remove
|
||||
translation.pop(key, None)
|
||||
|
||||
translator = deepl.Translator(args.key, send_platform_info=False, proxy=proxy)
|
||||
# translator = deepl.Translator(args.key, send_platform_info=False, proxy=proxy)
|
||||
|
||||
for text in translation.keys():
|
||||
# Remove redundant EN translation
|
||||
@@ -103,21 +149,21 @@ def main():
|
||||
f'skip reviewed translation: \'{text}\' --{target}--> \'{targetText}\''
|
||||
)
|
||||
else:
|
||||
result = translator.translate_text(
|
||||
text,
|
||||
source_lang='EN',
|
||||
target_lang=target,
|
||||
context=(
|
||||
f'\'{APPLICATION_NAME}\' is application name. '
|
||||
'Please do not translate this word'
|
||||
),
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f'query translation: \'{text}\' --{target}--> \'{result.text}\''
|
||||
)
|
||||
|
||||
translation[text][target] = result.text
|
||||
# result = translator.translate_text(
|
||||
# text,
|
||||
# source_lang='EN',
|
||||
# target_lang=target,
|
||||
# context=(
|
||||
# f'\'{APPLICATION_NAME}\' is application name. '
|
||||
# 'Please do not translate this word'
|
||||
# ),
|
||||
# )
|
||||
#
|
||||
# logger.info(
|
||||
# f'query translation: \'{text}\' --{target}--> \'{result.text}\''
|
||||
# )
|
||||
#
|
||||
# translation[text][target] = result.text
|
||||
|
||||
if not targetText or translation[text].get('isReviewed') is None:
|
||||
# Target translation does not exist, or does not have 'isReviewed' field.
|
||||
@@ -143,12 +189,12 @@ def main():
|
||||
if isReviewed == 'False':
|
||||
unreviewed += 1
|
||||
|
||||
logger.warning(f'have unreviewed translations \'{text}\'')
|
||||
logger.warning(f'have unreviewed translation \'{text}\'')
|
||||
|
||||
if unreviewed > 0:
|
||||
logger.error(f'have {unreviewed} unreviewed translations')
|
||||
logger.error(f'have {unreviewed} unreviewed translation(s)')
|
||||
else:
|
||||
logger.info(f'all translations have been reviewed')
|
||||
logger.info(f'all {len(translation)} translation(s) have been reviewed')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user