From d600f86d66a2b99b7b248b1e978a564c1799cf85 Mon Sep 17 00:00:00 2001 From: Loren Eteval Date: Thu, 20 Mar 2025 00:22:32 +0800 Subject: [PATCH] Refactor translation Signed-off-by: Loren Eteval --- Furious/Core/CoreManager.py | 7 -- Furious/Externals/GenTranslation.py | 75 +++++++----- Furious/QtFramework/DynamicTranslate.py | 26 +--- Furious/QtFramework/GuiEditorXXX.py | 8 +- Furious/QtFramework/QtWidgets.py | 19 +-- Furious/QtFramework/UpdatesManager.py | 13 +- Furious/TrayActions/Connect.py | 24 +--- Furious/TrayActions/EditConfiguration.py | 4 - Furious/TrayActions/Exit.py | 4 - Furious/TrayActions/Import.py | 42 ------- Furious/TrayActions/Language.py | 5 - Furious/TrayActions/Routing.py | 12 +- Furious/TrayActions/Settings.py | 23 +--- Furious/TrayActions/SystemProxy.py | 9 -- Furious/Utility/Constants.py | 7 +- Furious/Widget/Application.py | 10 -- Furious/Widget/GuiHysteria1.py | 22 ---- Furious/Widget/GuiHysteria2.py | 18 --- Furious/Widget/GuiShadowsocks.py | 14 --- Furious/Widget/GuiTrojan.py | 13 -- Furious/Widget/GuiVLESS.py | 14 --- Furious/Widget/GuiVMess.py | 12 -- Furious/Widget/GuiVTLS.py | 2 - Furious/Widget/GuiVTransport.py | 7 -- Furious/Widget/IndentSpinBox.py | 8 -- Furious/Widget/UserServersQTableWidget.py | 45 ++----- Furious/Widget/UserSubsQTableWidget.py | 8 -- Furious/Widget/XrayAssetViewerQListWidget.py | 11 -- Furious/Window/AppMainWindow.py | 37 ++---- Furious/Window/LogViewerWindow.py | 25 ---- Furious/Window/TextEditorWindow.py | 38 ------ Furious/Window/UserSubsWindow.py | 17 --- Furious/Window/XrayAssetViewerWindow.py | 13 -- Furious/__main__.py | 11 -- Translation.py | 120 +++++++++++++------ 35 files changed, 175 insertions(+), 548 deletions(-) diff --git a/Furious/Core/CoreManager.py b/Furious/Core/CoreManager.py index fd6ad6a..8534f81 100644 --- a/Furious/Core/CoreManager.py +++ b/Furious/Core/CoreManager.py @@ -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: diff --git a/Furious/Externals/GenTranslation.py b/Furious/Externals/GenTranslation.py index f150b8b..b2ebe5b 100644 --- a/Furious/Externals/GenTranslation.py +++ b/Furious/Externals/GenTranslation.py @@ -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" } } diff --git a/Furious/QtFramework/DynamicTranslate.py b/Furious/QtFramework/DynamicTranslate.py index b0ff436..f991f5a 100644 --- a/Furious/QtFramework/DynamicTranslate.py +++ b/Furious/QtFramework/DynamicTranslate.py @@ -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 diff --git a/Furious/QtFramework/GuiEditorXXX.py b/Furious/QtFramework/GuiEditorXXX.py index 7ff9de4..be3dd58 100644 --- a/Furious/QtFramework/GuiEditorXXX.py +++ b/Furious/QtFramework/GuiEditorXXX.py @@ -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) diff --git a/Furious/QtFramework/QtWidgets.py b/Furious/QtFramework/QtWidgets.py index a5993a8..c7a56d0 100644 --- a/Furious/QtFramework/QtWidgets.py +++ b/Furious/QtFramework/QtWidgets.py @@ -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) diff --git a/Furious/QtFramework/UpdatesManager.py b/Furious/QtFramework/UpdatesManager.py index 2c39af6..7daa615 100644 --- a/Furious/QtFramework/UpdatesManager.py +++ b/Furious/QtFramework/UpdatesManager.py @@ -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/' diff --git a/Furious/TrayActions/Connect.py b/Furious/TrayActions/Connect.py index ca68a9a..c35b8de 100644 --- a/Furious/TrayActions/Connect.py +++ b/Furious/TrayActions/Connect.py @@ -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')) diff --git a/Furious/TrayActions/EditConfiguration.py b/Furious/TrayActions/EditConfiguration.py index e5d81f3..af9a6e5 100644 --- a/Furious/TrayActions/EditConfiguration.py +++ b/Furious/TrayActions/EditConfiguration.py @@ -23,10 +23,6 @@ import functools __all__ = ['EditConfigurationAction'] -needTrans = functools.partial(needTransFn, source=__name__) - -needTrans('Edit Configuration...') - class EditConfigurationAction(AppQAction): def __init__(self, **kwargs): diff --git a/Furious/TrayActions/Exit.py b/Furious/TrayActions/Exit.py index 184f93f..c248d31 100644 --- a/Furious/TrayActions/Exit.py +++ b/Furious/TrayActions/Exit.py @@ -23,10 +23,6 @@ import functools __all__ = ['ExitAction'] -needTrans = functools.partial(needTransFn, source=__name__) - -needTrans('Exit') - class ExitAction(AppQAction): def __init__(self, **kwargs): diff --git a/Furious/TrayActions/Import.py b/Furious/TrayActions/Import.py index 8931831..55ef500 100644 --- a/Furious/TrayActions/Import.py +++ b/Furious/TrayActions/Import.py @@ -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__( diff --git a/Furious/TrayActions/Language.py b/Furious/TrayActions/Language.py index f0b2cde..41a1567 100644 --- a/Furious/TrayActions/Language.py +++ b/Furious/TrayActions/Language.py @@ -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__( diff --git a/Furious/TrayActions/Routing.py b/Furious/TrayActions/Routing.py index 85ea50f..00ea880 100644 --- a/Furious/TrayActions/Routing.py +++ b/Furious/TrayActions/Routing.py @@ -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': diff --git a/Furious/TrayActions/Settings.py b/Furious/TrayActions/Settings.py index c301ec3..8f2ffd4 100644 --- a/Furious/TrayActions/Settings.py +++ b/Furious/TrayActions/Settings.py @@ -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': diff --git a/Furious/TrayActions/SystemProxy.py b/Furious/TrayActions/SystemProxy.py index a9ce258..6de6c35 100644 --- a/Furious/TrayActions/SystemProxy.py +++ b/Furious/TrayActions/SystemProxy.py @@ -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__( diff --git a/Furious/Utility/Constants.py b/Furious/Utility/Constants.py index 94e4e82..666b084 100644 --- a/Furious/Utility/Constants.py +++ b/Furious/Utility/Constants.py @@ -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.*;' diff --git a/Furious/Widget/Application.py b/Furious/Widget/Application.py index 2d07832..bb70b2e 100644 --- a/Furious/Widget/Application.py +++ b/Furious/Widget/Application.py @@ -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) diff --git a/Furious/Widget/GuiHysteria1.py b/Furious/Widget/GuiHysteria1.py index bf024a2..653d865 100644 --- a/Furious/Widget/GuiHysteria1.py +++ b/Furious/Widget/GuiHysteria1.py @@ -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) diff --git a/Furious/Widget/GuiHysteria2.py b/Furious/Widget/GuiHysteria2.py index d34fea3..b2bbad4 100644 --- a/Furious/Widget/GuiHysteria2.py +++ b/Furious/Widget/GuiHysteria2.py @@ -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) diff --git a/Furious/Widget/GuiShadowsocks.py b/Furious/Widget/GuiShadowsocks.py index 2c38e2f..22afaff 100644 --- a/Furious/Widget/GuiShadowsocks.py +++ b/Furious/Widget/GuiShadowsocks.py @@ -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) diff --git a/Furious/Widget/GuiTrojan.py b/Furious/Widget/GuiTrojan.py index 5aebbc9..0e64937 100644 --- a/Furious/Widget/GuiTrojan.py +++ b/Furious/Widget/GuiTrojan.py @@ -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) diff --git a/Furious/Widget/GuiVLESS.py b/Furious/Widget/GuiVLESS.py index 24e0524..0227548 100644 --- a/Furious/Widget/GuiVLESS.py +++ b/Furious/Widget/GuiVLESS.py @@ -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) diff --git a/Furious/Widget/GuiVMess.py b/Furious/Widget/GuiVMess.py index b3cbf15..4ef3c13 100644 --- a/Furious/Widget/GuiVMess.py +++ b/Furious/Widget/GuiVMess.py @@ -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) diff --git a/Furious/Widget/GuiVTLS.py b/Furious/Widget/GuiVTLS.py index fd5117e..2473fa2 100644 --- a/Furious/Widget/GuiVTLS.py +++ b/Furious/Widget/GuiVTLS.py @@ -28,8 +28,6 @@ from typing import Callable __all__ = ['GuiVTLSQGroupBox'] -needTrans = functools.partial(needTransFn, source=__name__) - STREAM_SECURITY = [ '', 'none', diff --git a/Furious/Widget/GuiVTransport.py b/Furious/Widget/GuiVTransport.py index 2bed3e8..497e0cc 100644 --- a/Furious/Widget/GuiVTransport.py +++ b/Furious/Widget/GuiVTransport.py @@ -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) diff --git a/Furious/Widget/IndentSpinBox.py b/Furious/Widget/IndentSpinBox.py index f0be1a4..9a0e162 100644 --- a/Furious/Widget/IndentSpinBox.py +++ b/Furious/Widget/IndentSpinBox.py @@ -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): diff --git a/Furious/Widget/UserServersQTableWidget.py b/Furious/Widget/UserServersQTableWidget.py index 6c8f290..b0f8d54 100644 --- a/Furious/Widget/UserServersQTableWidget.py +++ b/Furious/Widget/UserServersQTableWidget.py @@ -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 diff --git a/Furious/Widget/UserSubsQTableWidget.py b/Furious/Widget/UserSubsQTableWidget.py index 0c1131a..2b53957 100644 --- a/Furious/Widget/UserSubsQTableWidget.py +++ b/Furious/Widget/UserSubsQTableWidget.py @@ -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', '')), diff --git a/Furious/Widget/XrayAssetViewerQListWidget.py b/Furious/Widget/XrayAssetViewerQListWidget.py index b06e305..5ab927c 100644 --- a/Furious/Widget/XrayAssetViewerQListWidget.py +++ b/Furious/Widget/XrayAssetViewerQListWidget.py @@ -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) diff --git a/Furious/Window/AppMainWindow.py b/Furious/Window/AppMainWindow.py index b9a2fc6..5e2cfc9 100644 --- a/Furious/Window/AppMainWindow.py +++ b/Furious/Window/AppMainWindow.py @@ -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'] diff --git a/Furious/Window/LogViewerWindow.py b/Furious/Window/LogViewerWindow.py index 268786a..9a42f25 100644 --- a/Furious/Window/LogViewerWindow.py +++ b/Furious/Window/LogViewerWindow.py @@ -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', '') diff --git a/Furious/Window/TextEditorWindow.py b/Furious/Window/TextEditorWindow.py index 58a45b8..567d3bc 100644 --- a/Furious/Window/TextEditorWindow.py +++ b/Furious/Window/TextEditorWindow.py @@ -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) diff --git a/Furious/Window/UserSubsWindow.py b/Furious/Window/UserSubsWindow.py index 06731bc..b19bcf3 100644 --- a/Furious/Window/UserSubsWindow.py +++ b/Furious/Window/UserSubsWindow.py @@ -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) diff --git a/Furious/Window/XrayAssetViewerWindow.py b/Furious/Window/XrayAssetViewerWindow.py index 8e4a178..d80c1cf 100644 --- a/Furious/Window/XrayAssetViewerWindow.py +++ b/Furious/Window/XrayAssetViewerWindow.py @@ -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): diff --git a/Furious/__main__.py b/Furious/__main__.py index 9fb6901..b4322a7 100644 --- a/Furious/__main__.py +++ b/Furious/__main__.py @@ -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)) diff --git a/Translation.py b/Translation.py index 65fe537..03ccf4f 100644 --- a/Translation.py +++ b/Translation.py @@ -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"(?= 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__':