From a5cd118b9918f4aa47465176063f4e815e60a8a5 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 16 May 2024 08:58:41 -0600 Subject: [PATCH] change: Improved translation services' settings. Closes #632 --- doc/changelog.md | 3 +++ src/app-configuration.defaults | 7 ++++--- src/controller/settings.py | 8 +++++++- src/extra/translator/engines/deep_l.py | 4 ++-- src/extra/translator/translator.py | 21 +++++++++---------- src/wxUI/dialogs/configuration.py | 28 ++++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 1d9f0bfdc..7d708f989 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,9 @@ TWBlue Changelog ## changes in this version +* Core: + * Added Initial Support to GoToSocial. + * The translation module has been rewritten. Now, instead of offering translations with Google Translator, the user can choose between [LibreTranslate,](https://github.com/LibreTranslate/LibreTranslate) which requires no configuration thanks to the [instance of the NVDA Spanish community;](https://translate.nvda.es) or translate using [DeepL,](https://deepl.com) for which it is necessary to create an account on DeepL and [subscribe to a DeepL API Free plan](https://support.deepl.com/hc/en-us/articles/360021200939-DeepL-API-Free) to obtain the API key which can be used to translate up to 500000 characters every month. The API key can be entered in the global options dialog, under a new tab called translation services. When translating a text, the translation engine can be changed. When changing the translation engine, the target language must be selected again before translation takes place. * Mastodon: * Fixed an error that caused TWBlue to be unable to properly display the user action dialog from the followers or following buffer. ([#575](https://github.com/mcv-software/twblue/issues/575)) diff --git a/src/app-configuration.defaults b/src/app-configuration.defaults index 3901db0a8..b3c23ea8c 100644 --- a/src/app-configuration.defaults +++ b/src/app-configuration.defaults @@ -31,6 +31,7 @@ user = string(default="") password = string(default="") [translator] -engine=string(default="deepl") -translator_api_url=string(default="https://translate.nvda.es") -translator_api_key=string(default="") +engine=string(default="LibreTranslate") +lt_api_url=string(default="https://translate.nvda.es") +lt_api_key=string(default="") +deepl_api_key = string(default="") \ No newline at end of file diff --git a/src/controller/settings.py b/src/controller/settings.py index 1ef7ffd78..b6b6767db 100644 --- a/src/controller/settings.py +++ b/src/controller/settings.py @@ -73,7 +73,10 @@ def create_config(self): self.dialog.set_value("proxy", "port", config.app["proxy"]["port"]) self.dialog.set_value("proxy", "user", config.app["proxy"]["user"]) self.dialog.set_value("proxy", "password", config.app["proxy"]["password"]) - + self.dialog.create_translator_panel() + self.dialog.set_value("translator_panel", "libre_api_url", config.app["translator"]["lt_api_url"]) + self.dialog.set_value("translator_panel", "libre_api_key", config.app["translator"]["lt_api_key"]) + self.dialog.set_value("translator_panel", "deepL_api_key", config.app["translator"]["deepl_api_key"]) self.dialog.realize() self.response = self.dialog.get_response() @@ -120,4 +123,7 @@ def save_configuration(self): config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") config.app["proxy"]["user"] = self.dialog.get_value("proxy", "user") config.app["proxy"]["password"] = self.dialog.get_value("proxy", "password") + config.app["translator"]["lt_api_url"] = self.dialog.get_value("translator_panel", "libre_api_url") + config.app["translator"]["lt_api_key"] = self.dialog.get_value("translator_panel", "libre_api_key") + config.app["translator"]["deepl_api_key"] = self.dialog.get_value("translator_panel", "deepL_api_key") config.app.write() diff --git a/src/extra/translator/engines/deep_l.py b/src/extra/translator/engines/deep_l.py index 32096d005..42a5d2b4d 100644 --- a/src/extra/translator/engines/deep_l.py +++ b/src/extra/translator/engines/deep_l.py @@ -3,12 +3,12 @@ from deepl import Translator def translate(text: str, target_language: str) -> str: - key = config.app["translator"]["translator_api_key"] + key = config.app["translator"]["deepl_api_key"] t = Translator(key) return t.translate_text(text, target_lang=target_language).text def languages(): - key = config.app["translator"]["translator_api_key"] + key = config.app["translator"]["deepl_api_key"] t = Translator(key) langs = t.get_target_languages() return langs \ No newline at end of file diff --git a/src/extra/translator/translator.py b/src/extra/translator/translator.py index 4e1015713..1957d372a 100644 --- a/src/extra/translator/translator.py +++ b/src/extra/translator/translator.py @@ -17,9 +17,9 @@ def __init__(self, text): self.response = False self.dialog = translateDialog() pub.subscribe(self.on_engine_changed, "translator.engine_changed") - if config.app["translator"]["engine"] == "libretranslate": + if config.app["translator"]["engine"] == "LibreTranslate": self.dialog.engine_select.SetSelection(0) - elif config.app["translator"]["engine"] == "deepl": + elif config.app["translator"]["engine"] == "DeepL": self.dialog.engine_select.SetSelection(1) threading.Thread(target=self.load_languages).start() if self.dialog.ShowModal() == wx.ID_OK: @@ -35,27 +35,24 @@ def load_languages(self): self.dialog.set_languages(self.languages) def on_engine_changed(self, engine): - if engine == "LibreTranslate": - config.app["translator"]["engine"] = engine.lower() - elif engine == "DeepL": - config.app["translator"]["engine"] = engine.lower() + config.app["translator"]["engine"] = engine config.app.write() threading.Thread(target=self.load_languages).start() def translate(self): log.debug("Received translation request for language %s, text=%s" % (self.target_language, self.text)) - if config.app["translator"].get("engine") == "libretranslate": - translator = libre_translate.CustomLibreTranslateAPI(config.app["translator"]["translator_api_url"]) + if config.app["translator"].get("engine") == "LibreTranslate": + translator = libre_translate.CustomLibreTranslateAPI(config.app["translator"]["lt_api_url"], config.app["translator"]["lt_api_key"]) vars = dict(q=self.text, target=self.target_language) return translator.translate(**vars) - elif config.app["translator"]["engine"] == "deepl" and config.app["translator"]["translator_api_key"] != "": + elif config.app["translator"]["engine"] == "DeepL" and config.app["translator"]["deepl_api_key"] != "": return deep_l.translate(text=self.text, target_language=self.target_language) def get_languages(self): languages = {} - if config.app["translator"].get("engine") == "libretranslate": - translator = libre_translate.CustomLibreTranslateAPI(config.app["translator"]["translator_api_url"]) + if config.app["translator"].get("engine") == "LibreTranslate": + translator = libre_translate.CustomLibreTranslateAPI(config.app["translator"]["lt_api_url"], config.app["translator"]["lt_api_key"]) languages = {l.get("code"): l.get("name") for l in translator.languages()} - elif config.app["translator"]["engine"] == "deepl" and config.app["translator"]["translator_api_key"] != "": + elif config.app["translator"]["engine"] == "DeepL" and config.app["translator"]["deepl_api_key"] != "": languages = {language.code: language.name for language in deep_l.languages()} return dict(sorted(languages.items(), key=lambda x: x[1])) diff --git a/src/wxUI/dialogs/configuration.py b/src/wxUI/dialogs/configuration.py index 45e6ef422..c131f4e0f 100644 --- a/src/wxUI/dialogs/configuration.py +++ b/src/wxUI/dialogs/configuration.py @@ -201,6 +201,30 @@ def get_list(self): buffers_list.append(self.buffers.get_text_column(i, 0)) return buffers_list +class TranslatorPanel(wx.Panel, baseDialog.BaseWXDialog): + def __init__(self, parent): + super(TranslatorPanel, self).__init__(parent) + + sizer = wx.BoxSizer(wx.VERTICAL) + lbl_libre_url = wx.StaticText(self, wx.ID_ANY, _(u"LibreTranslate API URL: ")) + self.libre_api_url = wx.TextCtrl(self, wx.ID_ANY) + libreUrlBox = wx.BoxSizer(wx.HORIZONTAL) + libreUrlBox.Add(lbl_libre_url, 0, wx.ALL, 5) + libreUrlBox.Add(self.libre_api_url, 1, wx.ALL | wx.EXPAND, 5) + sizer.Add(libreUrlBox, 0, wx.ALL | wx.EXPAND, 5) + lbl_libre_api_key = wx.StaticText(self, wx.ID_ANY, _(u"LibreTranslate API Key (optional): ")) + self.libre_api_key = wx.TextCtrl(self, wx.ID_ANY) + libreApiKeyBox = wx.BoxSizer(wx.HORIZONTAL) + libreApiKeyBox.Add(lbl_libre_api_key, 0, wx.ALL, 5) + libreApiKeyBox.Add(self.libre_api_key, 1, wx.ALL | wx.EXPAND, 5) + sizer.Add(libreApiKeyBox, 0, wx.ALL | wx.EXPAND, 5) + lbl_deepL_api_key = wx.StaticText(self, wx.ID_ANY, _(u"DeepL API Key: ")) + self.deepL_api_key = wx.TextCtrl(self, wx.ID_ANY) + deepLApiKeyBox = wx.BoxSizer(wx.HORIZONTAL) + deepLApiKeyBox.Add(lbl_deepL_api_key, 0, wx.ALL, 5) + deepLApiKeyBox.Add(self.deepL_api_key, 1, wx.ALL | wx.EXPAND, 5) + sizer.Add(deepLApiKeyBox, 0, wx.ALL | wx.EXPAND, 5) + self.SetSizer(sizer) class configurationDialog(baseDialog.BaseWXDialog): def set_title(self, title): self.SetTitle(title) @@ -221,6 +245,10 @@ def create_proxy(self, proxyTypes): self.proxy = proxy(self.notebook, proxyTypes) self.notebook.AddPage(self.proxy, _(u"Proxy")) + def create_translator_panel(self): + self.translator_panel= TranslatorPanel(self.notebook) + self.notebook.AddPage(self.translator_panel, _("Translation services")) + def realize(self): self.sizer.Add(self.notebook, 0, wx.ALL, 5) ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)