Merge branch 'develop' of https://bitbucket.org/tom79/mastodon_etalab into develop

# Conflicts:
#	app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java
This commit is contained in:
tom79 2017-09-01 19:58:41 +02:00
commit 21a86957de
2 changed files with 189 additions and 3 deletions

View File

@ -40,8 +40,8 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Html;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@ -108,6 +108,7 @@ import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
import fr.gouv.etalab.mastodon.drawers.DraftsListAdapter;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.helper.ParserUtils;
import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
@ -127,7 +128,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
* Toot activity class
*/
public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface {
public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, ParserUtils.ParserListener {
private String visibility;
@ -309,6 +310,13 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}});
if( sharedContent != null ){ //Shared content
// ParserUtils is a class I borrowed from Tusky.
final ParserUtils parser = new ParserUtils(this);
parser.putInClipboardManager(TootActivity.this, sharedContent);
String urlString = parser.getPastedURLText(TootActivity.this);
if( sharedSubject != null){
sharedContent = sharedSubject + "\n\n" + sharedContent;
}
@ -346,7 +354,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
int charsInCw = 0;
int charsInToot = 0;
uploadSharedImage(sharedUri);
if (!sharedUri.isEmpty()) {
uploadSharedImage(sharedUri);
}
boolean isAccountPrivate = account.isLocked();
if(isAccountPrivate){
@ -585,6 +595,16 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
mToast.show();
}
//TODO: This overload takes care of the single URL coming from a text share.
public void uploadSharedImage(Uri image)
{
if (image != null) {
ArrayList<Uri> uri = new ArrayList<>();
uri.add(image);
uploadSharedImage(uri);
}
}
// Handles uploading shared images
public void uploadSharedImage(ArrayList<Uri> uri)
{
@ -597,6 +617,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
break;
}
// TODO: Work out what needs to be done to the URL from a text URL share to allow upload.
Toast.makeText(getApplicationContext(), "in upload: " + fileUri.toString(), Toast.LENGTH_SHORT).show();
picture_scrollview.setVisibility(View.VISIBLE);
try {
@ -1351,5 +1374,27 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
}
// TODO: These two methods are part of the interface for ParserUtils
/*
These two methods are added to handle the grafted on code from Tusky,
they are part of its interface.
*/
@Override
public void onReceiveHeaderInfo(ParserUtils.HeaderInfo headerInfo) {
if (!TextUtils.isEmpty(headerInfo.title)) {
Toast.makeText(getApplicationContext(), headerInfo.title, Toast.LENGTH_SHORT).show();
if (!TextUtils.isEmpty(headerInfo.image)) {
Toast.makeText(getApplicationContext(), "We have an image", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), headerInfo.image, Toast.LENGTH_SHORT).show();
uploadSharedImage(Uri.parse(headerInfo.image));
}
}
}
@Override
public void onErrorHeaderInfo() {
Toast.makeText(this.getApplicationContext(), "An error has occurred.", Toast.LENGTH_SHORT).show();
}
}

View File

@ -0,0 +1,141 @@
package fr.gouv.etalab.mastodon.helper;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.webkit.URLUtil;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.helper.HttpConnection;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
// TODO: Borrowed wholesale from Tusky
/**
* Inspect and get the information from a URL.
*/
public class ParserUtils {
public final static String carriageReturn = System.getProperty("line.separator");
final private static String QUOTE = "\"";
private static final String TAG = "ParserUtils";
private ParserListener parserListener;
public ParserUtils(ParserListener parserListener) {
this.parserListener = parserListener;
}
// TootActivity : EditText inside the onTextChanged
public String getPastedURLText(Context context) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
String pasteData;
if (clipboard.hasPrimaryClip()) {
// get what is in the clipboard
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
pasteData = item.getText().toString();
// If we share with an app, it's not only an url
List<String> strings = extractUrl(pasteData);
if (strings.size() > 0) {
String url = strings.get(0); // we assume that the first url is the good one
if (URLUtil.isValidUrl(url)) {
new ThreadHeaderInfo().execute(url);
}
}
}
return null;
}
public void putInClipboardManager(Context context, String string) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("", string);
clipboard.setPrimaryClip(clip);
}
/** parse the HTML page */
private HeaderInfo parsePageHeaderInfo(String urlStr) throws Exception {
Connection con = Jsoup.connect(urlStr);
HeaderInfo headerInfo = new HeaderInfo();
con.userAgent(HttpConnection.DEFAULT_UA);
Document doc = con.get();
// get info
String text;
Elements metaOgTitle = doc.select("meta[property=og:title]");
if (metaOgTitle != null) {
text = metaOgTitle.attr("content");
} else {
text = doc.title();
}
String imageUrl = null;
Elements metaOgImage = doc.select("meta[property=og:image]");
if (metaOgImage != null) {
imageUrl = metaOgImage.attr("content");
}
// set info
headerInfo.baseUrl = urlStr;
if (!TextUtils.isEmpty(text)) {
headerInfo.title = QUOTE + text + QUOTE;
}
if (!TextUtils.isEmpty(imageUrl)) {
headerInfo.image = (imageUrl);
}
return headerInfo;
}
public interface ParserListener {
void onReceiveHeaderInfo(HeaderInfo headerInfo);
void onErrorHeaderInfo();
}
public class HeaderInfo {
public String baseUrl;
public String title;
public String image;
}
private class ThreadHeaderInfo extends AsyncTask<String, Void, HeaderInfo> {
protected HeaderInfo doInBackground(String... urls) {
try {
String url = urls[0];
return parsePageHeaderInfo(url);
} catch (Exception e) {
Log.e(TAG, "ThreadHeaderInfo#parsePageHeaderInfo() failed." + e.getMessage());
return null;
}
}
protected void onPostExecute(HeaderInfo headerInfo) {
if (headerInfo != null) {
Log.i(TAG, "ThreadHeaderInfo#parsePageHeaderInfo() success." + headerInfo.title + " " + headerInfo.image);
parserListener.onReceiveHeaderInfo(headerInfo);
} else {
parserListener.onErrorHeaderInfo();
}
}
}
static List<String> extractUrl(String text) {
List<String> links = new ArrayList<>();
Matcher m = Patterns.WEB_URL.matcher(text);
while (m.find()) {
String url = m.group();
links.add(url);
}
return links;
}
}