From 309238fa2b0c4a1a3e42ee4eb7e90d904cd8076f Mon Sep 17 00:00:00 2001 From: stom79 Date: Tue, 31 Oct 2017 18:06:01 +0100 Subject: [PATCH] Fixes an issue --- .../mastodon/activities/TootActivity.java | 18 +- .../mastodon/drawers/StatusListAdapter.java | 9 +- .../gouv/etalab/mastodon/helper/Helper.java | 6 +- .../interfaces/OnTranslatedInterface.java | 5 +- .../translation/GoogleTranslateQuery.java | 12 +- .../mastodon/translation/Translate.java | 164 ++++++++++-------- .../mastodon/translation/YandexQuery.java | 12 +- 7 files changed, 127 insertions(+), 99 deletions(-) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index b3766c257..c877e1718 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -46,6 +46,7 @@ import android.text.Html; import android.text.InputFilter; import android.text.InputType; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -180,7 +181,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc private final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754; private BroadcastReceiver receive_picture; private Account accountReply; - private Translate translate; private View popup_trans; private AlertDialog dialogTrans; @@ -776,7 +776,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc popup_trans = getLayoutInflater().inflate( R.layout.popup_translate, null ); transAlert.setView(popup_trans); - translate = new Translate(getApplicationContext(), code, TootActivity.this).privacy(toot_content.getText().toString(), toot_cw_content.getText().toString()); + new Translate(getApplicationContext(), Helper.targetField.CW, code, TootActivity.this).privacy(toot_cw_content.getText().toString()); + new Translate(getApplicationContext(), Helper.targetField.STATUS, code, TootActivity.this).privacy(toot_content.getText().toString()); transAlert.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); @@ -786,8 +787,10 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc public void onClick(DialogInterface dialog, int whichButton) { TextView toot_trans = popup_trans.findViewById(R.id.toot_trans); TextView cw_trans = popup_trans.findViewById(R.id.cw_trans); - if( toot_trans != null) + if( toot_trans != null) { toot_content.setText(toot_trans.getText().toString()); + toot_content.setSelection(toot_content.getText().length()); + } if( cw_trans != null) toot_cw_content.setText(cw_trans.getText().toString()); dialog.dismiss(); @@ -1672,16 +1675,15 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } @Override - public void onTranslatedTextview(Status status, String translatedResult, Boolean error) { + public void onTranslatedTextview(Translate translate, Status status, String translatedResult, Boolean error) { } @Override - public void onTranslated(Helper.targetField targetField, String translatedResult, Boolean error) { - + public void onTranslated(Translate translate, Helper.targetField targetField, String translatedResult, Boolean error) { try { - String aJsonString = new Translate(getApplicationContext(), translate).replace(translatedResult); - if( popup_trans != null && translate != null) { + String aJsonString = translate.replace(translatedResult); + if( popup_trans != null ) { ProgressBar trans_progress_cw = popup_trans.findViewById(R.id.trans_progress_cw); ProgressBar trans_progress_toot = popup_trans.findViewById(R.id.trans_progress_toot); if( targetField == Helper.targetField.STATUS && trans_progress_toot != null) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java index 5ab914e66..6906be206 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java @@ -118,7 +118,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct private final int DISPLAYED_STATUS = 1; private List pins; private int conversationPosition; - private Translate translate; public StatusListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, String targetedId, boolean isOnWifi, int behaviorWithAttachments, int translator, List statuses){ super(); @@ -911,7 +910,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct @Override public void onClick(View v) { if( !status.isTranslated() ){ - translate = new Translate(context, status,StatusListAdapter.this).privacy(status.getContent(), null); + new Translate(context, status,StatusListAdapter.this).privacy(status.getContent()); }else { status.setTranslationShown(!status.isTranslationShown()); statusListAdapter.notifyDataSetChanged(); @@ -1382,12 +1381,12 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct } @Override - public void onTranslatedTextview(Status status, String translatedResult, Boolean error) { + public void onTranslatedTextview(Translate translate, Status status, String translatedResult, Boolean error) { if( error){ Toast.makeText(context, R.string.toast_error_translate, Toast.LENGTH_LONG).show(); }else { try { - String aJsonString = new Translate(context, translate).replace(translatedResult); + String aJsonString = translate.replace(translatedResult); if( aJsonString != null) { status.setTranslated(true); status.setTranslationShown(true); @@ -1402,7 +1401,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct } @Override - public void onTranslated(Helper.targetField targetField, String content, Boolean error) { + public void onTranslated(Translate translate, Helper.targetField targetField, String content, Boolean error) { } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index 9db726d7d..8a5c8e1a6 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -278,13 +278,15 @@ public class Helper { Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); public static final Pattern hashtagPattern = Pattern.compile("(#[\\w_À-ú-]+)"); - public static final Pattern mentionPattern = Pattern.compile("([\\w]*@[\\w]+)"); + public static final Pattern mentionPattern = Pattern.compile("(@[\\w]+)"); + public static final Pattern mentionOtherInstancePattern = Pattern.compile("(@[\\w]*@[\\w.-]+)"); public static final Pattern blacklistPattern = Pattern.compile("(%[\\w_À-ú-]+)"); //Targeted field after translation public enum targetField{ STATUS, - CW + CW, + SIMPLE } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnTranslatedInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnTranslatedInterface.java index bea00808c..b8cecfa38 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnTranslatedInterface.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnTranslatedInterface.java @@ -16,13 +16,14 @@ package fr.gouv.etalab.mastodon.interfaces; import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.translation.Translate; /** * Created by Thomas on 03/07/2017. * Yandex client API Handler */ public interface OnTranslatedInterface { - void onTranslatedTextview(Status status, String translatedResult, Boolean error); - void onTranslated(Helper.targetField targetField, String content, Boolean error); + void onTranslatedTextview(Translate translate, Status status, String translatedResult, Boolean error); + void onTranslated(Translate translate, Helper.targetField targetField, String content, Boolean error); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/translation/GoogleTranslateQuery.java b/app/src/main/java/fr/gouv/etalab/mastodon/translation/GoogleTranslateQuery.java index 5b2789cb4..2f689b565 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/translation/GoogleTranslateQuery.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/translation/GoogleTranslateQuery.java @@ -35,7 +35,7 @@ class GoogleTranslateQuery { this.listener = listenner; } - void getGoogleTextview(final Status status, final String text, final String toLanguage) throws JSONException { + void getGoogleTextview(final Translate translate, final Status status, final String text, final String toLanguage) throws JSONException { GoogleTranslateClient.get(text, toLanguage, new AsyncHttpResponseHandler() { @Override @@ -45,19 +45,19 @@ class GoogleTranslateQuery { @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { String str_response = new String(response); - listener.onTranslatedTextview(status, str_response,false); + listener.onTranslatedTextview(translate, status, str_response,false); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { - listener.onTranslatedTextview(status, null, true); + listener.onTranslatedTextview(translate, status, null, true); } }); } - void getGoogleTranslation(final Helper.targetField target, final String text, final String toLanguage) throws JSONException { + void getGoogleTranslation(final Translate translate, final Helper.targetField target, final String text, final String toLanguage) throws JSONException { GoogleTranslateClient.get(text, toLanguage, new AsyncHttpResponseHandler() { @Override @@ -67,12 +67,12 @@ class GoogleTranslateQuery { @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { String str_response = new String(response); - listener.onTranslated(target, str_response,false); + listener.onTranslated(translate, target, str_response,false); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { - listener.onTranslated(target, null, true); + listener.onTranslated(translate, target, null, true); } }); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/translation/Translate.java b/app/src/main/java/fr/gouv/etalab/mastodon/translation/Translate.java index 08668d42d..d7c22d73d 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/translation/Translate.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/translation/Translate.java @@ -48,39 +48,43 @@ public class Translate { private HashMap urlConversion; private HashMap tagConversion; + private HashMap mentionConversionOtherInstance; private HashMap mentionConversion; private HashMap blacklistConversion; - private Translate translate; + + private android.content.Context context; private OnTranslatedInterface listener; private Status status; private String targetedLanguage; + private Helper.targetField targetField; public Translate(android.content.Context context, Status status, OnTranslatedInterface onTranslatedInterface){ - this.translate = this; this.context = context; this.listener = onTranslatedInterface; this.status = status; targetedLanguage = currentLocale; + this.targetField = Helper.targetField.SIMPLE; } - public Translate(android.content.Context context, String targetedLanguage, OnTranslatedInterface onTranslatedInterface){ - this.translate = this; + public Translate(android.content.Context context, Helper.targetField targetField, String targetedLanguage, OnTranslatedInterface onTranslatedInterface){ this.context = context; this.listener = onTranslatedInterface; this.targetedLanguage = targetedLanguage; + this.targetField = targetField; } - public Translate(android.content.Context context, Translate translate){ - this.context = context; - this.translate = translate; - } - public Translate privacy (String content, String cw){ - tagConversion = new HashMap<>(); - mentionConversion = new HashMap<>(); - urlConversion = new HashMap<>(); - blacklistConversion = new HashMap<>(); + /*** + * Removes sensitive elements from translation, ie: links, tags, mentions, and blacklisted words starting with % + * @param content String + */ + public void privacy (String content){ + this.tagConversion = new HashMap<>(); + this.mentionConversion = new HashMap<>(); + this.urlConversion = new HashMap<>(); + this.blacklistConversion = new HashMap<>(); + this.mentionConversionOtherInstance = new HashMap<>(); try { SpannableString spannableString; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) @@ -89,41 +93,17 @@ public class Translate { //noinspection deprecation spannableString = new SpannableString(Html.fromHtml(content)); String text = spannableString.toString(); - tagConversion = new HashMap<>(); - mentionConversion = new HashMap<>(); - urlConversion = new HashMap<>(); - blacklistConversion = new HashMap<>(); Matcher matcher; - //Extracts urls - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) - matcher = Patterns.WEB_URL.matcher(spannableString.toString()); - else - matcher = Helper.urlPattern.matcher(spannableString.toString()); + int i = 0; - //replaces them by a kind of variable which shouldn't be translated ie: __u0__, __u1__, etc. + //Same for mentions for other instances with __o0__, __o1__, etc. + matcher = Helper.mentionOtherInstancePattern.matcher(text); while (matcher.find()){ - String key = "__u" + String.valueOf(i) + "__"; + String key = "__o" + String.valueOf(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())); - } + this.mentionConversionOtherInstance.put(key, value); if( value != null) { - urlConversion.put(key, value); - text = text.replace(value, key); - } - i++; - } - i = 0; - //Same for tags with __t0__, __t1__, etc. - matcher = Helper.hashtagPattern.matcher(text); - while (matcher.find()){ - String key = "__t" + String.valueOf(i) + "__"; - String value = matcher.group(0); - tagConversion.put(key, value); - if( value != null) { - tagConversion.put(key, value); + this.mentionConversionOtherInstance.put(key, value); text = text.replace(value, key); } i++; @@ -134,9 +114,43 @@ public class Translate { while (matcher.find()){ String key = "__m" + String.valueOf(i) + "__"; String value = matcher.group(0); - mentionConversion.put(key, value); + this.mentionConversion.put(key, value); if( value != null) { - mentionConversion.put(key, value); + this.mentionConversion.put(key, value); + text = text.replace(value, key); + } + i++; + } + //Extracts urls + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) + matcher = Patterns.WEB_URL.matcher(spannableString.toString()); + else + matcher = Helper.urlPattern.matcher(spannableString.toString()); + i = 0; + //replaces them by a kind of variable which shouldn't be translated ie: __u0__, __u1__, etc. + while (matcher.find()){ + String key = "__u" + String.valueOf(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 = Helper.hashtagPattern.matcher(text); + while (matcher.find()){ + String key = "__t" + String.valueOf(i) + "__"; + String value = matcher.group(0); + this.tagConversion.put(key, value); + if( value != null) { + this.tagConversion.put(key, value); text = text.replace(value, key); } i++; @@ -147,9 +161,9 @@ public class Translate { while (matcher.find()){ String key = "__b" + String.valueOf(i) + "__"; String value = matcher.group(0); - blacklistConversion.put(key, value); + this.blacklistConversion.put(key, value); if( value != null) { - blacklistConversion.put(key, value); + this.blacklistConversion.put(key, value); text = text.replace(value, key); } i++; @@ -159,77 +173,87 @@ public class Translate { if( status == null) { if (translator == Helper.TRANS_YANDEX) { if (content != null) - new YandexQuery(this.listener).getYandexTranslation(Helper.targetField.STATUS, content, targetedLanguage); - if (cw != null) - new YandexQuery(this.listener).getYandexTranslation(Helper.targetField.CW, content, targetedLanguage); + new YandexQuery(this.listener).getYandexTranslation(this, Helper.targetField.STATUS, content, this.targetedLanguage); + if (targetField == Helper.targetField.CW) + new YandexQuery(this.listener).getYandexTranslation(this, Helper.targetField.CW, content, this.targetedLanguage); } else { - while (text.charAt(text.length() - 1) == '\n' && text.length() > 0) + while (text.length() > 0 && text.charAt(text.length() - 1) == '\n' && text.length() > 0) text = text.substring(0, text.length() - 1); text += "."; if (content != null) - new GoogleTranslateQuery(this.listener).getGoogleTranslation(Helper.targetField.STATUS, text, targetedLanguage); - if (cw != null) - new GoogleTranslateQuery(this.listener).getGoogleTranslation(Helper.targetField.CW, text, targetedLanguage); + new GoogleTranslateQuery(this.listener).getGoogleTranslation(this, Helper.targetField.STATUS, text, this.targetedLanguage); + if (targetField == Helper.targetField.CW) + new GoogleTranslateQuery(this.listener).getGoogleTranslation(this, Helper.targetField.CW, content, this.targetedLanguage); } }else { if (translator == Helper.TRANS_YANDEX) { - new YandexQuery(this.listener).getYandexTextview(status, content, targetedLanguage); + new YandexQuery(this.listener).getYandexTextview(this, this.status, content, this.targetedLanguage); } else { - while (text.charAt(text.length() - 1) == '\n' && text.length() > 0) + while (text.length() > 0 && text.charAt(text.length() - 1) == '\n' && text.length() > 0) text = text.substring(0, text.length() - 1); text += "."; - new GoogleTranslateQuery(this.listener).getGoogleTextview(status, text, targetedLanguage); + new GoogleTranslateQuery(this.listener).getGoogleTextview(this, this.status, text, this.targetedLanguage); } } } catch (JSONException e) { Toast.makeText(context, R.string.toast_error_translate, Toast.LENGTH_LONG).show(); } - - return translate; } - + /** + * Replaces sensitive elements once translated by their original values + * @param translatedResult String + * @return String "decrypted content" + */ public String replace(String translatedResult){ final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); int translator = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX); String aJsonString = null; try { - if (translator == Helper.TRANS_YANDEX) aJsonString = yandexTranslateToText(translatedResult); else if( translator == Helper.TRANS_GOOGLE) aJsonString = googleTranslateToText(translatedResult); if( aJsonString == null) return null; - if( urlConversion != null) { - Iterator itU = urlConversion.entrySet().iterator(); + + if( this.urlConversion != null) { + Iterator itU = this.urlConversion.entrySet().iterator(); while (itU.hasNext()) { Map.Entry pair = (Map.Entry) itU.next(); aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString()); itU.remove(); } } - if( tagConversion != null) { - Iterator itT = tagConversion.entrySet().iterator(); + if( this.tagConversion != null) { + Iterator itT = this.tagConversion.entrySet().iterator(); while (itT.hasNext()) { Map.Entry pair = (Map.Entry) itT.next(); aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString()); itT.remove(); } } - if( mentionConversion != null) { - Iterator itM = mentionConversion.entrySet().iterator(); + if( this.mentionConversionOtherInstance != null) { + Iterator itM = this.mentionConversionOtherInstance.entrySet().iterator(); while (itM.hasNext()) { Map.Entry pair = (Map.Entry) itM.next(); aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString()); itM.remove(); } } - if( blacklistConversion != null) { - Iterator itB = blacklistConversion.entrySet().iterator(); + if( this.mentionConversion != null) { + Iterator itM = this.mentionConversion.entrySet().iterator(); + while (itM.hasNext()) { + Map.Entry pair = (Map.Entry) itM.next(); + aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString()); + itM.remove(); + } + } + if( this.blacklistConversion != null) { + Iterator itB = this.blacklistConversion.entrySet().iterator(); while (itB.hasNext()) { Map.Entry pair = (Map.Entry) itB.next(); - aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString()); + aJsonString = aJsonString.replace(pair.getKey().toString(), pair.getValue().toString().substring(1)); itB.remove(); } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/translation/YandexQuery.java b/app/src/main/java/fr/gouv/etalab/mastodon/translation/YandexQuery.java index d0dc2fdb1..8d6c597a1 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/translation/YandexQuery.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/translation/YandexQuery.java @@ -33,7 +33,7 @@ class YandexQuery { this.listener = listenner; } - void getYandexTextview(final Status status, final String text, final String toLanguage) throws JSONException { + void getYandexTextview(final Translate translate, final Status status, final String text, final String toLanguage) throws JSONException { YandexClient.get(text, toLanguage, new AsyncHttpResponseHandler() { @Override @@ -44,17 +44,17 @@ class YandexQuery { @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { String str_response = new String(response); - listener.onTranslatedTextview(status, str_response,false); + listener.onTranslatedTextview(translate, status, str_response,false); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { - listener.onTranslatedTextview(status, null, true); + listener.onTranslatedTextview(translate, status, null, true); } }); } - void getYandexTranslation(final Helper.targetField target, final String content, final String toLanguage) throws JSONException { + void getYandexTranslation(final Translate translate, final Helper.targetField target, final String content, final String toLanguage) throws JSONException { YandexClient.get(content, toLanguage, new AsyncHttpResponseHandler() { @Override @@ -65,12 +65,12 @@ class YandexQuery { @Override public void onSuccess(int statusCode, Header[] headers, byte[] response) { String str_response = new String(response); - listener.onTranslated(target, str_response,false); + listener.onTranslated(translate, target, str_response,false); } @Override public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) { - listener.onTranslated(target, null, true); + listener.onTranslated(translate, target, null, true); } });