Removes lib & keeps on improvements

This commit is contained in:
stom79 2017-11-18 12:22:41 +01:00
parent f199446c70
commit e89f55ea5e
13 changed files with 238 additions and 443 deletions

View File

@ -36,8 +36,6 @@ dependencies {
implementation 'com.android.support:design:27.0.1' implementation 'com.android.support:design:27.0.1'
implementation 'com.android.support:support-v4:27.0.1' implementation 'com.android.support:support-v4:27.0.1'
implementation 'com.android.support:recyclerview-v7:27.0.1' implementation 'com.android.support:recyclerview-v7:27.0.1'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.evernote:android-job:1.2.0' implementation 'com.evernote:android-job:1.2.0'
implementation 'com.github.chrisbanes:PhotoView:2.0.0' implementation 'com.github.chrisbanes:PhotoView:2.0.0'

View File

@ -40,6 +40,7 @@ import org.json.JSONObject;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;

View File

@ -40,13 +40,9 @@ import android.widget.ImageView;
import android.widget.MediaController; import android.widget.MediaController;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView; import android.widget.VideoView;
import com.github.chrisbanes.photoview.OnMatrixChangedListener; import com.github.chrisbanes.photoview.OnMatrixChangedListener;
import com.github.chrisbanes.photoview.PhotoView; import com.github.chrisbanes.photoview.PhotoView;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.FileAsyncHttpResponseHandler;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
@ -54,24 +50,18 @@ import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import java.io.File; import java.io.File;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList; import java.util.ArrayList;
import cz.msebera.android.httpclient.Header;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.client.Entities.Attachment; import fr.gouv.etalab.mastodon.client.Entities.Attachment;
import fr.gouv.etalab.mastodon.client.MastalabSSLSocketFactory; import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.HttpsConnection;
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnDownloadInterface;
import static fr.gouv.etalab.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE; import static fr.gouv.etalab.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE;
import static fr.gouv.etalab.mastodon.helper.Helper.USER_AGENT;
import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
@ -80,7 +70,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
* Media Activity * Media Activity
*/ */
public class MediaActivity extends AppCompatActivity { public class MediaActivity extends AppCompatActivity implements OnDownloadInterface {
private RelativeLayout loader; private RelativeLayout loader;
@ -103,6 +93,8 @@ public class MediaActivity extends AppCompatActivity {
private boolean canSwipe; private boolean canSwipe;
private enum actionSwipe{ private enum actionSwipe{
RIGHT_TO_LEFT, RIGHT_TO_LEFT,
LEFT_TO_RIGHT, LEFT_TO_RIGHT,
@ -326,9 +318,10 @@ public class MediaActivity extends AppCompatActivity {
url = attachment.getRemote_url(); url = attachment.getRemote_url();
attachment.setType(type); attachment.setType(type);
} }
final String finalUrl = url;
switch (type){ switch (type){
case "image": case "image":
final String finalUrl = url;
imageLoader.displayImage(url, imageView, options, new SimpleImageLoadingListener(){ imageLoader.displayImage(url, imageView, options, new SimpleImageLoadingListener(){
@Override @Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
@ -348,81 +341,29 @@ public class MediaActivity extends AppCompatActivity {
case "video": case "video":
case "gifv": case "gifv":
try { File file = new File(getCacheDir() + "/" + Helper.md5(url)+".mp4");
File file = new File(getCacheDir() + "/" + Helper.md5(url)+".mp4"); if(file.exists()) {
if(file.exists()) { Uri uri = Uri.parse(file.getAbsolutePath());
Uri uri = Uri.parse(file.getAbsolutePath()); videoView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.VISIBLE); videoView.setVideoURI(uri);
videoView.setVideoURI(uri); videoView.start();
videoView.start(); MediaController mc = new MediaController(MediaActivity.this);
MediaController mc = new MediaController(MediaActivity.this); videoView.setMediaController(mc);
videoView.setMediaController(mc); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override
@Override public void onPrepared(MediaPlayer mp) {
public void onPrepared(MediaPlayer mp) { loader.setVisibility(View.GONE);
loader.setVisibility(View.GONE); mp.start();
mp.start(); mp.setLooping(true);
mp.setLooping(true); }
} });
}); videoView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.VISIBLE); fileVideo = file;
fileVideo = file; downloadedImage = null;
downloadedImage = null; }else{
}else{ progress.setText("0 %");
progress.setText("0 %"); progress.setVisibility(View.VISIBLE);
progress.setVisibility(View.VISIBLE); new HttpsConnection(getApplicationContext()).download(finalUrl, MediaActivity.this );
AsyncHttpClient client = new AsyncHttpClient();
MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.setUserAgent(USER_AGENT);
client.setConnectTimeout(120000); //120s timeout
final String finalUrl1 = url;
client.get(url, null, new FileAsyncHttpResponseHandler(MediaActivity.this) {
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, File file) {
progress.setVisibility(View.GONE);
}
@Override
public void onProgress(long bytesWritten, long totalSize) {
long progressPercentage = (long)100*bytesWritten/totalSize;
progress.setText(String.format("%s%%",String.valueOf(progressPercentage)));
}
@Override
public void onSuccess(int statusCode, Header[] headers, File response) {
File dir = getCacheDir();
File from = new File(dir, response.getName());
File to = new File(dir, Helper.md5(finalUrl1) + ".mp4");
if (from.exists())
//noinspection ResultOfMethodCallIgnored
from.renameTo(to);
fileVideo = to;
downloadedImage = null;
progress.setVisibility(View.GONE);
Uri uri = Uri.parse(to.getAbsolutePath());
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(uri);
videoView.start();
MediaController mc = new MediaController(MediaActivity.this);
videoView.setMediaController(mc);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
loader.setVisibility(View.GONE);
mp.start();
mp.setLooping(true);
}
});
videoView.setVisibility(View.VISIBLE);
}
});
}
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
progress.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(),R.string.toast_error,Toast.LENGTH_LONG).show();
} }
break; break;
} }
@ -440,5 +381,28 @@ public class MediaActivity extends AppCompatActivity {
} }
} }
@Override
public void onDownloaded(Uri uri, Error error) {
progress.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(uri);
videoView.start();
MediaController mc = new MediaController(MediaActivity.this);
videoView.setMediaController(mc);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
loader.setVisibility(View.GONE);
mp.start();
mp.setLooping(true);
}
});
videoView.setVisibility(View.VISIBLE);
}
@Override
public void onUpdateProgress(int progressPercentage) {
progress.setText(String.format("%s%%",String.valueOf(progressPercentage)));
}
} }

View File

@ -44,8 +44,6 @@ import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
@ -60,9 +58,9 @@ import org.json.JSONObject;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import cz.msebera.android.httpclient.Header;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveRelationshipAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveRelationshipAsyncTask;
@ -72,7 +70,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.Entities.Relationship; import fr.gouv.etalab.mastodon.client.Entities.Relationship;
import fr.gouv.etalab.mastodon.client.Entities.Results; import fr.gouv.etalab.mastodon.client.Entities.Results;
import fr.gouv.etalab.mastodon.client.KinrarClient; import fr.gouv.etalab.mastodon.client.HttpsConnection;
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.drawers.AccountSearchDevAdapter; import fr.gouv.etalab.mastodon.drawers.AccountSearchDevAdapter;
import fr.gouv.etalab.mastodon.helper.ExpandableHeightListView; import fr.gouv.etalab.mastodon.helper.ExpandableHeightListView;
@ -195,43 +193,52 @@ public class RemoteFollowActivity extends AppCompatActivity implements OnRetriev
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
if( s.length() > 2 && !isLoadingInstance){ if( s.length() > 2 && !isLoadingInstance){
String action = "/instances/search"; final String action = "/instances/search";
RequestParams parameters = new RequestParams(); final HashMap<String, String> parameters = new HashMap<>();
parameters.add("q", s.toString().trim()); parameters.put("q", s.toString().trim());
parameters.add("count", String.valueOf(10)); parameters.put("count", String.valueOf(5));
parameters.add("name", String.valueOf(true)); parameters.put("name", String.valueOf(true));
isLoadingInstance = true; isLoadingInstance = true;
new KinrarClient().get(action, parameters, new AsyncHttpResponseHandler() { new Thread(new Runnable(){
@Override @Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { public void run() {
isLoadingInstance = false;
String response = new String(responseBody);
String[] instances;
try { try {
JSONObject jsonObject = new JSONObject(response); final String response = new HttpsConnection().get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN );
JSONArray jsonArray = jsonObject.getJSONArray("instances"); runOnUiThread(new Runnable() {
if( jsonArray != null){ public void run() {
instances = new String[jsonArray.length()]; isLoadingInstance = false;
for(int i = 0 ; i < jsonArray.length() ; i++){ String[] instances;
instances[i] = jsonArray.getJSONObject(i).get("name").toString(); try {
} JSONObject jsonObject = new JSONObject(response);
}else { JSONArray jsonArray = jsonObject.getJSONArray("instances");
instances = new String[]{}; if( jsonArray != null){
} instances = new String[jsonArray.length()];
rf_instance.setAdapter(null); for(int i = 0 ; i < jsonArray.length() ; i++){
ArrayAdapter<String> adapter = instances[i] = jsonArray.getJSONObject(i).get("name").toString();
new ArrayAdapter<>(RemoteFollowActivity.this, android.R.layout.simple_list_item_1, instances); }
rf_instance.setAdapter(adapter); }else {
if( rf_instance.hasFocus() && !RemoteFollowActivity.this.isFinishing()) instances = new String[]{};
rf_instance.showDropDown(); }
rf_instance.setAdapter(null);
ArrayAdapter<String> adapter =
new ArrayAdapter<>(RemoteFollowActivity.this, android.R.layout.simple_list_item_1, instances);
rf_instance.setAdapter(adapter);
if( rf_instance.hasFocus() && !RemoteFollowActivity.this.isFinishing())
rf_instance.showDropDown();
} catch (JSONException ignored) {isLoadingInstance = false;} } catch (JSONException ignored) {isLoadingInstance = false;}
}
});
} catch (HttpsConnection.HttpsConnectionException e) {
isLoadingInstance = false;
e.printStackTrace();
} catch (Exception e) {
isLoadingInstance = false;
e.printStackTrace();
}
} }
@Override }).start();
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
isLoadingInstance = false;
}
});
} }
} }
}); });

View File

@ -63,7 +63,6 @@ import android.view.ViewTreeObserver;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.webkit.URLUtil;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
@ -85,8 +84,6 @@ import android.widget.Toast;
import com.github.stom79.localepicker.CountryPicker; import com.github.stom79.localepicker.CountryPicker;
import com.github.stom79.localepicker.CountryPickerListener; import com.github.stom79.localepicker.CountryPickerListener;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.BinaryHttpResponseHandler;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
@ -99,10 +96,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -112,8 +106,6 @@ import java.util.Locale;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import cz.msebera.android.httpclient.Header;
import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveEmojiAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveEmojiAsyncTask;
@ -132,6 +124,7 @@ import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
import fr.gouv.etalab.mastodon.client.HttpsConnection; import fr.gouv.etalab.mastodon.client.HttpsConnection;
import fr.gouv.etalab.mastodon.drawers.CustomEmojiAdapter; import fr.gouv.etalab.mastodon.drawers.CustomEmojiAdapter;
import fr.gouv.etalab.mastodon.drawers.EmojisSearchAdapter; import fr.gouv.etalab.mastodon.drawers.EmojisSearchAdapter;
import fr.gouv.etalab.mastodon.interfaces.OnDownloadInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface;
import fr.gouv.etalab.mastodon.sqlite.CustomEmojiDAO; import fr.gouv.etalab.mastodon.sqlite.CustomEmojiDAO;
import fr.gouv.etalab.mastodon.translation.Translate; import fr.gouv.etalab.mastodon.translation.Translate;
@ -163,7 +156,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
* Toot activity class * Toot activity class
*/ */
public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnTranslatedInterface, OnRetrieveEmojiInterface { public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnTranslatedInterface, OnRetrieveEmojiInterface, OnDownloadInterface {
private String visibility; private String visibility;
@ -410,32 +403,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
toot_content.setSelection(toot_content.getText().length()); toot_content.setSelection(toot_content.getText().length());
} }
if( image != null){ if( image != null){
AsyncHttpClient client = new AsyncHttpClient(); new HttpsConnection(getApplicationContext()).download(image, TootActivity.this);
String[] allowedTypes = new String[] { "image/png","image/jpeg" };
client.get(image, new BinaryHttpResponseHandler(allowedTypes) {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {
OutputStream f;
try {
f = new FileOutputStream(getCacheDir() + URLUtil.guessFileName(image, null, null));
picture_scrollview.setVisibility(View.VISIBLE);
InputStream bis = new ByteArrayInputStream(binaryData);
toot_picture_container.setVisibility(View.VISIBLE);
toot_picture.setEnabled(false);
new HttpsConnection(getApplicationContext()).upload(bis, TootActivity.this);
f.write(binaryData);
f.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error) {
error.printStackTrace();
}
});
} }
} }
@ -1219,6 +1187,19 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
} }
} }
@Override
public void onDownloaded(String pathToFile, Error error) {
picture_scrollview.setVisibility(View.VISIBLE);
Bitmap pictureMention = BitmapFactory.decodeFile(pathToFile);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
pictureMention.compress(Bitmap.CompressFormat.PNG, 0, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata);
toot_picture_container.setVisibility(View.VISIBLE);
toot_picture.setEnabled(false);
new HttpsConnection(getApplicationContext()).upload(bs, TootActivity.this);
}
@Override @Override
public void onUpdateProgress(int progress) { public void onUpdateProgress(int progress) {
ProgressBar progressBar = findViewById(R.id.upload_progress); ProgressBar progressBar = findViewById(R.id.upload_progress);

View File

@ -33,15 +33,14 @@ import android.webkit.WebViewClient;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.Toast; import android.widget.Toast;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import cz.msebera.android.httpclient.Header; import java.util.HashMap;
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
import fr.gouv.etalab.mastodon.client.OauthClient; import fr.gouv.etalab.mastodon.client.HttpsConnection;
import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
@ -108,40 +107,37 @@ public class WebviewConnectActivity extends AppCompatActivity {
} }
String code = val[1]; String code = val[1];
String action = "/oauth/token"; final String action = "/oauth/token";
RequestParams parameters = new RequestParams(); final HashMap<String, String> parameters = new HashMap<>();
parameters.add(Helper.CLIENT_ID, clientId); parameters.put(Helper.CLIENT_ID, clientId);
parameters.add(Helper.CLIENT_SECRET, clientSecret); parameters.put(Helper.CLIENT_SECRET, clientSecret);
parameters.add(Helper.REDIRECT_URI,Helper.REDIRECT_CONTENT_WEB); parameters.put(Helper.REDIRECT_URI,Helper.REDIRECT_CONTENT_WEB);
parameters.add("grant_type", "authorization_code"); parameters.put("grant_type", "authorization_code");
parameters.add("code",code); parameters.put("code",code);
new OauthClient(instance).post(action, parameters, new AsyncHttpResponseHandler() { new Thread(new Runnable(){
@Override @Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { public void run() {
String response = new String(responseBody);
JSONObject resobj;
try { try {
resobj = new JSONObject(response); final String response = new HttpsConnection().post("https://" + instance + action, 30, parameters, null);
String token = resobj.get("access_token").toString(); JSONObject resobj;
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); try {
SharedPreferences.Editor editor = sharedpreferences.edit(); resobj = new JSONObject(response);
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token); String token = resobj.get("access_token").toString();
editor.apply(); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
//Update the account with the token; SharedPreferences.Editor editor = sharedpreferences.edit();
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
} catch (JSONException e) { editor.apply();
//Update the account with the token;
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (JSONException e) {
e.printStackTrace();
}
} catch (HttpsConnection.HttpsConnectionException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
}});
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
error.printStackTrace();
}
});
return true; return true;
} }
return false; return false;

View File

@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import com.loopj.android.http.RequestParams;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -193,7 +192,7 @@ public class API {
public Relationship getRelationship(String accountId) { public Relationship getRelationship(String accountId) {
Relationship relationship = new Relationship(); Relationship relationship = new Relationship();
RequestParams params = new RequestParams(); HashMap<String, String> params = new HashMap<>();
params.put("id",accountId); params.put("id",accountId);
try { try {
String response = new HttpsConnection().get(getAbsoluteUrl("/accounts/relationships"), 60, null, prefKeyOauthTokenT); String response = new HttpsConnection().get(getAbsoluteUrl("/accounts/relationships"), 60, null, prefKeyOauthTokenT);

View File

@ -16,9 +16,7 @@ package fr.gouv.etalab.mastodon.client;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build; import android.os.Build;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -29,8 +27,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader; import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.security.KeyManagementException; import java.security.KeyManagementException;
@ -42,12 +40,12 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.client.Entities.Attachment; import fr.gouv.etalab.mastodon.client.Entities.Attachment;
import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnDownloadInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
@ -72,6 +70,7 @@ public class HttpsConnection {
this.context = context; this.context = context;
} }
@SuppressWarnings("ConstantConditions")
public String get(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException { public String get(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
Map<String,Object> params = new LinkedHashMap<>(); Map<String,Object> params = new LinkedHashMap<>();
@ -167,6 +166,67 @@ public class HttpsConnection {
} }
public void download(final String downloadUrl, final OnDownloadInterface listener) {
new Thread(new Runnable() {
@Override
public void run() {
URL url;
try {
url = new URL(downloadUrl);
httpsURLConnection = (HttpsURLConnection) url.openConnection();
int responseCode = httpsURLConnection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpsURLConnection.getHeaderField("Content-Disposition");
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1,
downloadUrl.length());
}
// opens input stream from the HTTP connection
InputStream inputStream = httpsURLConnection.getInputStream();
File saveDir = context.getCacheDir();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead;
byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
listener.onDownloaded(saveFilePath, null);
} else {
Error error = new Error();
error.setError(String.valueOf(responseCode));
listener.onDownloaded(null, error);
}
httpsURLConnection.disconnect();
} catch (IOException e) {
Error error = new Error();
error.setError(context.getString(R.string.toast_error));
e.printStackTrace();
}
}
}).start();
}
public void upload(final InputStream inputStream, final OnRetrieveAttachmentInterface listener) { public void upload(final InputStream inputStream, final OnRetrieveAttachmentInterface listener) {
new Thread(new Runnable() { new Thread(new Runnable() {
@ -248,7 +308,7 @@ public class HttpsConnection {
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = ""; String line;
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null) { while ((line = responseStreamReader.readLine()) != null) {

View File

@ -1,61 +0,0 @@
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Mastalab
*
* 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.
*
* Mastalab 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 Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
package fr.gouv.etalab.mastodon.client;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import fr.gouv.etalab.mastodon.helper.Helper;
import static fr.gouv.etalab.mastodon.helper.Helper.USER_AGENT;
/**
* Created by Thomas on 04/08/2017.
* Client for the Kinrar's API
*/
public class KinrarClient {
private AsyncHttpClient client = new AsyncHttpClient();
public void get(String action, RequestParams params, AsyncHttpResponseHandler responseHandler) {
try {
client.setConnectTimeout(10000); //10s timeout
client.setUserAgent(USER_AGENT);
client.addHeader("Authorization", "Bearer " + Helper.THEKINRAR_SECRET_TOKEN);
MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
//mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.setSSLSocketFactory(mastalabSSLSocketFactory);
client.get(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
}
}
private String getAbsoluteUrl(String action) {
return "https://instances.social/api/1.0" + action;
}
}

View File

@ -1,92 +0,0 @@
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Mastalab
*
* 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.
*
* Mastalab 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 Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
package fr.gouv.etalab.mastodon.client;
/*
* Created by Thomas on 20/05/2017.
* Custom MySSLSocketFactory
*/
import android.annotation.SuppressLint;
import java.io.IOException;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* This file is introduced to fix HTTPS Post bug on API &lt; ICS see
* https://code.google.com/p/android/issues/detail?id=13117#c14 <p>&nbsp;</p> Warning! This omits SSL
* certificate validation on every device, use with caution
*/
public class MastalabSSLSocketFactory extends com.loopj.android.http.MySSLSocketFactory {
private final SSLContext sslContext = SSLContext.getInstance("TLS");
/**
* Creates a new SSL Socket Factory with the given KeyStore.
*
* @param truststore A KeyStore to create the SSL Socket Factory in context of
* @throws NoSuchAlgorithmException NoSuchAlgorithmException
* @throws KeyManagementException KeyManagementException
* @throws KeyStoreException KeyStoreException
* @throws UnrecoverableKeyException UnrecoverableKeyException
*/
public MastalabSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
X509TrustManager tm = new X509TrustManager() {
@SuppressLint("TrustAllX509TrustManager")
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@SuppressLint("TrustAllX509TrustManager")
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[]{tm}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket(socket, host, port, autoClose));
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(sslContext.getSocketFactory().createSocket());
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}

View File

@ -1,84 +0,0 @@
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Mastalab
*
* 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.
*
* Mastalab 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 Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
package fr.gouv.etalab.mastodon.client;
import android.util.Log;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import fr.gouv.etalab.mastodon.helper.Helper;
import static fr.gouv.etalab.mastodon.helper.Helper.USER_AGENT;
/**
* Created by Thomas on 23/04/2017.
* Client to call urls
*/
public class OauthClient {
private static AsyncHttpClient client = new AsyncHttpClient();
private String instance;
public OauthClient(String instance){
this.instance = instance;
}
public void get(String action, RequestParams params, AsyncHttpResponseHandler responseHandler) {
try {
client.setConnectTimeout(30000); //30s timeout
client.setUserAgent(USER_AGENT);
MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
//mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// client.setSSLSocketFactory(mastalabSSLSocketFactory);
Log.v(Helper.TAG,"getAbsoluteUrl(action): " + getAbsoluteUrl(action));
Log.v(Helper.TAG,"params: " + params);
client.get(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
}
}
public void post(String action, RequestParams params, AsyncHttpResponseHandler responseHandler) {
try {
client.setConnectTimeout(30000); //30s timeout
client.setUserAgent(USER_AGENT);
MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore());
//mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// client.setSSLSocketFactory(mastalabSSLSocketFactory);
Log.v(Helper.TAG,"getAbsoluteUrl(action): " + getAbsoluteUrl(action));
Log.v(Helper.TAG,"params: " + params);
client.post(getAbsoluteUrl(action), params, responseHandler);
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) {
e.printStackTrace();
}
}
private String getAbsoluteUrl(String action) {
return "https://" + instance + action;
}
}

View File

@ -85,7 +85,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.loopj.android.http.BuildConfig;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
@ -123,6 +122,7 @@ import java.util.TimeZone;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import fr.gouv.etalab.mastodon.BuildConfig;
import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.HashTagActivity; import fr.gouv.etalab.mastodon.activities.HashTagActivity;
import fr.gouv.etalab.mastodon.activities.LoginActivity; import fr.gouv.etalab.mastodon.activities.LoginActivity;

View File

@ -0,0 +1,26 @@
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Mastalab
*
* 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.
*
* Mastalab 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 Mastalab; if not,
* see <http://www.gnu.org/licenses>. */
package fr.gouv.etalab.mastodon.interfaces;
import fr.gouv.etalab.mastodon.client.Entities.Error;
/**
* Created by Thomas on 17/11/2017.
* Interface when a media has been downloaded
*/
public interface OnDownloadInterface {
void onDownloaded(String saveFilePath, Error error);
void onUpdateProgress(int progress);
}