diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 83862c5287..9029f205e2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,8 @@ Thx - Hardy --> + Select picture + Cannot upload image, please, try again later Motorboat Kayak Search history diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 73301158c5..30b7f05cd8 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -6,6 +6,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.ColorStateList; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.Typeface; @@ -33,11 +35,14 @@ import androidx.appcompat.view.ContextThemeWrapper; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; +import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.*; +import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; 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.NoImagesCard; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; +import net.osmand.plus.openplacereviews.OPRWebviewActivity; import net.osmand.plus.openplacereviews.OprStartFragment; +import net.osmand.plus.osmedit.opr.OpenDBAPI; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RenderingIcons; 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.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 static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; @@ -92,6 +107,12 @@ public class MenuBuilder { private String preferredMapAppLang; 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 { void onCollapseExpand(boolean collapsed); } @@ -336,8 +357,103 @@ public class MenuBuilder { b.setTypeface(null, Typeface.BOLD); b.setText(context.getResources().getString(R.string.shared_string_add_photo)); 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 - b.setVisibility(View.GONE); + //b.setVisibility(View.GONE); b.setTextColor(ContextCompat.getColor(context, R.color.preference_category_title)); return b; } @@ -357,6 +473,10 @@ public class MenuBuilder { } onlinePhotoCards = new ArrayList<>(); onlinePhotoCardsRow.setProgressCard(); + startLoadingImagesTask(); + } + + private void startLoadingImagesTask(){ execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(), new GetImageCardsListener() { @Override @@ -364,6 +484,11 @@ public class MenuBuilder { processOnlinePhotosCards(cardList); } + @Override + public void onPlaceIdAcquired(String[] placeId) { + MenuBuilder.this.placeId = placeId; + } + @Override public void onFinish(List cardList) { if (!isHidden()) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java index 1108692934..33feb6c5a3 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java @@ -438,6 +438,8 @@ public abstract class ImageCard extends AbstractCard { public interface GetImageCardsListener { void onPostProcess(List cardList); + void onPlaceIdAcquired(String[] placeId); + void onFinish(List cardList); } @@ -464,8 +466,7 @@ public abstract class ImageCard extends AbstractCard { if (response != null) { getPicturesForPlace(result, response); String[] id = getIdFromResponse(response); - //TODO perform something with image - //listener.onOPRPlaceIdAcquired(id); + listener.onPlaceIdAcquired(id); } } try { diff --git a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java index 0d77c49d25..fbaa401cf6 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/opr/OpenDBAPI.java @@ -28,7 +28,7 @@ import static org.openplacereviews.opendb.SecUtils.*; public class OpenDBAPI { private static final Log log = PlatformUtil.getLog(SecUtils.class); 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; /* @@ -39,7 +39,7 @@ public class OpenDBAPI { * Need to encode key * Do not call on mainThread */ - public boolean checkPrivateKeyValid(String username, String privateKey) throws UnsupportedEncodingException { + public boolean checkPrivateKeyValid(String username, String privateKey) { String url = null; try { url = BuildConfig.OPR_BASE_URL + checkLoginEndpoint + @@ -50,7 +50,7 @@ public class OpenDBAPI { //need to encode the key URLEncoder.encode(privateKey, "UTF-8"); } catch (UnsupportedEncodingException e) { - throw e; + return false; } StringBuilder response = new StringBuilder(); return (NetworkUtils.sendGetRequest(url,null,response) == null) && @@ -63,7 +63,7 @@ public class OpenDBAPI { Security.addProvider(new BouncyCastleProvider()); } KeyPair kp = SecUtils.getKeyPair(ALGO_EC, privateKey, null); - String signed = username;// + ":opr-web"; + String signed = username + ":opr-web"; JsonFormatter formatter = new JsonFormatter(); OPRImage OPRImage = new GsonBuilder().create().fromJson(image, OPRImage.class);