From 7bb0ec1e2e06de0f5669f3a009f9e70d0b0290b2 Mon Sep 17 00:00:00 2001 From: ! Freaku <92618708+Freaku17@users.noreply.github.com> Date: Sat, 29 Aug 2026 16:34:12 +0530 Subject: [PATCH 1/2] CRITICAL FIX: `translate.py` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • If YOU were using `translate.py` before v1.7.40 & later updated. It worked fine. • However, if YOU installed it for the first time after v1.7.40 • Your config would not be saved. • Meaning you were unable to change your language preferences. • Reason is because, Eric (developer of bombsquad). Changed the API; instead of `ba.app.lang` made new `ba.app.locale` • This changed config "keys" into another type. • This commit/update has **FIXED** this issued entirely. • This also fixes those whose config may have been broken. (Only if it was caused by translate.py) Other changes: • Use `ba.CallPartial` instead of `ba.CallStrict` • Import `urllib` submodules • Use `daemon` for threads • If using Translate without internet, prints a warning to connect to internet. • Commit config instantly instead of waiting for bombsquad to save it (which it does automatically periodically) • Exact text_widget translate!!! (Wanted to implement this since start, until now it used `for` loop to find text & replace with translated message. Issue was, if someone spammed same message & you clicked translate on 1 message. It would've translated the first message. Instead of the "exact" message you clicked to translate. This basically fixes it, by directly passing the entire text_widget. Yippie! ) --- plugins/utilities/translate.py | 261 +++++++++++++++++++++++++-------- 1 file changed, 198 insertions(+), 63 deletions(-) diff --git a/plugins/utilities/translate.py b/plugins/utilities/translate.py index 241f7942..6f571140 100644 --- a/plugins/utilities/translate.py +++ b/plugins/utilities/translate.py @@ -9,59 +9,159 @@ import bauiv1 as bui from bauiv1lib.popup import PopupMenu import bauiv1lib.party -import urllib +import urllib.parse +import urllib.request import threading import random show_translate_result = True config = babase.app.config -default_config = {'O Source Trans Lang': 'Auto Detect', 'O Target Trans Lang': babase.app.locale.default_locale, - 'Y Source Trans Lang': 'Auto Detect', 'Y Target Trans Lang': babase.app.locale.default_locale} - -for key in default_config: - if not key in config: - config[key] = default_config[key] - -translate_languages = {'Auto Detect': 'auto', 'Arabic': 'ar', 'Chinese (simplified)': 'zh-CN', 'Chinese (traditional)': 'zh-TW', 'Croatian': 'hr', 'Czech': 'cs', - 'Danish': 'da', 'Dutch': 'nl', 'English': 'en', 'Esperanto': 'eo', - 'Finnish': 'fi', - 'Tagalog': 'tl', 'French': 'fr', 'German': 'de', 'Greek': 'el', - 'Hindi': 'hi', 'Hungarian': 'hu', 'Indonesian': 'id', 'Italian': 'it', - 'Japanese': 'ja', - 'Korean': 'ko', 'Malay': 'ms', 'Malayalam': 'ml', 'Marathi': 'mr', 'Persian': 'fa', 'Polish': 'pl', - 'Portuguese': 'pt', 'Romanian': 'ro', 'Russian': 'ru', 'Serbian': 'sr', - 'Slovak': 'sk', 'Spanish': 'es', 'Swedish': 'sv', 'Tamil': 'ta', - 'Telugu': 'te', - 'Thai': 'th', 'Turkish': 'tr', 'Ukrainian': 'uk', 'Vietnamese': 'vi'} -available_translate_languages = [] -for lang in translate_languages: - available_translate_languages.append(lang) + +# Convert Ballistica Locale -> this mod's language name. +def get_default_translate_language(): + locale = babase.app.locale.default_locale + + # Ballistica 1.7.40 Locale objects have a .value such as 'eng'. + locale_value = getattr(locale, 'value', str(locale)) + + locale_map = { + 'eng': 'English', + 'ara': 'Arabic', + 'zho': 'Chinese (simplified)', + 'hrv': 'Croatian', + 'ces': 'Czech', + 'dan': 'Danish', + 'nld': 'Dutch', + 'fin': 'Finnish', + 'fra': 'French', + 'deu': 'German', + 'ell': 'Greek', + 'hin': 'Hindi', + 'hun': 'Hungarian', + 'ind': 'Indonesian', + 'ita': 'Italian', + 'jpn': 'Japanese', + 'kor': 'Korean', + 'msa': 'Malay', + 'mal': 'Malayalam', + 'mar': 'Marathi', + 'fas': 'Persian', + 'pol': 'Polish', + 'por': 'Portuguese', + 'ron': 'Romanian', + 'rus': 'Russian', + 'srp': 'Serbian', + 'slk': 'Slovak', + 'spa': 'Spanish', + 'swe': 'Swedish', + 'tam': 'Tamil', + 'tel': 'Telugu', + 'tha': 'Thai', + 'tur': 'Turkish', + 'ukr': 'Ukrainian', + 'vie': 'Vietnamese', + 'tgl': 'Tagalog', + } + + return locale_map.get(locale_value, 'English') + + +default_language = get_default_translate_language() + +default_config = { + 'O Source Trans Lang': 'Auto Detect', + 'O Target Trans Lang': default_language, + 'Y Source Trans Lang': 'Auto Detect', + 'Y Target Trans Lang': default_language, +} + +for key, value in default_config.items(): + if key not in config: + config[key] = value + +# Repair configs created with the old Locale-object behavior. +for key in ('O Target Trans Lang', 'Y Target Trans Lang'): + if not isinstance(config[key], str): + config[key] = default_language + + + +# Language names -> Google Translate language codes. +translate_languages = { + 'Auto Detect': 'auto', + 'Arabic': 'ar', + 'Chinese (simplified)': 'zh-CN', + 'Chinese (traditional)': 'zh-TW', + 'Croatian': 'hr', + 'Czech': 'cs', + 'Danish': 'da', + 'Dutch': 'nl', + 'English': 'en', + 'Esperanto': 'eo', + 'Finnish': 'fi', + 'Tagalog': 'tl', + 'French': 'fr', + 'German': 'de', + 'Greek': 'el', + 'Hindi': 'hi', + 'Hungarian': 'hu', + 'Indonesian': 'id', + 'Italian': 'it', + 'Japanese': 'ja', + 'Korean': 'ko', + 'Malay': 'ms', + 'Malayalam': 'ml', + 'Marathi': 'mr', + 'Persian': 'fa', + 'Polish': 'pl', + 'Portuguese': 'pt', + 'Romanian': 'ro', + 'Russian': 'ru', + 'Serbian': 'sr', + 'Slovak': 'sk', + 'Spanish': 'es', + 'Swedish': 'sv', + 'Tamil': 'ta', + 'Telugu': 'te', + 'Thai': 'th', + 'Turkish': 'tr', + 'Ukrainian': 'uk', + 'Vietnamese': 'vi', +} + +available_translate_languages = list(translate_languages.keys()) available_translate_languages.sort() + available_translate_languages.remove('Auto Detect') available_translate_languages.insert(0, 'Auto Detect') + def translate(text, _callback, source='auto', target='en'): - text = urllib.parse.quote(text) - url = f'https://translate.google.com/m?tl={target}&sl={source}&q={text}' - request = urllib.request.Request(url) - data = urllib.request.urlopen(request).read().decode('utf-8') - result = data[(data.find('"result-container">'))+len('"result-container">') - :data.find('