summaryrefslogtreecommitdiffstats
path: root/mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java
diff options
context:
space:
mode:
Diffstat (limited to 'mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java')
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java388
1 files changed, 388 insertions, 0 deletions
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java b/mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java
new file mode 100644
index 000000000..6bccabff0
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java
@@ -0,0 +1,388 @@
+package com.github.stom79.mytransl.translate;
+/* Copyright 2017 Thomas Schneider
+ *
+ * This file is a part of MyTransL
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * MyTransL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with MyTransL; if not,
+ * see <http://www.gnu.org/licenses>. */
+
+
+import android.os.Build;
+import android.text.Html;
+import android.text.SpannableString;
+import android.util.Patterns;
+
+import com.github.stom79.mytransl.MyTransL;
+import com.github.stom79.mytransl.client.HttpsConnectionException;
+import com.github.stom79.mytransl.client.Results;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * Created by @stom79 on 28/11/2017.
+ * The class which manages the replies
+ * Changed 10/01/2021
+ */
+
+@SuppressWarnings({"unused", "RedundantSuppression"})
+public class Translate {
+
+ private static final Pattern hashtagPattern = Pattern.compile("(#[\\w_À-ú-]+)");
+ private static final Pattern mentionPattern = Pattern.compile("(@[\\w]+)");
+ private static final Pattern mentionOtherInstancePattern = Pattern.compile("(@[\\w]*@[\\w.-]+)");
+ private final Translate translate;
+ private String targetedLanguage;
+ private String initialLanguage;
+ private MyTransL.translatorEngine translatorEngine;
+ private String initialContent;
+ private String obfuscateContent;
+ private String translatedContent;
+ private Params.fType format;
+ private HashMap<String, String> tagConversion, mentionConversion, urlConversion, mailConversion;
+
+ public Translate() {
+ this.translate = this;
+ }
+
+ private static String replacer(StringBuffer outBuffer) throws UnsupportedEncodingException {
+ String data = outBuffer.toString();
+ data = data.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
+ data = data.replaceAll("\\+", "%2B");
+ data = URLDecoder.decode(data, "utf-8");
+ return data;
+ }
+
+ public Params.fType getFormat() {
+ return format;
+ }
+
+ public void setFormat(Params.fType format) {
+ this.format = format;
+ }
+
+ public String getTargetedLanguage() {
+ return targetedLanguage;
+ }
+
+ public void setTargetedLanguage(String targetedLanguage) {
+ this.targetedLanguage = targetedLanguage;
+ }
+
+ public String getInitialLanguage() {
+ return initialLanguage;
+ }
+
+ private void setInitialLanguage(String initialLanguage) {
+ this.initialLanguage = initialLanguage;
+ }
+
+ public String getInitialContent() {
+ return initialContent;
+ }
+
+ public void setInitialContent(String initialContent) {
+ this.initialContent = initialContent;
+ }
+
+ public String getTranslatedContent() {
+ return translatedContent;
+ }
+
+ private void setTranslatedContent(String translatedContent) {
+ this.translatedContent = translatedContent;
+ }
+
+ public MyTransL.translatorEngine getTranslatorEngine() {
+ return translatorEngine;
+ }
+
+ public void setTranslatorEngine(MyTransL.translatorEngine translatorEngine) {
+ this.translatorEngine = translatorEngine;
+ }
+
+ public HashMap<String, String> getTagConversion() {
+ return this.tagConversion;
+ }
+
+ public HashMap<String, String> getMentionConversion() {
+ return this.mentionConversion;
+ }
+
+ public HashMap<String, String> getUrlConversion() {
+ return this.urlConversion;
+ }
+
+ public HashMap<String, String> getMailConversion() {
+ return this.mailConversion;
+ }
+
+ public String getObfuscateContent() {
+ return this.obfuscateContent;
+ }
+
+ public void obfuscate() {
+
+ this.tagConversion = new HashMap<>();
+ this.mentionConversion = new HashMap<>();
+ this.urlConversion = new HashMap<>();
+ this.mailConversion = new HashMap<>();
+ SpannableString spannableString;
+ String content = this.translate.getInitialContent();
+ content = content.replaceAll("\n", "<br/>");
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ spannableString = new SpannableString(Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY));
+ } else {
+ spannableString = new SpannableString(Html.fromHtml(content));
+ }
+ String text = spannableString.toString();
+ Matcher matcher;
+
+ //Mentions with instances (@name@domain) will be replaced by __o0__, __o1__, etc.
+ int i = 0;
+ matcher = mentionOtherInstancePattern.matcher(text);
+ while (matcher.find()) {
+ String key = "$o" + i;
+ String value = matcher.group(0);
+ if (value != null) {
+ this.mentionConversion.put(key, value);
+ text = text.replace(value, key);
+ }
+ i++;
+ }
+ //Extracts Emails
+ matcher = Patterns.EMAIL_ADDRESS.matcher(text);
+ i = 0;
+ //replaces them by a kind of variable which shouldn't be translated ie: __e0__, __e1__, etc.
+ while (matcher.find()) {
+ String key = "$e" + i;
+ String value = matcher.group(0);
+ if (value != null) {
+ this.mailConversion.put(key, value);
+ text = text.replace(value, key);
+ }
+ i++;
+ }
+
+ //Same for mentions with __m0__, __m1__, etc.
+ i = 0;
+ matcher = mentionPattern.matcher(text);
+ while (matcher.find()) {
+ String key = "$m" + i;
+ String value = matcher.group(0);
+ if (value != null) {
+ this.mentionConversion.put(key, value);
+ text = text.replace(value, key);
+ }
+ i++;
+ }
+
+ //Extracts urls
+ matcher = Patterns.WEB_URL.matcher(text);
+ i = 0;
+ //replaces them by a kind of variable which shouldn't be translated ie: __u0__, __u1__, etc.
+ while (matcher.find()) {
+ String key = "$u" + i;
+ String value = matcher.group(0);
+ int end = matcher.end();
+ if (spannableString.length() > end && spannableString.charAt(end) == '/') {
+ text = spannableString.toString().substring(0, end).
+ concat(spannableString.toString().substring(end + 1, spannableString.length()));
+ }
+ if (value != null) {
+ this.urlConversion.put(key, value);
+ text = text.replace(value, key);
+ }
+ i++;
+ }
+ i = 0;
+ //Same for tags with __t0__, __t1__, etc.
+ matcher = hashtagPattern.matcher(text);
+ while (matcher.find()) {
+ String key = "$t" + i;
+ String value = matcher.group(0);
+ if (value != null) {
+ this.tagConversion.put(key, value);
+ text = text.replace(value, key);
+ }
+ i++;
+ }
+ this.obfuscateContent = text;
+ }
+
+ public void deobfuscate() {
+ String aJsonString = null;
+ try {
+ if (translatorEngine == MyTransL.translatorEngine.YANDEX)
+ aJsonString = yandexTranslateToText(translatedContent);
+ else
+ aJsonString = translatedContent;
+ if (aJsonString != null) {
+ if (this.urlConversion != null) {
+ Iterator<Map.Entry<String, String>> itU = this.urlConversion.entrySet().iterator();
+ while (itU.hasNext()) {
+ Map.Entry<String, String> pair = itU.next();
+ aJsonString = aJsonString.replace(pair.getKey(), pair.getValue());
+ itU.remove();
+ }
+ }
+ if (this.tagConversion != null) {
+ Iterator<Map.Entry<String, String>> itT = this.tagConversion.entrySet().iterator();
+ while (itT.hasNext()) {
+ Map.Entry<String, String> pair = itT.next();
+ aJsonString = aJsonString.replace(pair.getKey(), pair.getValue());
+ itT.remove();
+ }
+ }
+ if (this.mentionConversion != null) {
+ Iterator<Map.Entry<String, String>> itM = this.mentionConversion.entrySet().iterator();
+ while (itM.hasNext()) {
+ Map.Entry<String, String> pair = itM.next();
+ aJsonString = aJsonString.replace(pair.getKey(), pair.getValue());
+ itM.remove();
+ }
+ }
+ if (this.mailConversion != null) {
+ Iterator<Map.Entry<String, String>> itE = this.mailConversion.entrySet().iterator();
+ while (itE.hasNext()) {
+ Map.Entry<String, String> pair = itE.next();
+ aJsonString = aJsonString.replace(pair.getKey(), pair.getValue());
+ itE.remove();
+ }
+ }
+ }
+ } catch (UnsupportedEncodingException | IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ if (aJsonString != null)
+ translatedContent = aJsonString;
+ }
+
+ private String yandexTranslateToText(String text) throws UnsupportedEncodingException {
+ if (text == null)
+ return null;
+ /* The one instance where I've seen this happen,
+ the special tag was originally a hashtag ("__t1__"),
+ that Yandex decided to change to a "__q1 - __".
+ */
+ text = text.replaceAll("__q(\\d+) - __", "\\$t$1");
+ // Noticed this in the very same toot
+ text = text.replace("&amp;", "&");
+ text = replacer(new StringBuffer(text));
+ return text;
+ }
+
+ /***
+ * Method to parse result coming from the Yandex translator
+ * More about Yandex translate API - https://tech.yandex.com/translate/
+ * @param response String - Response of the engine translator
+ * @param listener - Results Listener
+ */
+ public void parseYandexResult(String response, Results listener) {
+ translate.setTranslatorEngine(MyTransL.translatorEngine.YANDEX);
+ try {
+ JSONObject translationJson = new JSONObject(response);
+ //Retrieves the translated content
+ JSONArray aJsonArray = translationJson.getJSONArray("text");
+ String aJsonString = aJsonArray.get(0).toString();
+ aJsonString = aJsonString.replace("&amp;", "&");
+ aJsonString = replacer(new StringBuffer(aJsonString));
+ translate.setTranslatedContent(aJsonString);
+ //Retrieves the translation direction
+ String translationDirection = translationJson.get("lang").toString();
+ String[] td = translationDirection.split("-");
+ translate.setInitialLanguage(td[0]);
+ translate.setTargetedLanguage(td[1]);
+ } catch (JSONException | UnsupportedEncodingException e1) {
+ 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
+ * @param response String - Response of the engine translator
+ * @param listener - Results Listener
+ */
+ public void parseLibreTranslateResult(String response, Results listener) {
+ translate.setTranslatorEngine(MyTransL.translatorEngine.DEEPL);
+ try {
+ JSONObject translationJson = new JSONObject(response);
+ //Retrieves the translated content
+ translate.setTranslatedContent(translationJson.getString("translatedText"));
+ //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
+ * @param response String - Response of the engine translator
+ * @param listener - Results Listener
+ */
+ public void parseDeeplResult(String response, Results listener) {
+ translate.setTranslatorEngine(MyTransL.translatorEngine.DEEPL);
+ try {
+ JSONObject translationJson = new JSONObject(response);
+ //Retrieves the translated content
+ JSONArray aJsonArray = translationJson.getJSONArray("translations");
+ JSONObject aJsonString = aJsonArray.getJSONObject(0);
+ translate.setTranslatedContent(aJsonString.getString("text"));
+ //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 Systrans translator
+ * More about Systran translate API - https://platform.systran.net/reference/translation
+ * @param response String - Response of the engine translator
+ * @param listener - Results Listener
+ */
+ public void parseSystranlResult(String response, Results listener) {
+ translate.setTranslatorEngine(MyTransL.translatorEngine.SYSTRAN);
+ try {
+ JSONObject translationJson = new JSONObject(response);
+ //Retrieves the translated content
+ JSONArray aJsonArray = translationJson.getJSONArray("outputs");
+ JSONObject aJsonString = aJsonArray.getJSONObject(0);
+ translate.setTranslatedContent(aJsonString.getString("output"));
+ //Retrieves the initial language
+ translate.setInitialLanguage(initialLanguage);
+ } catch (JSONException e1) {
+ e1.printStackTrace();
+ HttpsConnectionException httpsConnectionException = new HttpsConnectionException(-1, e1.getMessage());
+ listener.onFail(httpsConnectionException);
+ }
+ }
+}