Add MinT machine translation system support

This commit is contained in:
Thomas 2025-03-27 16:31:12 +01:00
parent f3ae0a6cea
commit 9f57e77d77
8 changed files with 108 additions and 6 deletions

View file

@ -51,6 +51,8 @@ public class TranslateHelper {
et = MyTransL.translatorEngine.LIBRETRANSLATE;
} else if (translator.compareToIgnoreCase("LINGVA") == 0) {
et = MyTransL.translatorEngine.LINGVA;
} else if (translator.compareToIgnoreCase("MINT") == 0) {
et = MyTransL.translatorEngine.MINT;
} else {
et = MyTransL.translatorEngine.DEEPL;
}
@ -68,7 +70,13 @@ public class TranslateHelper {
host = context.getString(R.string.SET_TRANSLATOR_HOST_LINGVA);
}
myTransL.setLingvaDomain(host);
} else {
} else if (translator.compareToIgnoreCase("MINT") == 0) {
String host = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR_DOMAIN_MINT), context.getString(R.string.SET_TRANSLATOR_HOST_MINT));
if (host == null || host.trim().isEmpty()) {
host = context.getString(R.string.SET_TRANSLATOR_HOST_MINT);
}
myTransL.setMintDomain(host);
}else {
String translatorVersion = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR_VERSION), "PRO");
params.setPro(translatorVersion.equals("PRO"));
String apikey = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR_API_KEY), null);

View file

@ -76,6 +76,13 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen
}
}
if (SET_TRANSLATOR != null && !SET_TRANSLATOR.getValue().equals("MINT")) {
if (SET_TRANSLATOR_DOMAIN != null) {
preferenceScreen.removePreferenceRecursively("SET_TRANSLATOR_DOMAIN_MINT");
}
}
SwitchPreferenceCompat SET_DISPLAY_BOOKMARK = findPreference(getString(R.string.SET_DISPLAY_BOOKMARK));
if (SET_DISPLAY_BOOKMARK != null) {
boolean checked = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_BOOKMARK) + MainActivity.currentUserID + MainActivity.currentInstance, true);

View file

@ -857,6 +857,7 @@
<item>Fedilab</item>
<item>Lingva</item>
<item>DeepL</item>
<item>Mint</item>
</string-array>
<string-array name="set_translator_version_values">
<item>Free</item>
@ -867,6 +868,7 @@
<item>FEDILAB</item>
<item>LINGVA</item>
<item>DEEPL</item>
<item>MINT</item>
</string-array>
<string-array name="SET_TRANSLATOR_VERSION_VALUES" translatable="false">
@ -1176,8 +1178,11 @@
<string name="SET_POST_FORMAT" translatable="false">SET_POST_FORMAT</string>
<string name="SET_COMPOSE_LOCAL_ONLY" translatable="false">SET_COMPOSE_LOCAL_ONLY</string>
<string name="SET_TRANSLATOR_HOST_MINT" translatable="false">translate.wmcloud.org</string>
<string name="SET_TRANSLATOR_HOST_LINGVA" translatable="false">lingva.ml</string>
<string name="SET_TRANSLATOR_DOMAIN" translatable="false">SET_TRANSLATOR_DOMAIN</string>
<string name="SET_TRANSLATOR_DOMAIN_MINT" translatable="false">SET_TRANSLATOR_DOMAIN_MINT</string>
<string name="SET_TRANSLATOR" translatable="false">SET_TRANSLATOR</string>
<string name="SET_TRANSLATOR_VERSION" translatable="false">SET_TRANSLATOR_VERSION</string>

View file

@ -164,6 +164,13 @@
app:key="@string/SET_TRANSLATOR_DOMAIN"
app:title="@string/translator_domain"
app:useSimpleSummaryProvider="true" />
<EditTextPreference
app:defaultValue="translate.wmcloud.org"
app:dependency="@string/SET_TRANSLATOR"
app:iconSpaceReserved="false"
app:key="@string/SET_TRANSLATOR_DOMAIN_MINT"
app:title="@string/translator_domain"
app:useSimpleSummaryProvider="true" />
<ListPreference
app:defaultValue="PRO"
app:dialogTitle="@string/version"

View file

@ -29,5 +29,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation("com.github.pemistahl:lingua:1.2.2")
implementation "com.google.code.gson:gson:2.10.1"
}

View file

@ -29,6 +29,7 @@ public class MyTransL {
private static MyTransL myTransL;
private static String libretranslateDomain;
private static String lingvaDomain;
private static String mintDomain;
private translatorEngine te;
private String yandexAPIKey, deeplAPIKey, systranAPIKey, libreTranslateAPIKey, lingvaAPIKey;
private int timeout = 30;
@ -66,6 +67,16 @@ public class MyTransL {
return "https://" + lingvaDomain + "/api/v1/";
}
/**
* Allows to get the current domain for Mint
*
* @return locale String
*/
public static String getMintUrl() {
return "https://" + mintDomain + "/api/translate";
}
/**
* Allows to get the current locale of the device
@ -126,7 +137,7 @@ public class MyTransL {
}
public String getingvaDomain() {
public String getLingvaDomain() {
return lingvaDomain;
}
@ -134,6 +145,15 @@ public class MyTransL {
MyTransL.lingvaDomain = lingvaDomain;
}
public String getMintDomain() {
return mintDomain;
}
public void setMintDomain(String mintDomain) {
MyTransL.mintDomain = mintDomain;
}
public String getLibreTranslateAPIKey() {
return libreTranslateAPIKey;
}
@ -177,7 +197,8 @@ public class MyTransL {
DEEPL,
SYSTRAN,
LIBRETRANSLATE,
LINGVA
LINGVA,
MINT
}
}

View file

@ -17,6 +17,9 @@ package com.github.stom79.mytransl.async;
import android.os.Handler;
import android.os.Looper;
import com.github.pemistahl.lingua.api.Language;
import com.github.pemistahl.lingua.api.LanguageDetector;
import com.github.pemistahl.lingua.api.LanguageDetectorBuilder;
import com.github.stom79.mytransl.MyTransL;
import com.github.stom79.mytransl.client.Client;
import com.github.stom79.mytransl.client.HttpsConnectionException;
@ -30,9 +33,9 @@ import org.json.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.SortedMap;
/**
@ -150,10 +153,31 @@ public class TransAsync {
}
str_response = new Client().post(MyTransL.getLibreTranslateUrl(), this.timeout, params);
} else if (te == MyTransL.translatorEngine.LINGVA) {
String key = MyTransL.getInstance(te).getLibreTranslateAPIKey();
//String contentToSendEncoded = URLEncoder.encode(contentToSend, "UTF-8");
String lingvaURL = MyTransL.getLingvaUrl() + this.params.getSource_lang() + "/" + toLanguage + "/" + URLEncoder.encode(contentToSend, "utf-8");
str_response = new Client().get(lingvaURL, this.timeout);
} else if(te == MyTransL.translatorEngine.MINT) {
JSONObject params = new JSONObject();
LanguageDetector languageDetector = LanguageDetectorBuilder.fromAllLanguages().withMinimumRelativeDistance(0.25).build();
SortedMap<Language, Double> languages = languageDetector.computeLanguageConfidenceValues(contentToSend);
String fromLanguage = null;
if(!languages.isEmpty()) {
Language language = languages.firstKey();
fromLanguage = language.getIsoCode639_1().name();
}
if(fromLanguage == null) {
fromLanguage = "en";
}
try {
params.put("source_language", fromLanguage.toLowerCase());
params.put("target_language", toLanguage);
params.put("content", contentToSend);
params.put("format", "text");
params.put("model", "nllb200-600M");
} catch (JSONException e) {
e.printStackTrace();
}
str_response = new Client().post(MyTransL.getMintUrl(), this.timeout, params);
}
} catch (IOException | NoSuchAlgorithmException | KeyManagementException err) {
this.e = new HttpsConnectionException(-1, err.getMessage());
@ -177,6 +201,8 @@ public class TransAsync {
translate.parseLibreTranslateResult(result, listener);
} else if (this.te == MyTransL.translatorEngine.LINGVA) {
translate.parseLingvaResult(result, listener);
} else if (this.te == MyTransL.translatorEngine.MINT) {
translate.parseMintResult(result, listener);
}
//Obfuscation if asked
if (obfuscation) {

View file

@ -360,6 +360,33 @@ public class Translate {
}
}
/***
* Method to parse result coming from the Mint
* @param response String - Response of the engine translator
* @param listener - Results Listener
*/
public void parseMintResult(String response, Results listener) {
translate.setTranslatorEngine(MyTransL.translatorEngine.MINT);
try {
JSONObject translationJson = new JSONObject(response);
//Retrieves the translated content
String content;
try {
content = URLDecoder.decode(translationJson.getString("translation"), "utf-8");
} catch (UnsupportedEncodingException e) {
content = translationJson.getString("translation");
}
translate.setTranslatedContent(content);
//Retrieves the initial language
translate.setInitialLanguage(initialLanguage);
} catch (JSONException e1) {
e1.printStackTrace();
HttpsConnectionException httpsConnectionException = new HttpsConnectionException(-1, e1.getMessage());
listener.onFail(httpsConnectionException);
}
}
/***
* Method to parse result coming from the Deepl translator
* More about Deepl translate API - https://www.deepl.com/api-reference.html