summaryrefslogtreecommitdiffstats
path: root/mytransl
diff options
context:
space:
mode:
authorThomas <tschneider.ac@gmail.com>2022-04-27 15:20:42 +0200
committerThomas <tschneider.ac@gmail.com>2022-04-27 15:20:42 +0200
commit0f855c5ac2dccbc1c1df99b9d5ee17d6293d82df (patch)
tree157224e6752e2facae194034e2e709d23a04fc7d /mytransl
first commit
Diffstat (limited to 'mytransl')
-rw-r--r--mytransl/.gitignore1
-rw-r--r--mytransl/build.gradle34
-rw-r--r--mytransl/src/main/AndroidManifest.xml5
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/MyTransL.java150
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/async/TransAsync.java181
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/client/Client.java171
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/client/HttpsConnectionException.java52
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/client/Results.java29
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/client/TLSSocketFactory.java91
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/translate/Helper.java129
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/translate/Params.java104
-rw-r--r--mytransl/src/main/java/com/github/stom79/mytransl/translate/Translate.java388
12 files changed, 1335 insertions, 0 deletions
diff --git a/mytransl/.gitignore b/mytransl/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/mytransl/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/mytransl/build.gradle b/mytransl/build.gradle
new file mode 100644
index 000000000..6cd6f921a
--- /dev/null
+++ b/mytransl/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'com.android.library'
+
+group = 'com.github.stom79'
+android {
+ compileSdkVersion 31
+
+
+ defaultConfig {
+ minSdkVersion 15
+ targetSdkVersion 31
+ versionCode 7
+ versionName "3.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ buildConfigField("String","VERSION_NAME","\"${defaultConfig.versionName}\"")
+ }
+ debug{
+ buildConfigField("String","VERSION_NAME","\"${defaultConfig.versionName}\"")
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation "com.google.code.gson:gson:2.8.6"
+}
diff --git a/mytransl/src/main/AndroidManifest.xml b/mytransl/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..c3342ad18
--- /dev/null
+++ b/mytransl/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.github.stom79.mytransl">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+</manifest>
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/MyTransL.java b/mytransl/src/main/java/com/github/stom79/mytransl/MyTransL.java
new file mode 100644
index 000000000..4f96bc5c0
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/MyTransL.java
@@ -0,0 +1,150 @@
+package com.github.stom79.mytransl;
+/* 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 com.github.stom79.mytransl.async.TransAsync;
+import com.github.stom79.mytransl.client.Results;
+import com.github.stom79.mytransl.translate.Params;
+
+import java.util.Locale;
+
+
+@SuppressWarnings({"unused", "RedundantSuppression"})
+public class MyTransL {
+
+ public static String TAG = "MyTrans_TAG";
+ private static MyTransL myTransL;
+ private static String libretranslateDomain;
+ private final translatorEngine te;
+ private String yandexAPIKey, deeplAPIKey, systranAPIKey, libreTranslateAPIKey;
+ private int timeout = 30;
+ private boolean obfuscation = false;
+
+ private MyTransL(translatorEngine te) {
+ this.te = te;
+ }
+
+ public static synchronized MyTransL getInstance(translatorEngine te) {
+ if (myTransL == null)
+ myTransL = new MyTransL(te);
+ return myTransL;
+ }
+
+ /**
+ * Allows to get the current locale of the device
+ *
+ * @return locale String
+ */
+ public static String getLibreTranslateUrl() {
+ return "https://" + libretranslateDomain + "/translate?";
+ }
+
+ /**
+ * Allows to get the current locale of the device
+ *
+ * @return locale String
+ */
+ public static String getLocale() {
+ return Locale.getDefault().getLanguage();
+ }
+
+ /**
+ * Timeout in seconds
+ *
+ * @param timeout - int
+ */
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public void setObfuscation(boolean obfuscation) {
+ this.obfuscation = obfuscation;
+ }
+
+ public boolean isObfuscated() {
+ return this.obfuscation;
+ }
+
+ public String getDeeplAPIKey() {
+ return deeplAPIKey;
+ }
+
+ public void setDeeplAPIKey(String deeplAPIKey) {
+ this.deeplAPIKey = deeplAPIKey;
+ }
+
+ public String getYandexAPIKey() {
+ return this.yandexAPIKey;
+ }
+
+ public void setYandexAPIKey(String key) {
+ this.yandexAPIKey = key;
+ }
+
+ public String getSystranAPIKey() {
+ return this.systranAPIKey;
+ }
+
+ public void setSystranAPIKey(String key) {
+ this.systranAPIKey = key;
+ }
+
+ public String getLibretranslateDomain() {
+ return libretranslateDomain;
+ }
+
+ public void setLibretranslateDomain(String libretranslateDomain) {
+ MyTransL.libretranslateDomain = libretranslateDomain;
+ }
+
+ public String getLibreTranslateAPIKey() {
+ return libreTranslateAPIKey;
+ }
+
+ public void setLibreTranslateAPIKey(String libreTranslateAPIKey) {
+ this.libreTranslateAPIKey = libreTranslateAPIKey;
+ }
+
+ /**
+ * Asynchronous call for the translation
+ *
+ * @param content String - Content to translate
+ * @param toLanguage - String the targeted language
+ * @param listener - Callback for the asynchronous call
+ */
+ public void translate(final String content, final String toLanguage, Params params, final Results listener) {
+ new TransAsync(te, content, toLanguage, params, timeout, obfuscation, listener);
+ }
+
+ /**
+ * Asynchronous call for the translation
+ *
+ * @param content String - Content to translate
+ * @param toLanguage - String the targeted language
+ * @param listener - Callback for the asynchronous call
+ */
+ public void translate(final String content, Params.fType format, final String toLanguage, final Results listener) {
+ new TransAsync(te, content, format, toLanguage, timeout, obfuscation, listener);
+ }
+
+ public enum translatorEngine {
+ YANDEX,
+ DEEPL,
+ SYSTRAN,
+ LIBRETRANSLATE
+ }
+
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/async/TransAsync.java b/mytransl/src/main/java/com/github/stom79/mytransl/async/TransAsync.java
new file mode 100644
index 000000000..7c9052199
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/async/TransAsync.java
@@ -0,0 +1,181 @@
+package com.github.stom79.mytransl.async;
+/* 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.Handler;
+import android.os.Looper;
+
+import com.github.stom79.mytransl.MyTransL;
+import com.github.stom79.mytransl.client.Client;
+import com.github.stom79.mytransl.client.HttpsConnectionException;
+import com.github.stom79.mytransl.client.Results;
+import com.github.stom79.mytransl.translate.Helper;
+import com.github.stom79.mytransl.translate.Params;
+import com.github.stom79.mytransl.translate.Translate;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * Created by @stom79 on 27/11/2017.
+ * Asynchronous task to get the translation
+ * Changed 10/01/2021
+ */
+
+public class TransAsync {
+
+ private final Results listener;
+ private final MyTransL.translatorEngine te;
+ private final int timeout;
+ private final Translate translate;
+ private final boolean obfuscation;
+ private final String contentToSend;
+ private final String toLanguage;
+ private final Params params;
+ private Params.fType format;
+ private HttpsConnectionException e;
+
+ public TransAsync(MyTransL.translatorEngine te, String content, Params.fType format, String toLanguage, int timeout, boolean obfuscation, Results results) {
+ this.listener = results;
+ this.te = te;
+ this.timeout = timeout;
+ this.obfuscation = obfuscation;
+ //An instance of the Translate class will be hydrated depending of the translator engine
+ translate = new Translate();
+ translate.setTranslatorEngine(te);
+ translate.setInitialContent(content);
+ translate.setTargetedLanguage(toLanguage);
+ translate.setFormat(format);
+ //Obfuscation if asked
+ if (obfuscation)
+ translate.obfuscate();
+ if (obfuscation) {
+ contentToSend = translate.getObfuscateContent();
+ } else {
+ contentToSend = translate.getInitialContent();
+ }
+ this.toLanguage = toLanguage;
+ this.params = new Params();
+
+ new Thread(() -> {
+ String response = doInBackground();
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+ Runnable myRunnable = () -> onPostExecute(response);
+ mainHandler.post(myRunnable);
+ }).start();
+ }
+
+ public TransAsync(MyTransL.translatorEngine te, String content, String toLanguage, Params params, int timeout, boolean obfuscation, Results results) {
+ this.listener = results;
+ this.te = te;
+ this.timeout = timeout;
+ this.obfuscation = obfuscation;
+ //An instance of the Translate class will be hydrated depending of the translator engine
+ translate = new Translate();
+ translate.setTranslatorEngine(te);
+ translate.setInitialContent(content);
+ translate.setTargetedLanguage(toLanguage);
+ //Obfuscation if asked
+ if (obfuscation) {
+ translate.obfuscate();
+ }
+ if (obfuscation) {
+ contentToSend = translate.getObfuscateContent();
+ } else {
+ contentToSend = translate.getInitialContent();
+ }
+ this.toLanguage = toLanguage;
+ this.params = params;
+ new Thread(() -> {
+ String response = doInBackground();
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+ MyTransL.getLocale();
+ Runnable myRunnable = () -> onPostExecute(response);
+ mainHandler.post(myRunnable);
+ }).start();
+ }
+
+
+ protected String doInBackground() {
+ String str_response = null;
+ //Some parameters
+ try {
+ String url;
+
+ if (te == MyTransL.translatorEngine.YANDEX) {
+ String key = MyTransL.getInstance(te).getYandexAPIKey();
+ url = Helper.getYandexAbsoluteUrl(contentToSend, key, toLanguage);
+ str_response = new Client().get(url, this.timeout);
+ } else if (te == MyTransL.translatorEngine.DEEPL) {
+ String key = MyTransL.getInstance(te).getDeeplAPIKey();
+ url = Helper.getDeeplAbsoluteUrl(contentToSend, toLanguage, params, key);
+ str_response = new Client().get(url, this.timeout);
+ } else if (te == MyTransL.translatorEngine.SYSTRAN) {
+ String key = MyTransL.getInstance(te).getSystranAPIKey();
+ url = Helper.getSystranAbsoluteUrl(contentToSend, key, toLanguage);
+ str_response = new Client().get(url, this.timeout);
+ } else if (te == MyTransL.translatorEngine.LIBRETRANSLATE) {
+ String key = MyTransL.getInstance(te).getLibreTranslateAPIKey();
+ JSONObject params = new JSONObject();
+ try {
+ params.put("source", this.params.getSource_lang());
+ params.put("target", toLanguage);
+ params.put("q", contentToSend);
+ params.put("format", format);
+ if (key != null) {
+ params.put("key", key);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ str_response = new Client().post(MyTransL.getLibreTranslateUrl(), this.timeout, params);
+ }
+ } catch (IOException | NoSuchAlgorithmException | KeyManagementException err) {
+ this.e = new HttpsConnectionException(-1, err.getMessage());
+ err.printStackTrace();
+ } catch (HttpsConnectionException e) {
+ this.e = e;
+ }
+ return str_response;
+ }
+
+ protected void onPostExecute(String result) {
+ if (this.e == null) {
+ //Yandex response
+ if (this.te == MyTransL.translatorEngine.YANDEX) {
+ translate.parseYandexResult(result, listener);
+ } else if (this.te == MyTransL.translatorEngine.DEEPL) {
+ translate.parseDeeplResult(result, listener);
+ } else if (this.te == MyTransL.translatorEngine.SYSTRAN) {
+ translate.parseSystranlResult(result, listener);
+ } else if (this.te == MyTransL.translatorEngine.LIBRETRANSLATE) {
+ translate.parseLibreTranslateResult(result, listener);
+ }
+ //Obfuscation if asked
+ if (obfuscation) {
+ translate.deobfuscate();
+ }
+ listener.onSuccess(translate);
+ } else {
+ listener.onFail(this.e);
+ }
+ }
+
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/client/Client.java b/mytransl/src/main/java/com/github/stom79/mytransl/client/Client.java
new file mode 100644
index 000000000..26826622d
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/client/Client.java
@@ -0,0 +1,171 @@
+package com.github.stom79.mytransl.client;
+/* 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 com.github.stom79.mytransl.BuildConfig;
+
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.HttpsURLConnection;
+
+/**
+ * Created by @stom79 on 27/11/2017.
+ * Manages GET and POST calls
+ * Changed 10/01/2021
+ */
+
+public class Client {
+
+
+ private static final String USER_AGENT = "MyTransL/" + BuildConfig.VERSION_NAME + " Android/" + Build.VERSION.RELEASE;
+
+ public Client() {
+ }
+
+
+ /***
+ * Get call to the translator API
+ * @param urlConnection - String url to query
+ * @param timeout - int a timeout
+ * @return response - String
+ * @throws IOException - Exception
+ * @throws NoSuchAlgorithmException - Exception
+ * @throws KeyManagementException - Exception
+ * @throws HttpsConnectionException - Exception
+ */
+ @SuppressWarnings({"SameParameterValue"})
+ public String get(String urlConnection, int timeout) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
+ URL url = new URL(urlConnection);
+ HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
+ httpsURLConnection.setConnectTimeout(timeout * 1000);
+ httpsURLConnection.setRequestProperty("http.keepAlive", "false");
+ httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
+ httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
+ httpsURLConnection.setRequestMethod("GET");
+ //Read the reply
+ if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
+ Reader in;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), StandardCharsets.UTF_8));
+ } else {
+ //noinspection CharsetObjectCanBeUsed
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int c; (c = in.read()) >= 0; )
+ sb.append((char) c);
+ httpsURLConnection.disconnect();
+ in.close();
+ return sb.toString();
+ } else {
+ Reader in;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), StandardCharsets.UTF_8));
+ } else {
+ //noinspection CharsetObjectCanBeUsed
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
+ }
+ StringBuilder sb = new StringBuilder();// TODO Auto-generated catch block
+ for (int c; (c = in.read()) >= 0; )
+ sb.append((char) c);
+ httpsURLConnection.disconnect();
+ throw new HttpsConnectionException(httpsURLConnection.getResponseCode(), sb.toString());
+ }
+ }
+
+
+ /***
+ * POST call to the translator API
+ * @param urlConnection - String url to query
+ * @param timeout - int a timeout
+ * @param jsonObject - parameters to send (JSON)
+ * @return response - String
+ * @throws IOException - Exception
+ * @throws NoSuchAlgorithmException - Exception
+ * @throws KeyManagementException - Exception
+ * @throws HttpsConnectionException - Exception
+ */
+ @SuppressWarnings({"SameParameterValue", "unused", "RedundantSuppression"})
+ public String post(String urlConnection, int timeout, JSONObject jsonObject) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
+ URL url = new URL(urlConnection);
+ HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
+ byte[] postDataBytes;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
+ } else {
+ //noinspection CharsetObjectCanBeUsed
+ postDataBytes = jsonObject.toString().getBytes("utf-8");
+ }
+ httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
+ httpsURLConnection.setConnectTimeout(timeout * 1000);
+ httpsURLConnection.setDoInput(true);
+ httpsURLConnection.setDoOutput(true);
+ httpsURLConnection.setUseCaches(false);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
+ httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory());
+ httpsURLConnection.setRequestMethod("POST");
+ httpsURLConnection.setRequestProperty("Content-Type", "application/json");
+ httpsURLConnection.setRequestProperty("Accept", "application/json");
+ httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
+ // Send POST output
+ DataOutputStream printout = new DataOutputStream(httpsURLConnection.getOutputStream());
+ httpsURLConnection.getOutputStream().write(postDataBytes);
+ printout.flush();
+ printout.close();
+ //Read the reply
+ if (httpsURLConnection.getResponseCode() >= 200 && httpsURLConnection.getResponseCode() < 400) {
+ Reader in;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), StandardCharsets.UTF_8));
+ } else {
+ //noinspection CharsetObjectCanBeUsed
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), "UTF-8"));
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int c; (c = in.read()) >= 0; )
+ sb.append((char) c);
+ httpsURLConnection.disconnect();
+ in.close();
+ return sb.toString();
+ } else {
+ Reader in;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), StandardCharsets.UTF_8));
+ } else {
+ //noinspection CharsetObjectCanBeUsed
+ in = new BufferedReader(new InputStreamReader(httpsURLConnection.getErrorStream(), "UTF-8"));
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int c; (c = in.read()) >= 0; )
+ sb.append((char) c);
+ httpsURLConnection.disconnect();
+ throw new HttpsConnectionException(httpsURLConnection.getResponseCode(), sb.toString());
+ }
+ }
+
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/client/HttpsConnectionException.java b/mytransl/src/main/java/com/github/stom79/mytransl/client/HttpsConnectionException.java
new file mode 100644
index 000000000..fd4adebfe
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/client/HttpsConnectionException.java
@@ -0,0 +1,52 @@
+package com.github.stom79.mytransl.client;
+/* 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;
+
+/**
+ * Created by @stom79 on 28/11/2017.
+ * Manage custom Exception
+ * Changed 10/01/2021
+ */
+
+@SuppressWarnings({"unused", "RedundantSuppression"})
+public class HttpsConnectionException extends Exception {
+
+ private final int statusCode;
+ private final String message;
+
+ public HttpsConnectionException(int statusCode, String message) {
+ this.statusCode = statusCode;
+ SpannableString spannableString;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ spannableString = new SpannableString(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
+ } else {
+ spannableString = new SpannableString(Html.fromHtml(message));
+ }
+ this.message = spannableString.toString();
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/client/Results.java b/mytransl/src/main/java/com/github/stom79/mytransl/client/Results.java
new file mode 100644
index 000000000..28cfce2b9
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/client/Results.java
@@ -0,0 +1,29 @@
+package com.github.stom79.mytransl.client;
+/* 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 com.github.stom79.mytransl.translate.Translate;
+
+/**
+ * Created by @stom79 on 27/11/2017.
+ * Handler for the results of the translation
+ */
+
+public interface Results {
+ void onSuccess(Translate translate);
+
+ void onFail(HttpsConnectionException httpsConnectionException);
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/client/TLSSocketFactory.java b/mytransl/src/main/java/com/github/stom79/mytransl/client/TLSSocketFactory.java
new file mode 100644
index 000000000..8b9f665a3
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/client/TLSSocketFactory.java
@@ -0,0 +1,91 @@
+package com.github.stom79.mytransl.client;
+/* 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 java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Created by @stom79 on 27/11/2017.
+ * Enable TLS 1.1 & 1.2 on older devices
+ * Changed 10/01/2021
+ */
+
+public class TLSSocketFactory extends SSLSocketFactory {
+
+ private final SSLSocketFactory sSLSocketFactory;
+
+ TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
+
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, null, null);
+ sSLSocketFactory = context.getSocketFactory();
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return sSLSocketFactory.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return sSLSocketFactory.getSupportedCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket());
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket(s, host, port, autoClose));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket(host, port, localHost, localPort));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+ return enableTLSOnSocket(sSLSocketFactory.createSocket(address, port, localAddress, localPort));
+ }
+
+ private Socket enableTLSOnSocket(Socket socket) {
+ if ((socket instanceof SSLSocket)) {
+ ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2",});
+ }
+ return socket;
+ }
+}
diff --git a/mytransl/src/main/java/com/github/stom79/mytransl/translate/Helper.java b/mytransl/src/main/java/com/github/stom79/mytransl/translate/Helper.java
new file mode 100644
index 000000000..86aaac0f6
--- /dev/null
+++ b/mytransl/src/main/java/com/github/stom79/mytransl/translate/Helper.java
@@ -0,0 +1,129 @@
+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 java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Arrays;
+
+/**
+ * Created by Thomas on 28/11/2017.
+ * Some static references
+ * Changed 10/01/2021
+ */
+
+public class Helper {
+
+
+ private static final String YANDEX_BASE_URL = "https://translate.yandex.net/api/v1.5/tr.json/translate?";
+ private static final String DEEPL_BASE_URL = "https://api.deepl.com/v1/translate?";
+ private static final String SYSTRAN_BASE_URL = "https://api-platform.systran.net/translation/text/translate?";
+ private static final String[] deeplAvailableLang = {"EN", "DE", "FR", "ES", "IT", "NL", "PL"};
+
+
+ /***
+ * Returns the URL for Yandex
+ * @param content String - Content to translate
+ * @param apikey String - The Yandex API Key
+ * @param toLanguage String - The targeted locale
+ * @return String - absolute URL for Yandex
+ */
+ public static String getYandexAbsoluteUrl(String content, String apikey, String toLanguage) {
+ String key = "key=" + apikey + "&";
+ toLanguage = toLanguage.replace("null", "");
+ String lang = "lang=" + toLanguage + "&";
+ String text;
+ try {
+ text = "text=" + URLEncoder.encode(content, "utf-8") + "&";
+ } catch (UnsupportedEncodingException e) {
+ text = "text=" + content + "&";
+ e.printStackTrace();
+ }
+ String format = "format=html&";
+ return Helper.YANDEX_BASE_URL + key + lang + format + text;
+ }
+
+
+ /***
+ * Returns the URL for Deepl
+ * @param content String - Content to translate
+ * @param toLanguage String - The targeted locale
+ * @param deepLParams DeepLParams - The deepl paramaters see: https://www.deepl.com/api.html#api_reference_article
+ * @param apikey String - The Deepl API Key
+ * @return String - absolute URL for Deepl
+ */
+ public static String getDeeplAbsoluteUrl(String content, String toLanguage, Params deepLParams, String apikey) {
+ String key = "&auth_key=" + apikey;
+ toLanguage = toLanguage.replace("null", "");
+ String lang = "target_lang=" + toLanguage.toUpperCase();
+ String text;
+ try {
+ text = "text=" + URLEncoder.encode(content, "utf-8") + "&";
+ } catch (UnsupportedEncodingException e) {
+ text = "text=" + content + "&";
+ e.printStackTrace();
+ }
+ String params = "";
+ if (deepLParams.isPreserve_formatting())
+ params += "&a