photo upload feature implemented

This commit is contained in:
Simon Yakymovych 2020-11-20 12:26:23 +02:00
parent 5cef32531b
commit c307a0e4fe
4 changed files with 135 additions and 7 deletions

View file

@ -11,6 +11,8 @@
Thx - Hardy Thx - Hardy
--> -->
<string name="select_picture">Select picture</string>
<string name="cannot_upload_image">Cannot upload image, please, try again later</string>
<string name="app_mode_motorboat">Motorboat</string> <string name="app_mode_motorboat">Motorboat</string>
<string name="app_mode_kayak">Kayak</string> <string name="app_mode_kayak">Kayak</string>
<string name="shared_string_search_history">Search history</string> <string name="shared_string_search_history">Search history</string>

View file

@ -6,6 +6,8 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Typeface; import android.graphics.Typeface;
@ -33,11 +35,14 @@ import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.*; import net.osmand.plus.*;
import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard;
@ -46,7 +51,9 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask;
import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
import net.osmand.plus.openplacereviews.OPRWebviewActivity;
import net.osmand.plus.openplacereviews.OprStartFragment; import net.osmand.plus.openplacereviews.OprStartFragment;
import net.osmand.plus.osmedit.opr.OpenDBAPI;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.transport.TransportStopRoute;
@ -57,6 +64,14 @@ import net.osmand.plus.widgets.tools.ClickableSpanTouchListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import org.openplacereviews.opendb.util.exception.FailedVerificationException;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.*; import java.util.*;
import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
@ -92,6 +107,12 @@ public class MenuBuilder {
private String preferredMapAppLang; private String preferredMapAppLang;
private boolean transliterateNames; private boolean transliterateNames;
private static final int PICK_IMAGE = 1231;
private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
private View view;
private OpenDBAPI openDBAPI = new OpenDBAPI();
private String[] placeId = new String[0];
public interface CollapseExpandListener { public interface CollapseExpandListener {
void onCollapseExpand(boolean collapsed); void onCollapseExpand(boolean collapsed);
} }
@ -336,8 +357,103 @@ public class MenuBuilder {
b.setTypeface(null, Typeface.BOLD); b.setTypeface(null, Typeface.BOLD);
b.setText(context.getResources().getString(R.string.shared_string_add_photo)); b.setText(context.getResources().getString(R.string.shared_string_add_photo));
b.setBackgroundResource(R.drawable.btn_border_light); b.setBackgroundResource(R.drawable.btn_border_light);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View view) {
mapActivity.registerActivityResultListener(new ActivityResultListener(PICK_IMAGE,
new ActivityResultListener.OnActivityResultListener() {
@Override
public void onResult(int resultCode, Intent resultData) {
InputStream inputStream = null;
try {
inputStream = mapActivity.getContentResolver().openInputStream(resultData.getData());
} catch (Exception e) {
LOG.error(e);
}
handleSelectedImage(view, inputStream);
}
}));
final String privateKey = OPRWebviewActivity.getPrivateKeyFromCookie();
final String name = OPRWebviewActivity.getUsernameFromCookie();
if (privateKey == null || privateKey.isEmpty()) {
OprStartFragment.showInstance(mapActivity.getSupportFragmentManager());
return;
}
new Thread(new Runnable() {
@Override
public void run() {
if (openDBAPI.checkPrivateKeyValid(name,privateKey)){
app.runInUIThread(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
mapActivity.startActivityForResult(Intent.createChooser(intent,
mapActivity.getString(R.string.select_picture)), PICK_IMAGE);
}
});
}
else {
OprStartFragment.showInstance(mapActivity.getSupportFragmentManager());
}
}
}).start();
}
private void handleSelectedImage(final View view, final InputStream image) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
uploadImageToPlace(view, image);
} catch (Exception e) {
LOG.error(e);
}
}
});
t.start();
}
private void uploadImageToPlace(View view, InputStream image) {
//compress image
BufferedInputStream bufferedInputStream = new BufferedInputStream(image);
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
ByteArrayOutputStream os = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 70, os);
byte[] buff = os.toByteArray();
InputStream serverData = new ByteArrayInputStream(buff);
String url = BuildConfig.OPR_BASE_URL + "api/ipfs/image";
String response = NetworkUtils.sendPostDataRequest(url, serverData);
if (response != null) {
int res = 0;
try {
res = openDBAPI.uploadImage(
placeId,
OPRWebviewActivity.getPrivateKeyFromCookie()
, OPRWebviewActivity.getUsernameFromCookie(),
response);
} catch (FailedVerificationException e) {
LOG.error(e);
app.showToastMessage(view.getResources().getString(R.string.cannot_upload_image));
}
if (res != 200) {
//image was uploaded but not added to blockchain
app.showToastMessage(view.getResources().getString(R.string.cannot_upload_image));
} else {
String str = MessageFormat.format(view.getResources()
.getString(R.string.successfully_uploaded_pattern), 1, 1);
app.showToastMessage(str);
//refresh the image
startLoadingImagesTask();
}
} else {
app.showToastMessage(view.getResources().getString(R.string.cannot_upload_image));
}
}
});
//TODO feature under development //TODO feature under development
b.setVisibility(View.GONE); //b.setVisibility(View.GONE);
b.setTextColor(ContextCompat.getColor(context, R.color.preference_category_title)); b.setTextColor(ContextCompat.getColor(context, R.color.preference_category_title));
return b; return b;
} }
@ -357,6 +473,10 @@ public class MenuBuilder {
} }
onlinePhotoCards = new ArrayList<>(); onlinePhotoCards = new ArrayList<>();
onlinePhotoCardsRow.setProgressCard(); onlinePhotoCardsRow.setProgressCard();
startLoadingImagesTask();
}
private void startLoadingImagesTask(){
execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(), execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(),
new GetImageCardsListener() { new GetImageCardsListener() {
@Override @Override
@ -364,6 +484,11 @@ public class MenuBuilder {
processOnlinePhotosCards(cardList); processOnlinePhotosCards(cardList);
} }
@Override
public void onPlaceIdAcquired(String[] placeId) {
MenuBuilder.this.placeId = placeId;
}
@Override @Override
public void onFinish(List<ImageCard> cardList) { public void onFinish(List<ImageCard> cardList) {
if (!isHidden()) { if (!isHidden()) {

View file

@ -438,6 +438,8 @@ public abstract class ImageCard extends AbstractCard {
public interface GetImageCardsListener { public interface GetImageCardsListener {
void onPostProcess(List<ImageCard> cardList); void onPostProcess(List<ImageCard> cardList);
void onPlaceIdAcquired(String[] placeId);
void onFinish(List<ImageCard> cardList); void onFinish(List<ImageCard> cardList);
} }
@ -464,8 +466,7 @@ public abstract class ImageCard extends AbstractCard {
if (response != null) { if (response != null) {
getPicturesForPlace(result, response); getPicturesForPlace(result, response);
String[] id = getIdFromResponse(response); String[] id = getIdFromResponse(response);
//TODO perform something with image listener.onPlaceIdAcquired(id);
//listener.onOPRPlaceIdAcquired(id);
} }
} }
try { try {

View file

@ -28,7 +28,7 @@ import static org.openplacereviews.opendb.SecUtils.*;
public class OpenDBAPI { public class OpenDBAPI {
private static final Log log = PlatformUtil.getLog(SecUtils.class); private static final Log log = PlatformUtil.getLog(SecUtils.class);
private static final String checkLoginEndpoint = "api/auth/user-check-loginkey?"; private static final String checkLoginEndpoint = "api/auth/user-check-loginkey?";
private static final String LOGIN_SUCCESS_MESSAGE = "success"; private static final String LOGIN_SUCCESS_MESSAGE = "{\"result\":\"OK\"}";
private static final int THREAD_ID = 11200; private static final int THREAD_ID = 11200;
/* /*
@ -39,7 +39,7 @@ public class OpenDBAPI {
* Need to encode key * Need to encode key
* Do not call on mainThread * Do not call on mainThread
*/ */
public boolean checkPrivateKeyValid(String username, String privateKey) throws UnsupportedEncodingException { public boolean checkPrivateKeyValid(String username, String privateKey) {
String url = null; String url = null;
try { try {
url = BuildConfig.OPR_BASE_URL + checkLoginEndpoint + url = BuildConfig.OPR_BASE_URL + checkLoginEndpoint +
@ -50,7 +50,7 @@ public class OpenDBAPI {
//need to encode the key //need to encode the key
URLEncoder.encode(privateKey, "UTF-8"); URLEncoder.encode(privateKey, "UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw e; return false;
} }
StringBuilder response = new StringBuilder(); StringBuilder response = new StringBuilder();
return (NetworkUtils.sendGetRequest(url,null,response) == null) && return (NetworkUtils.sendGetRequest(url,null,response) == null) &&
@ -63,7 +63,7 @@ public class OpenDBAPI {
Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new BouncyCastleProvider());
} }
KeyPair kp = SecUtils.getKeyPair(ALGO_EC, privateKey, null); KeyPair kp = SecUtils.getKeyPair(ALGO_EC, privateKey, null);
String signed = username;// + ":opr-web"; String signed = username + ":opr-web";
JsonFormatter formatter = new JsonFormatter(); JsonFormatter formatter = new JsonFormatter();
OPRImage OPRImage = new GsonBuilder().create().fromJson(image, OPRImage.class); OPRImage OPRImage = new GsonBuilder().create().fromJson(image, OPRImage.class);