diff --git a/uniquebible/db/BiblesSqlite.py b/uniquebible/db/BiblesSqlite.py index b5f6c37799..33047fc537 100644 --- a/uniquebible/db/BiblesSqlite.py +++ b/uniquebible/db/BiblesSqlite.py @@ -1265,7 +1265,7 @@ def readTextVerse(self, b, c, v, noAudioTag=False): else: return (b, c, v, f"{FileUtil.getVerseAudioTag(self.text, b, c, v)}{textVerse}") else: - print("Verse table does not exist") + print(f"Verse table does not exist in {self.text}") return (b, c, v, "") def readFormattedChapter(self, verse, source): diff --git a/uniquebible/db/BiblesSqlite_nogui.py b/uniquebible/db/BiblesSqlite_nogui.py index b157f56503..2dacd64bf5 100644 --- a/uniquebible/db/BiblesSqlite_nogui.py +++ b/uniquebible/db/BiblesSqlite_nogui.py @@ -1092,7 +1092,7 @@ def readTextVerse(self, b, c, v): # return a tuple return textVerse else: - print("Verse table does not exist") + print(f"Verse table does not exist in {self.text}") return (b, c, v, "") def readFormattedChapter(self, verse, source): diff --git a/uniquebible/docker_requirements.txt b/uniquebible/docker_requirements.txt index fbdd3732f7..bfa6e2a4db 100644 --- a/uniquebible/docker_requirements.txt +++ b/uniquebible/docker_requirements.txt @@ -23,8 +23,6 @@ gTTS==2.2.3 html-text==0.5.2 html5lib==1.1 htmldocx==0.0.6 -ibm-cloud-sdk-core==3.14.0 -ibm-watson==5.3.1 idna==3.7 importlib-metadata==4.8.1 Jinja2==3.1.4 diff --git a/uniquebible/gui/AlephMainWindow.py b/uniquebible/gui/AlephMainWindow.py index e474fd5af3..a32a7686dc 100644 --- a/uniquebible/gui/AlephMainWindow.py +++ b/uniquebible/gui/AlephMainWindow.py @@ -174,14 +174,6 @@ def create_menu(self): ("setup", self.setupGist), ("menu_gist", self.showGistWindow), ) - for feature, action in items: - addMenuItem(subMenu, feature, self, action) - subMenu = addSubMenu(menu1_defaults, "watsonTranslator") - items = ( - ("setup", self.setupWatsonTranslator), - ("enterCredentials", self.showWatsonCredentialWindow), - ("menu1_setMyLanguage", self.openTranslationLanguageDialog), - ) for feature, action in items: addMenuItem(subMenu, feature, self, action) if ("OfflineTts" in config.enabled): diff --git a/uniquebible/gui/ConfigFlagsWindow.py b/uniquebible/gui/ConfigFlagsWindow.py index 8e48cf3fe5..da17eca2db 100644 --- a/uniquebible/gui/ConfigFlagsWindow.py +++ b/uniquebible/gui/ConfigFlagsWindow.py @@ -146,6 +146,7 @@ def getOptions(self): ("refreshWindowsAfterSavingNote", config.refreshWindowsAfterSavingNote, self.refreshWindowsAfterSavingNoteChanged, True, config.thisTranslation["refreshWindowsAfterSavingNote"]), ("limitWorkspaceFilenameLength", config.limitWorkspaceFilenameLength, self.limitWorkspaceFilenameLengthChanged, True, config.thisTranslation["limitWorkspaceFilenameLength"]), ("enableHttpRemoteErrorRedirection", config.enableHttpRemoteErrorRedirection, self.enableHttpRemoteErrorRedirection, False, config.thisTranslation["enableHttpRemoteErrorRedirection"]), + ("overrideCompareToUseAllTexts", config.overrideCompareToUseAllTexts, self.overrideCompareToUseAllTexts, False, config.thisTranslation["overrideCompareToUseAllTexts"]), ] if ("OfflineTts" in config.enabled): options += [ @@ -604,3 +605,6 @@ def limitWorkspaceFilenameLengthChanged(self): def enableHttpRemoteErrorRedirection(self): config.enableHttpRemoteErrorRedirection = not config.enableHttpRemoteErrorRedirection + + def overrideCompareToUseAllTexts(self): + config.overrideCompareToUseAllTexts = not config.overrideCompareToUseAllTexts \ No newline at end of file diff --git a/uniquebible/gui/FocusMainWindow.py b/uniquebible/gui/FocusMainWindow.py index 553ccc07ad..fdec79db6b 100644 --- a/uniquebible/gui/FocusMainWindow.py +++ b/uniquebible/gui/FocusMainWindow.py @@ -230,14 +230,6 @@ def create_menu(self): subMenu = addSubMenu(subMenu0, "menu1_programInterface") for language in LanguageUtil.getNamesSupportedLanguages(): addMenuItem(subMenu, language, self, partial(self.changeInterfaceLanguage, language), translation=False) - subMenu = addSubMenu(subMenu0, "watsonTranslator") - items = ( - ("setup", self.setupWatsonTranslator), - ("enterCredentials", self.showWatsonCredentialWindow), - ("menu1_setMyLanguage", self.openTranslationLanguageDialog), - ) - for feature, action in items: - addMenuItem(subMenu, feature, self, action) if ("OfflineTts" in config.enabled): languages = self.getTtsLanguages() languageCodes = list(languages.keys()) diff --git a/uniquebible/gui/MainWindow.py b/uniquebible/gui/MainWindow.py index 26985e0dbb..3bfdb1b79a 100755 --- a/uniquebible/gui/MainWindow.py +++ b/uniquebible/gui/MainWindow.py @@ -60,7 +60,6 @@ from uniquebible.gui.GistWindow import GistWindow from uniquebible.gui.Downloader import Downloader, DownloadProcess from uniquebible.gui.ModifyDatabaseDialog import ModifyDatabaseDialog -from uniquebible.gui.WatsonCredentialWindow import WatsonCredentialWindow from uniquebible.gui.LanguageItemWindow import LanguageItemWindow from uniquebible.gui.ImportSettings import ImportSettings #from uniquebible.gui.NoteEditor import NoteEditor @@ -3170,9 +3169,6 @@ def setupYouTube(self): def setupGist(self): self.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/Gist-synching") - def setupWatsonTranslator(self): - self.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") - def openUbaWiki(self): self.openWebsite("https://github.com/eliranwong/UniqueBible/wiki") @@ -4846,7 +4842,7 @@ def openInterfaceLanguageDialog(self): self.setupMenuLayout(config.menuLayout) self.reloadControlPanel(False) - def changeInterfaceLanguage(self, language): + def changeInterfaceLanguage(self, language, dummy=None): config.displayLanguage = Languages.code[language] self.setTranslation() self.setupMenuLayout(config.menuLayout) @@ -4857,19 +4853,13 @@ def changeInterfaceLanguage(self, language): # userLanguage is used when user translate a selected word with right-click menu or use TRANSLATE::: command # For example, a user can use English menu but he can translate a word into Chinese. def openTranslationLanguageDialog(self): - # Use IBM Watson service to translate text - translator = Translator() - if translator.language_translator is not None: - if not config.userLanguage or not config.userLanguage in Translator.toLanguageNames: - userLanguage = "English" - else: - userLanguage = config.userLanguage - item, ok = QInputDialog.getItem(self, "UniqueBible", config.thisTranslation["menu1_setMyLanguage"], Translator.toLanguageNames, Translator.toLanguageNames.index(userLanguage), False) - if ok and item: - config.userLanguage = item + if not config.userLanguage or not config.userLanguage in Translator.toLanguageNames: + userLanguage = "English" else: - self.displayMessage(config.thisTranslation["ibmWatsonNotEnalbed"]) - self.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") + userLanguage = config.userLanguage + item, ok = QInputDialog.getItem(self, "UniqueBible", config.thisTranslation["menu1_setMyLanguage"], Translator.toLanguageNames, Translator.toLanguageNames.index(userLanguage), False) + if ok and item: + config.userLanguage = item # Set verse number single-click action (config.verseNoSingleClickAction) def selectSingleClickActionDialog(self): @@ -5386,11 +5376,6 @@ def showGistWindow(self): config.gistToken = gw.gistTokenInput.text() self.reloadCurrentRecord() - def showWatsonCredentialWindow(self): - window = WatsonCredentialWindow() - if window.exec(): - config.myIBMWatsonApikey, config.myIBMWatsonUrl, config.myIBMWatsonVersion = window.inputApiKey.text(), window.inputURL.text(), window.inputVersion.text() - def showAddLanguageItemWindow(self): window = LanguageItemWindow(config.thisTranslation["addLanguageFiles"]) if window.exec() and window.key.text(): diff --git a/uniquebible/gui/MaterialMainWindow.py b/uniquebible/gui/MaterialMainWindow.py index 95e4d8d3b9..cc3b5d098d 100644 --- a/uniquebible/gui/MaterialMainWindow.py +++ b/uniquebible/gui/MaterialMainWindow.py @@ -488,14 +488,6 @@ def setMarkdownExportHeadingStyleSubmenu(): subMenu = addSubMenu(subMenu01, "menu1_programInterface") for language in LanguageUtil.getNamesSupportedLanguages(): addCheckableMenuItem(subMenu, language, self, partial(self.changeInterfaceLanguage, language), config.displayLanguage, Languages.code[language], translation=False) - subMenu = addSubMenu(subMenu01, "watsonTranslator") - items = ( - ("setup", self.setupWatsonTranslator), - ("enterCredentials", self.showWatsonCredentialWindow), - ("menu1_setMyLanguage", self.openTranslationLanguageDialog), - ) - for feature, action in items: - addMenuItem(subMenu, feature, self, action) if ("OfflineTts" in config.enabled): languages = self.getTtsLanguages() languageCodes = list(languages.keys()) diff --git a/uniquebible/gui/NoteEditor.py b/uniquebible/gui/NoteEditor.py index c85514be38..02123754db 100644 --- a/uniquebible/gui/NoteEditor.py +++ b/uniquebible/gui/NoteEditor.py @@ -1315,14 +1315,10 @@ def translateText(self): text = self.editor.textCursor().selectedText() if text: translator = Translator() - if translator.language_translator is not None: - fromLanguage = Translator.fromLanguageCodes[self.fromLanguageCombo.currentIndex() - 1] if self.fromLanguageCombo.currentIndex() != 0 else translator.identify(text) - toLanguage = Translator.toLanguageCodes[self.toLanguageCombo.currentIndex()] - result = translator.translate(text, fromLanguage, toLanguage) - self.editor.insertPlainText(result) - else: - self.displayMessage(config.thisTranslation["ibmWatsonNotEnalbed"]) - webbrowser.open("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") + fromLanguage = Translator.fromLanguageCodes[self.fromLanguageCombo.currentIndex() - 1] if self.fromLanguageCombo.currentIndex() != 0 else translator.identify(text) + toLanguage = Translator.toLanguageCodes[self.toLanguageCombo.currentIndex()] + result = translator.translate(text, fromLanguage, toLanguage) + self.editor.insertPlainText(result) else: self.selectTextFirst() diff --git a/uniquebible/gui/WatsonCredentialWindow.py b/uniquebible/gui/WatsonCredentialWindow.py deleted file mode 100644 index 92bbec80bf..0000000000 --- a/uniquebible/gui/WatsonCredentialWindow.py +++ /dev/null @@ -1,58 +0,0 @@ -from uniquebible import config -import webbrowser -if config.qtLibrary == "pyside6": - from PySide6.QtGui import QMouseEvent - from PySide6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QLineEdit -else: - from qtpy.QtGui import QMouseEvent - from qtpy.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QLineEdit - - -class WatsonCredentialWindow(QDialog): - - def __init__(self): - super().__init__() - self.setWindowTitle(config.thisTranslation["ibmWatsonCredentials"]) - self.setMinimumWidth(380) - - layout0 = QVBoxLayout() - layout0.setSpacing(20) - - layout = QVBoxLayout() - layout.setSpacing(5) - - layout.addWidget(QLabel(config.thisTranslation["ibmWatsonCredentials"])) - - wikiLink = "https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator" - readWiki = QLabel(wikiLink) - readWiki.mouseReleaseEvent = lambda event=QMouseEvent, wikiLink=wikiLink: webbrowser.open(wikiLink) - layout.addWidget(readWiki) - - layout0.addLayout(layout) - - layout = QVBoxLayout() - layout.setSpacing(5) - - layout.addWidget(QLabel("API key:")) - self.inputApiKey = QLineEdit() - self.inputApiKey.setText(config.myIBMWatsonApikey) - layout.addWidget(self.inputApiKey) - - layout.addWidget(QLabel("URL:")) - self.inputURL = QLineEdit() - self.inputURL.setText(config.myIBMWatsonUrl) - layout.addWidget(self.inputURL) - - layout.addWidget(QLabel("Version:")) - self.inputVersion = QLineEdit() - self.inputVersion.setText(config.myIBMWatsonVersion) - layout.addWidget(self.inputVersion) - - button = QDialogButtonBox.Ok - buttonBox = QDialogButtonBox(button) - buttonBox.accepted.connect(self.accept) - layout.addWidget(buttonBox) - - layout0.addLayout(layout) - - self.setLayout(layout0) diff --git a/uniquebible/gui/WebEngineView.py b/uniquebible/gui/WebEngineView.py index 7c5f21124f..5720195fe9 100644 --- a/uniquebible/gui/WebEngineView.py +++ b/uniquebible/gui/WebEngineView.py @@ -892,8 +892,6 @@ def addMenuActions(self): separator.setSeparator(True) self.addAction(separator) - # IBM-Watson Translation Service - # Translate into User-defined Language userLanguage = config.userLanguage translateText = QAction(self) @@ -909,10 +907,6 @@ def addMenuActions(self): action.triggered.connect(partial(self.selectedTextToSelectedLanguage, languageCode)) translateMenu.addAction(action) - watsonTranslate = QAction(self) - watsonTranslate.setText(config.thisTranslation["watsonTranslator"]) - watsonTranslate.setMenu(translateMenu) - translateMenu = QMenu() for language, languageCode in Languages.googleTranslateCodes.items(): action = QAction(self) @@ -927,7 +921,6 @@ def addMenuActions(self): translateWrapper = QAction(self) translateWrapper.setText(config.thisTranslation["translate"]) translateWrapperMenu = QMenu() - translateWrapperMenu.addAction(watsonTranslate) translateWrapperMenu.addAction(googleTranslate) translateWrapper.setMenu(translateWrapperMenu) self.addAction(translateWrapper) @@ -1150,7 +1143,6 @@ def googleTranslate(self, language): url = "https://translate.google.com/?sl=origin_language_or_auto&tl={0}&text={1}&op=translate".format(language, selectedText) self.openSimpleBrowser(url) - # Translate selected words into Selected Language (Watson Translator) def selectedTextToSelectedLanguage(self, language): selectedText = self.selectedTextProcessed() if not selectedText: @@ -1160,32 +1152,22 @@ def selectedTextToSelectedLanguage(self, language): # Check if config.userLanguage is set def checkUserLanguage(self): - # Use IBM Watson service to translate text translator = Translator() - if translator.language_translator is not None: - if config.userLanguage and config.userLanguage in Translator.toLanguageNames: - selectedText = self.selectedTextProcessed() - if not selectedText: - self.messageNoSelection() - else: - userLanguage = Translator.toLanguageCodes[Translator.toLanguageNames.index(config.userLanguage)] - self.translateTextIntoUserLanguage(selectedText, userLanguage) + if config.userLanguage and config.userLanguage in Translator.toLanguageNames: + selectedText = self.selectedTextProcessed() + if not selectedText: + self.messageNoSelection() else: - self.parent.parent.openTranslationLanguageDialog() + userLanguage = Translator.toLanguageCodes[Translator.toLanguageNames.index(config.userLanguage)] + self.translateTextIntoUserLanguage(selectedText, userLanguage) else: - self.parent.parent.displayMessage(config.thisTranslation["ibmWatsonNotEnalbed"]) - config.mainWindow.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") + self.parent.parent.openTranslationLanguageDialog() # Translate selected words into user-defined language def translateTextIntoUserLanguage(self, text, userLanguage="en"): - # Use IBM Watson service to translate text translator = Translator() - if translator.language_translator is not None: - translation = translator.translate(text, None, userLanguage) - self.openPopover(html=translation) - else: - self.parent.parent.displayMessage(config.thisTranslation["ibmWatsonNotEnalbed"]) - config.mainWindow.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") + translation = translator.translate(text, "auto", userLanguage) + self.openPopover(html=translation) # TEXT-TO-SPEECH feature def textToSpeech(self, activeSelection=False): diff --git a/uniquebible/lang/language_de.py b/uniquebible/lang/language_de.py index b948ec4bc1..812814f92c 100644 --- a/uniquebible/lang/language_de.py +++ b/uniquebible/lang/language_de.py @@ -1093,4 +1093,5 @@ "donate": "Spenden", "about": "Informationen zu", "githubStatistics": "GitHub-Statistik", + "overrideCompareToUseAllTexts": "Überschreiben Vers Vergleich, um alle Bibeltexte anstelle von Lieblingstexten zu vergleichen", } \ No newline at end of file diff --git a/uniquebible/lang/language_el.py b/uniquebible/lang/language_el.py index b33f14230a..a43a476599 100644 --- a/uniquebible/lang/language_el.py +++ b/uniquebible/lang/language_el.py @@ -1093,4 +1093,5 @@ "donate": "Δότη!", "about": "-Ναι.", "githubStatistics": "Στατιστικά στοιχεία GitHub", + "overrideCompareToUseAllTexts": "Παράκαμψε τη σύγκριση των εδαφίων για να συγκρίνεις όλα τα Γραφικά εδάφια αντί των αγαπημένων κειμένων", } diff --git a/uniquebible/lang/language_en_GB.py b/uniquebible/lang/language_en_GB.py index b667613ea6..16956a061a 100644 --- a/uniquebible/lang/language_en_GB.py +++ b/uniquebible/lang/language_en_GB.py @@ -1093,4 +1093,5 @@ "donate": "Donate", "about": "About", "githubStatistics": "GitHub Statistics", + "overrideCompareToUseAllTexts": "Override verse comparison to compare all Bible texts instead of favourite texts", } diff --git a/uniquebible/lang/language_en_US.py b/uniquebible/lang/language_en_US.py index c8ef0b7cc7..632d36c4dd 100644 --- a/uniquebible/lang/language_en_US.py +++ b/uniquebible/lang/language_en_US.py @@ -1093,4 +1093,5 @@ "donate": "Donate", "about": "About", "githubStatistics": "GitHub Statistics", + "overrideCompareToUseAllTexts": "Override verse comparison to compare all Bible texts instead of favorite texts", } diff --git a/uniquebible/lang/language_es.py b/uniquebible/lang/language_es.py index 90f17a0a0a..3e49d05608 100644 --- a/uniquebible/lang/language_es.py +++ b/uniquebible/lang/language_es.py @@ -1093,4 +1093,5 @@ "donate": "Donar", "about": "Acerca de", "githubStatistics": "Estadísticas de GitHub", + "overrideCompareToUseAllTexts": "Superar la comparación de versículos para comparar todos los textos bíblicos en lugar de los textos favoritos", } diff --git a/uniquebible/lang/language_fr.py b/uniquebible/lang/language_fr.py index d67b409509..a312354c14 100644 --- a/uniquebible/lang/language_fr.py +++ b/uniquebible/lang/language_fr.py @@ -1093,4 +1093,5 @@ "donate": "Donate", "about": "A propos", "githubStatistics": "Statistiques GitHub", + "overrideCompareToUseAllTexts": "Comparativement aux versets pour comparer tous les textes bibliques au lieu des textes préférés", } diff --git a/uniquebible/lang/language_hi.py b/uniquebible/lang/language_hi.py index 1865d1daec..e9c463de38 100644 --- a/uniquebible/lang/language_hi.py +++ b/uniquebible/lang/language_hi.py @@ -1093,4 +1093,5 @@ "donate": "दान", "about": "लगभग", "githubStatistics": "Githb सांख्यिकी", + "overrideCompareToUseAllTexts": "पसंदीदा ग्रंथों के बजाय सभी बाइबिल ग्रंथों की तुलना करने के लिए ओवरराइड कविता तुलना", } diff --git a/uniquebible/lang/language_it.py b/uniquebible/lang/language_it.py index f35dcb377c..87d3cbfd63 100644 --- a/uniquebible/lang/language_it.py +++ b/uniquebible/lang/language_it.py @@ -1093,4 +1093,5 @@ "donate": "Donato", "about": "Informazioni su", "githubStatistics": "Statistiche GitHub", + "overrideCompareToUseAllTexts": "Confronto dei versetti override per confrontare tutti i testi della Bibbia invece di testi preferiti", } diff --git a/uniquebible/lang/language_ja.py b/uniquebible/lang/language_ja.py index d0229e74d0..1e89f4e5ae 100644 --- a/uniquebible/lang/language_ja.py +++ b/uniquebible/lang/language_ja.py @@ -1093,4 +1093,5 @@ "donate": "ドナーテ", "about": "アバウト", "githubStatistics": "GitHub 統計", + "overrideCompareToUseAllTexts": "お気に入りテキストの代わりに、すべての聖書のテキストを比較するための重複比較をオーバーライド", } diff --git a/uniquebible/lang/language_ko.py b/uniquebible/lang/language_ko.py index 5fc178d154..05f74ce584 100644 --- a/uniquebible/lang/language_ko.py +++ b/uniquebible/lang/language_ko.py @@ -1093,4 +1093,5 @@ "donate": "기부하다", "about": "정보", "githubStatistics": "깃허브 통계", + "overrideCompareToUseAllTexts": "가장 좋아하는 텍스트 대신 모든 성경 텍스트를 비교하는 배율 비교", } diff --git a/uniquebible/lang/language_ml.py b/uniquebible/lang/language_ml.py index 9b29b84260..6a26efebd1 100644 --- a/uniquebible/lang/language_ml.py +++ b/uniquebible/lang/language_ml.py @@ -1093,4 +1093,5 @@ "donate": "ഡോണെറ്റ്", "about": "ഏകദേശം", "githubStatistics": "ഗിറ്റ്ഹബ് സ്ഥിതിവിവരംName", + "overrideCompareToUseAllTexts": "Override verse comparison to compare all Bible texts instead of favourite texts", } diff --git a/uniquebible/lang/language_ro.py b/uniquebible/lang/language_ro.py index 9e89d75e8d..81cb7ded38 100644 --- a/uniquebible/lang/language_ro.py +++ b/uniquebible/lang/language_ro.py @@ -1093,4 +1093,5 @@ "donate": "Donează", "about": "Despre", "githubStatistics": "Statistici GitHub", + "overrideCompareToUseAllTexts": "Compară versetul cu toate textele biblice în locul textelor favorite", } diff --git a/uniquebible/lang/language_ru.py b/uniquebible/lang/language_ru.py index 01be84be79..d1904a7055 100644 --- a/uniquebible/lang/language_ru.py +++ b/uniquebible/lang/language_ru.py @@ -1093,4 +1093,5 @@ "donate": "Пожертвовать", "about": "О", "githubStatistics": "Статистика GitHub", + "overrideCompareToUseAllTexts": "Сравнение стихов для сравнения всех библейских текстов вместо любимых", } diff --git a/uniquebible/lang/language_zh_HANS.py b/uniquebible/lang/language_zh_HANS.py index f11455023b..6b61c13166 100644 --- a/uniquebible/lang/language_zh_HANS.py +++ b/uniquebible/lang/language_zh_HANS.py @@ -1093,4 +1093,5 @@ "donate": "捐赠", "about": "关于", "githubStatistics": "GitHub 统计信息", + "overrideCompareToUseAllTexts": "取代反比来比较所有圣经文本而不是最爱的文本", } diff --git a/uniquebible/lang/language_zh_HANT.py b/uniquebible/lang/language_zh_HANT.py index 1302a7ff83..1f1b53c427 100644 --- a/uniquebible/lang/language_zh_HANT.py +++ b/uniquebible/lang/language_zh_HANT.py @@ -1093,4 +1093,5 @@ "donate": "多納特", "about": "關於", "githubStatistics": "GitHub 統計資料", + "overrideCompareToUseAllTexts": "在比對所有聖經取而代之的取而代之的取而代之", } diff --git a/uniquebible/util/ConfigUtil.py b/uniquebible/util/ConfigUtil.py index 8a0d1a7fc6..15007995d5 100644 --- a/uniquebible/util/ConfigUtil.py +++ b/uniquebible/util/ConfigUtil.py @@ -699,15 +699,6 @@ def updateModules(module, isInstalled): setConfig("workingTranslation", """ # Specify the translation which is actively being edited. This option is created for development purpose.""", "en_US") - setConfig("myIBMWatsonApikey", """ - # IBM Watson service api key""", - "") - setConfig("myIBMWatsonUrl", """ - # IBM Watson service api url""", - "") - setConfig("myIBMWatsonVersion", """ - # IBM Watson service api version""", - "2018-05-01") setConfig("myGoogleApiKey", """ # Personal google api key for display of google maps inside UBA window.""", "") @@ -1799,6 +1790,21 @@ def updateModules(module, isInstalled): """, False) + setConfig("overrideCompareToUseAllTexts", """ + # Override verse comparison to compare all Bible texts instead of favourite texts + """, + False) + + setConfig("translate_api_url", """ + # Translation service API URL + """, + "https://translate.otweb.com") + + setConfig("translate_api_key", """ + # Translation service API key + """, + "") + patFile = os.path.join("secrets", "github", "pat.txt") if os.path.exists(patFile): with open(patFile) as file: diff --git a/uniquebible/util/LanguageUtil.py b/uniquebible/util/LanguageUtil.py index 6e27d8c761..2271b4c046 100644 --- a/uniquebible/util/LanguageUtil.py +++ b/uniquebible/util/LanguageUtil.py @@ -1,19 +1,19 @@ import glob, importlib, locale, sys +import os + from uniquebible import config from os import path from uniquebible.util.Languages import Languages from uniquebible.util.Translator import Translator from uniquebible.util.FileUtil import FileUtil -# config.updateModules("Ibmwatson", True) - class LanguageUtil: @staticmethod def getCodesSupportedLanguages(): - files = sorted(glob.glob("lang/language_*.py")) - return [file[14:-3] for file in files] + files = sorted(os.path.basename(file) for file in glob.glob(config.packageDir + "/lang/language_*.py")) + return [file[9:-3] for file in files] @staticmethod def getNamesSupportedLanguages(): @@ -68,7 +68,7 @@ def compareLanguageFiles(lang1, lang2): @staticmethod def createNewLanguageFile(lang, force=False): - filename = "lang/language_" + lang + ".py" + filename = "uniquebible/lang/language_" + lang + ".py" if not force and path.exists(filename): print(filename + " already exists") else: @@ -86,7 +86,8 @@ def createNewLanguageFile(lang, force=False): if key in ["menu1_app"]: result = text else: - result = translator.translate(text, "en", lang[:2]) + toLanguage = Translator.language_mapping[lang] + result = translator.translate(text, "en", toLanguage) fileObj.write(' "{0}": "{1}",\n'.format(key, result)) fileObj.write("}") fileObj.close() @@ -108,7 +109,8 @@ def updateLanguageFile(lang): count += 1 print(count) text = english[key] - result = translator.translate(text, "en", lang[:2]) + toLanguage = Translator.language_mapping[lang] + result = translator.translate(text, "en", toLanguage) missing += ' "{0}": "{1}",\n'.format(key, result) FileUtil.insertStringIntoFile(filename, missing, -1) print("{0} lines inserted into {1}".format(count, filename)) @@ -125,7 +127,8 @@ def addLanguageStringToAllFiles(key, englishTranslation): if code[:2] == "en": result = englishTranslation else: - result = translator.translate(englishTranslation, "en", "zh-TW" if code == "zh_HANT" else code[:2]) + toLanguage = Translator.language_mapping[code] + result = translator.translate(englishTranslation, "en", toLanguage) data = ' "{0}": "{1}",\n'.format(key, result) FileUtil.insertStringIntoFile(filename, data, -1) print("Inserted '{0}' into {1}".format(result, code)) @@ -141,7 +144,8 @@ def updateLanguageStringToAllFiles(key, englishTranslation): if code[:2] == "en": result = englishTranslation else: - result = translator.translate(englishTranslation, "en", "zh-TW" if code == "zh_HANT" else code[:2]) + toLanguage = Translator.language_mapping[code] + result = translator.translate(englishTranslation, "en", toLanguage) data = ' "{0}": "{1}",\n'.format(key, result) FileUtil.updateStringIntoFile(filename, data) print("updated '{0}' into {1}".format(result, code)) @@ -149,7 +153,6 @@ def updateLanguageStringToAllFiles(key, englishTranslation): @staticmethod def checkLanguageStringToAllFiles(key): codes = LanguageUtil.getCodesSupportedLanguages() - translator = Translator() for code in codes: translation = LanguageUtil.loadTranslation(code) if key in translation.keys(): @@ -230,5 +233,4 @@ def translateWord(text, code): except Exception as e: print("Error executing: " + str(e)) else: - # printCodesSupportedLanguages() - addLanguageStringToAllFiles("githubStatistics", "GitHub Statistics") + addLanguageStringToAllFiles("overrideCompareToUseAllTexts", "Override verse comparison to compare all Bible texts instead of favourite texts") diff --git a/uniquebible/util/TextCommandParser.py b/uniquebible/util/TextCommandParser.py index 15498995e4..1baad353f9 100644 --- a/uniquebible/util/TextCommandParser.py +++ b/uniquebible/util/TextCommandParser.py @@ -33,6 +33,7 @@ from uniquebible.util.Translator import Translator from uniquebible.db.Highlight import Highlight from uniquebible.util.TtsLanguages import TtsLanguages +from uniquebible.util.Languages import Languages from uniquebible.db.BiblesSqlite import MorphologySqlite from uniquebible.db.JournalSqlite import JournalSqlite @@ -726,8 +727,6 @@ def __init__(self, parent): # e.g. DOCX:::test.docx"""), "translate": (self.translateText, """ # [KEYWORD] TRANSLATE - # Feature - Use IBM Watson service to translate entered - # It works only if user install python package 'ibm-watson' # Usage - TRANSLATE:::[text to be translated] # Usage - TRANSLATE:::[source_language_code]-[target_language_code]:::[text to be translated] # Language code of config.userLanguage is used by default if language code is not provided. If config.userLanguage is not defined, "en" is used. @@ -2553,58 +2552,42 @@ def copyText(self, command, source): return ("", "", {}) # TRANSLATE::: - # Translate text using IBM Watson service - # It works only if user entered their own personal credential and store in config.py locally on users' computer. - # The store credentials are only used only for communicating with IBM Watson service with python package 'ibm-watson' - # UBA does not collect any of these data. + # e.g. TRANSLATE:::神, TRANSLATE:::dios, TRANSLATE:::en-zh:::jesus christ def translateText(self, command, source): translator = Translator() - # Use IBM Watson service to translate text - if translator.language_translator is not None: - # unpack command - if command.count(":::") == 0: - fromLanguage = translator.identify(command) - toLanguage = "en" + languages = Languages().code + if command.count(":::") == 0: + text = command + fromLanguage = "auto" + toLanguage = "en" + if config.userLanguage and config.userLanguage in languages.keys(): + toLanguage = languages[config.userLanguage] + else: + language, text = self.splitCommand(command) + if "fr-CA" in language: + language = language.replace("fr-CA", "fr") + if language.count("-") != 1: + if self.parent is not None: + self.parent.displayMessage(config.thisTranslation["message_invalid"]) + else: + fromLanguage, toLanguage = language.split("-") + if "@" in fromLanguage: + fromLanguage = fromLanguage.replace("@", "-") + if "@" in toLanguage: + toLanguage = toLanguage.replace("@", "-") if not fromLanguage in Translator.fromLanguageCodes: fromLanguage = "en" - if config.userLanguage in Translator.toLanguageCodes: - toLanguage = config.userLanguage - text = command + if not toLanguage in Translator.toLanguageCodes: + toLanguage = "en" + translation = translator.translate(text, fromLanguage, toLanguage) + if self.parent is not None: + self.parent.displayMessage(translation) + if config.autoCopyTranslateResult and not config.noQt: + if config.qtLibrary == "pyside6": + from PySide6.QtWidgets import QApplication else: - language, text = self.splitCommand(command) - if "fr-CA" in language: - language = language.replace("fr-CA", "fr@CA") - if "zh-TW" in language: - language = language.replace("zh-TW", "zh@TW") - if language.count("-") != 1: - if self.parent is not None: - self.parent.displayMessage(config.thisTranslation["message_invalid"]) - else: - fromLanguage, toLanguage = language.split("-") - if "@" in fromLanguage: - fromLanguage = fromLanguage.replace("@", "-") - if "@" in toLanguage: - toLanguage = toLanguage.replace("@", "-") - if not fromLanguage in Translator.fromLanguageCodes: - fromLanguage = "en" - if not toLanguage in Translator.toLanguageCodes: - toLanguage = "en" - # translate here - translation = translator.translate(text, fromLanguage, toLanguage) - if self.parent is not None: - self.parent.displayMessage(translation) - if config.autoCopyTranslateResult and not config.noQt: - if config.qtLibrary == "pyside6": - from PySide6.QtWidgets import QApplication - else: - from qtpy.QtWidgets import QApplication - QApplication.clipboard().setText(translation) - else: - if self.parent is not None: - self.parent.displayMessage(config.thisTranslation["ibmWatsonNotEnalbed"]) - if self.parent is not None: - self.parent.openWebsite("https://github.com/eliranwong/UniqueBible/wiki/IBM-Watson-Language-Translator") - return ("", "", {}) + from qtpy.QtWidgets import QApplication + QApplication.clipboard().setText(translation) # This function below is an old way to process TRANSLATE::: command with goolgetrans # However, we found googletrans no longer works with UBA. @@ -2673,7 +2656,10 @@ def getAllFavouriteBibles(self): # COMPARE::: def textCompare(self, command, source): if command.count(":::") == 0: - confirmedTexts = self.getAllFavouriteBibles() + if config.overrideCompareToUseAllTexts: + confirmedTexts = ["ALL"] + else: + confirmedTexts = self.getAllFavouriteBibles() verseList = self.extractAllVerses(command) else: texts, references = self.splitCommand(command) @@ -2689,9 +2675,11 @@ def textCompare(self, command, source): config.mainCssBibleFontStyle = "" texts = confirmedTexts if confirmedTexts == ["ALL"]: - #plainBibleList, formattedBibleList = biblesSqlite.getTwoBibleLists() - #texts = set(plainBibleList + formattedBibleList) - texts = self.getAllFavouriteBibles() + if config.overrideCompareToUseAllTexts: + plainBibleList, formattedBibleList = biblesSqlite.getTwoBibleLists() + texts = set(plainBibleList + formattedBibleList) + else: + texts = self.getAllFavouriteBibles() for text in texts: (fontFile, fontSize, css) = Bible(text).getFontInfo() config.mainCssBibleFontStyle += css diff --git a/uniquebible/util/Translator.py b/uniquebible/util/Translator.py index 2c912b9bf6..c3de1f7627 100644 --- a/uniquebible/util/Translator.py +++ b/uniquebible/util/Translator.py @@ -1,81 +1,45 @@ +import requests + from uniquebible import config class Translator: - fromLanguageCodes = ['ar', 'bg', 'bn', 'bs', 'ca', 'cnr', 'cs', 'cy', 'da', 'de', 'el', 'en', 'es', 'et', 'eu', 'fi', 'fr', 'fr-CA', 'ga', 'gu', 'he', 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'lt', 'lv', 'ml', 'ms', 'mt', 'nb', 'ne', 'nl', 'pl', 'pt', 'ro', 'ru', 'si', 'sk', 'sl', 'sr', 'sv', 'ta', 'te', 'th', 'tr', 'uk', 'ur', 'vi', 'zh', 'zh-TW'] + language_mapping = {"de": "de", "el": "el", "en": "en", "en_GB": "en", "en_US": "en", "es": "es", "fr": "fr", + "hi": "hi", "it": "it", "ja": "ja", "ko": "ko", "ml": "en", "ro": "ro", "ru": "ru", + "zh": "zh", "zh_HANS": "zh", "zt": "zt", "zh_HANT": "zt"} + + fromLanguageCodes = ['ar', 'bg', 'bn', 'bs', 'ca', 'cnr', 'cs', 'cy', 'da', 'de', 'el', 'en', 'es', 'et', 'eu', + 'fi', 'fr', 'fr-CA', 'ga', 'gu', 'he', 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'lt', 'lv', + 'ml', 'ms', 'mt', 'nb', 'ne', 'nl', 'pl', 'pt', 'ro', 'ru', 'si', 'sk', 'sl', 'sr', 'sv', 'ta', + 'te', 'th', 'tr', 'uk', 'ur', 'vi', 'zh', 'zh-TW'] - fromLanguageNames = ['Arabic', 'Bulgarian', 'Bengali', 'Bosnian', 'Catalan', 'Montenegrin', 'Czech', 'Welsh', 'Danish', 'German', 'Greek', 'English', 'Spanish', 'Estonian', 'Basque', 'Finnish', 'French', 'French (Canada)', 'Irish', 'Gujarati', 'Hebrew', 'Hindi', 'Croatian', 'Hungarian', 'Indonesian', 'Italian', 'Japanese', 'Korean', 'Lithuanian', 'Latvian', 'Malayalam', 'Malay', 'Maltese', 'Norwegian Bokmal', 'Nepali', 'Dutch', 'Polish', 'Portuguese', 'Romanian', 'Russian', 'Sinhala', 'Slovakian', 'Slovenian', 'Serbian', 'Swedish', 'Tamil', 'Telugu', 'Thai', 'Turkish', 'Ukrainian', 'Urdu', 'Vietnamese', 'Simplified Chinese', 'Traditional Chinese'] + fromLanguageNames = ['Arabic', 'Bulgarian', 'Bengali', 'Bosnian', 'Catalan', 'Montenegrin', 'Czech', 'Welsh', + 'Danish', 'German', 'Greek', 'English', 'Spanish', 'Estonian', 'Basque', 'Finnish', 'French', + 'French (Canada)', 'Irish', 'Gujarati', 'Hebrew', 'Hindi', 'Croatian', 'Hungarian', + 'Indonesian', 'Italian', 'Japanese', 'Korean', 'Lithuanian', 'Latvian', 'Malayalam', 'Malay', + 'Maltese', 'Norwegian Bokmal', 'Nepali', 'Dutch', 'Polish', 'Portuguese', 'Romanian', + 'Russian', 'Sinhala', 'Slovakian', 'Slovenian', 'Serbian', 'Swedish', 'Tamil', 'Telugu', + 'Thai', 'Turkish', 'Ukrainian', 'Urdu', 'Vietnamese', 'Simplified Chinese', + 'Traditional Chinese'] toLanguageCodes = ['ar', 'bg', 'bn', 'bs', 'ca', 'cnr', 'cs', 'cy', 'da', 'de', 'el', 'en', 'es', 'et', 'eu', 'fi', 'fr', 'fr-CA', 'ga', 'gu', 'he', 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'lt', 'lv', 'ml', 'ms', 'mt', 'nb', 'ne', 'nl', 'pl', 'pt', 'ro', 'ru', 'si', 'sk', 'sl', 'sr', 'sv', 'ta', 'te', 'th', 'tr', 'uk', 'ur', 'vi', 'zh', 'zh-TW'] toLanguageNames = ['Arabic', 'Bulgarian', 'Bengali', 'Bosnian', 'Catalan', 'Montenegrin', 'Czech', 'Welsh', 'Danish', 'German', 'Greek', 'English', 'Spanish', 'Estonian', 'Basque', 'Finnish', 'French', 'French (Canada)', 'Irish', 'Gujarati', 'Hebrew', 'Hindi', 'Croatian', 'Hungarian', 'Indonesian', 'Italian', 'Japanese', 'Korean', 'Lithuanian', 'Latvian', 'Malayalam', 'Malay', 'Maltese', 'Norwegian Bokmal', 'Nepali', 'Dutch', 'Polish', 'Portuguese', 'Romanian', 'Russian', 'Sinhala', 'Slovakian', 'Slovenian', 'Serbian', 'Swedish', 'Tamil', 'Telugu', 'Thai', 'Turkish', 'Ukrainian', 'Urdu', 'Vietnamese', 'Simplified Chinese', 'Traditional Chinese'] - def __init__(self): - self.authenticate() - - def authenticate(self): - try: - if ("Ibmwatson" in config.enabled) and config.myIBMWatsonApikey: - from ibm_watson import LanguageTranslatorV3 - from ibm_cloud_sdk_core.authenticators import IAMAuthenticator - - authenticator = IAMAuthenticator(config.myIBMWatsonApikey) - language_translator = LanguageTranslatorV3( - version=config.myIBMWatsonVersion, - authenticator=authenticator - ) - language_translator.set_service_url(config.myIBMWatsonUrl) - # print(language_translator) - self.language_translator = language_translator - else: - self.language_translator = None - except Exception as ex: - print(ex) - self.language_translator = None - - def getLanguageLists(self): - try: - languages = self.language_translator.list_languages().get_result() - #print(json.dumps(languages, indent=2)) - config.fromLanguageCodes = [] - config.fromLanguageNames = [] - config.toLanguageCodes = [] - config.toLanguageNames = [] - for i in languages["languages"]: - if i["supported_as_source"]: - config.fromLanguageCodes.append(i["language"]) - config.fromLanguageNames.append(i["language_name"]) - if i["supported_as_target"]: - config.toLanguageCodes.append(i["language"]) - config.toLanguageNames.append(i["language_name"]) - #print(config.fromLanguageCodes, config.fromLanguageNames, config.toLanguageCodes, config.toLanguageNames) - except: - self.language_translator = None - - def identify(self, text): - result = self.language_translator.identify(text).get_result() - #print(json.dumps(language, indent=2)) - #print(result["languages"][0]["language"]) - return result["languages"][0]["language"] - - def translate(self, text, fromLanguage=None, toLanguage="en"): - if fromLanguage is None: - fromLanguage = self.identify(text) - if self.language_translator: - translation = self.language_translator.translate( - text=text, - model_id="{0}-{1}".format(fromLanguage, toLanguage)).get_result() - #print(json.dumps(translation, indent=2, ensure_ascii=False)) - #print(translation["translations"][0]["translation"]) - return translation["translations"][0]["translation"] + def translate(self, text, fromLanguage="auto", toLanguage="en"): + toLanguage = self.language_mapping[toLanguage] + url = config.translate_api_url + "/translate" + api_key = config.translate_api_key + payload = {"source": fromLanguage, "target": toLanguage, "q": text, "format": "text", "api_key": api_key} + data = requests.post(url, json=payload).json() + if 'translatedText' in data: + translation = data['translatedText'] + elif 'error' in data: + translation = data['error'] else: - return "" - + translation = '???' + return translation if __name__ == "__main__": - config.updateModules("Ibmwatson", True) translator = Translator() - #translator.identify("这是中文") - #translator.getLanguageLists() - #print(config.fromLanguageCodes, config.fromLanguageNames, config.toLanguageCodes, config.toLanguageNames) - print(translator.translate("test", "en", "zh")) + print(translator.translate("hello", "auto", "zt")) diff --git a/uniquebible/util/checkup.py b/uniquebible/util/checkup.py index 711850cde2..8ed93b58ed 100644 --- a/uniquebible/util/checkup.py +++ b/uniquebible/util/checkup.py @@ -217,14 +217,6 @@ def isBeautifulsoup4Installed(): except: return False -def isIbmWatsonInstalled(): - try: - from ibm_watson import LanguageTranslatorV3 - from ibm_cloud_sdk_core.authenticators import IAMAuthenticator - return True - except: - return False - def isNumpyInstalled(): try: import numpy @@ -737,7 +729,6 @@ def runTerminalMode(): ("langdetect", "Detect Language", isLangdetectInstalled), ("pygithub", "Github access", isPygithubInstalled), ("telnetlib3", "Telnet Client and Server library", isTelnetlib3Installed), - ("ibm-watson", "IBM-Watson Language Translator", isIbmWatsonInstalled), ("translate", "Google Translate", isTranslateInstalled), ("qrcode", "QR Code", isQrCodeInstalled), ("pillow", "QR Code", isPillowInstalled), @@ -794,7 +785,6 @@ def runTerminalMode(): ("pygithub", "Github access", isPygithubInstalled), ("qt-material", "Qt Material Themes", isQtMaterialInstalled), ("telnetlib3", "Telnet Client and Server library", isTelnetlib3Installed), - ("ibm-watson", "IBM-Watson Language Translator", isIbmWatsonInstalled), ("translate", "Google Translate", isTranslateInstalled), ("qrcode", "QR Code", isQrCodeInstalled), ("pillow", "QR Code", isPillowInstalled),