From 07636057327fbc849558fe0af9f19f4a9444d22e Mon Sep 17 00:00:00 2001 From: Hung Date: Thu, 23 Nov 2023 17:27:54 +0800 Subject: [PATCH 1/5] bump version --- visearch-android/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/visearch-android/build.gradle b/visearch-android/build.gradle index 9ced798..0917036 100644 --- a/visearch-android/build.gradle +++ b/visearch-android/build.gradle @@ -4,9 +4,9 @@ plugins { } def versionMajor = 2 -def versionMinor = 3 -def versionPatch = 5 -version = '2.3.5' +def versionMinor = 4 +def versionPatch = 0 +version = '2.4.0' android { compileSdkVersion 29 From 359dcf211380fe861d254d4d029e7281f876d710 Mon Sep 17 00:00:00 2001 From: Hung Date: Thu, 23 Nov 2023 17:51:03 +0800 Subject: [PATCH 2/5] add ViSearch multisearch --- .../android/ProductSearchByImageParams.java | 11 ++++++ .../visearch/android/UploadSearchParams.java | 25 +++++++++++++ .../android/api/SearchOperations.java | 12 +++++-- .../android/api/impl/SearchOperationsImp.java | 5 +++ .../visearch/android/network/APIService.java | 9 +++++ .../android/network/SearchService.java | 35 ++++++++++++------- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearchByImageParams.java b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearchByImageParams.java index 1e6016c..de2bbd5 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearchByImageParams.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearchByImageParams.java @@ -34,6 +34,9 @@ public class ProductSearchByImageParams extends BaseProductSearchParams { // internal serialization @SerializedName("box") private String boxParam; + + @SerializedName("q") + private String q; public Boolean getSearchAllObjects() { return searchAllObjects; @@ -104,6 +107,14 @@ public String getBoxParam() { return boxParam; } + public String getQ() { + return q; + } + + public void setQ(String q) { + this.q = q; + } + public ProductSearchByImageParams() { super(); } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/UploadSearchParams.java b/visearch-android/src/main/java/com/visenze/visearch/android/UploadSearchParams.java index 08e7895..386ba8a 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/UploadSearchParams.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/UploadSearchParams.java @@ -30,6 +30,8 @@ public class UploadSearchParams extends SearchParams { private Integer resultLimit; + private String q; + public UploadSearchParams() { super(); } @@ -117,6 +119,16 @@ public UploadSearchParams setAttributes(Map attributes) { return this; } + /** + * + * @param q text query + * @return this instance. + */ + public UploadSearchParams setQ(String q) { + this.q = q; + return this; + } + /** * Get {@link Image Image} that is set to search * @@ -153,6 +165,15 @@ public String getDetection() { return detection; } + /** + * Get text query + * + * @return text query. + */ + public String getQ() { + return q; + } + @Override public Map > toMap() { Map > map = super.toMap(); @@ -203,6 +224,10 @@ public Map > toMap() { putStringInMap(map, "result_limit", resultLimit.toString()); } + if (q != null) { + putStringInMap(map,"q", q); + } + return map; } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/api/SearchOperations.java b/visearch-android/src/main/java/com/visenze/visearch/android/api/SearchOperations.java index f7c7170..40b3707 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/api/SearchOperations.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/api/SearchOperations.java @@ -41,7 +41,7 @@ public interface SearchOperations { * Upload Search (POST /uploadsearch) * Searching against the image collection with an uploading image. * - * @param uploadSearchParams the index search parameter setting + * @param uploadSearchParams request params * @param resultListener result listener */ public void uploadSearch(UploadSearchParams uploadSearchParams, final ViSearch.ResultListener resultListener); @@ -50,11 +50,19 @@ public interface SearchOperations { * Discover Search (POST /discoversearch) * Multiple Products Search * - * @param uploadSearchParams the index search parameter setting + * @param uploadSearchParams request params * @param resultListener result listener */ public void discoverSearch(UploadSearchParams uploadSearchParams, final ViSearch.ResultListener resultListener); + /** + * Multi Search (POST /multisearch) + * Multi-search (image and text query) + * + * @param uploadSearchParams request params (image and text query) + * @param resultListener result listener + */ + public void multiSearch(UploadSearchParams uploadSearchParams, final ViSearch.ResultListener resultListener); public void cancelSearch(ViSearch.ResultListener resultListener); } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/api/impl/SearchOperationsImp.java b/visearch-android/src/main/java/com/visenze/visearch/android/api/impl/SearchOperationsImp.java index bfda91e..6f12ab1 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/api/impl/SearchOperationsImp.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/api/impl/SearchOperationsImp.java @@ -42,6 +42,11 @@ public void discoverSearch(UploadSearchParams uploadSearchParams, ViSearch.Resul searchService.uploadSearch(SearchService.DISCOVER_SEARCH, uploadSearchParams, resultListener); } + @Override + public void multiSearch(UploadSearchParams uploadSearchParams, ViSearch.ResultListener resultListener) { + searchService.uploadSearch(SearchService.MULTI_SEARCH, uploadSearchParams, resultListener); + } + @Override public void cancelSearch(ViSearch.ResultListener resultListener) { resultListener.onSearchCanceled(); diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIService.java index 5ca9004..78da6f3 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIService.java @@ -52,4 +52,13 @@ public interface APIService { @POST("discoversearch") Call discoverSearch(@HeaderMap Map headers, @Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); + @Retry + @GET("multisearch") + Call multiSearch(@HeaderMap Map headers, @QueryMap RetrofitQueryMap query); + + @Retry + @Multipart + @POST("multisearch") + Call multiSearch(@HeaderMap Map headers, @Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); + } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/SearchService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/SearchService.java index f851660..1975c07 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/SearchService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/SearchService.java @@ -26,6 +26,7 @@ public class SearchService { public final static String COLOR_SEARCH = "colorsearch"; public final static String UPLOAD_SEARCH = "uploadsearch"; public final static String DISCOVER_SEARCH = "discoversearch"; + public final static String MULTI_SEARCH = "multisearch"; private final static String ACCESS_KEY = "access_key"; private String appKey; @@ -77,8 +78,11 @@ public void uploadSearch(String endPoint, UploadSearchParams uploadSearchParams, String imageUrl = uploadSearchParams.getImageUrl(); String imId = uploadSearchParams.getImId(); - if (imageBytes == null && (imageUrl == null || imageUrl.isEmpty()) && (imId == null || imId.isEmpty())) { - throw new ViSearchException("Missing parameter, image empty"); + // image is optional for multi-search + if (!SearchService.MULTI_SEARCH.equals(endPoint)) { + if (imageBytes == null && (imageUrl == null || imageUrl.isEmpty()) && (imId == null || imId.isEmpty())) { + throw new ViSearchException("Missing parameter, image empty"); + } } Map headers = getHeaders(); @@ -95,23 +99,28 @@ public void uploadSearch(String endPoint, UploadSearchParams uploadSearchParams, } private Call getCall(String endPoint, Map headers, RetrofitQueryMap params, MultipartBody.Part image) { - Call call; if(UPLOAD_SEARCH.equals(endPoint)) { if(image == null) { - call = apiService.uploadSearch(headers, params); - } else { - call = apiService.uploadSearch(headers, image, params); + return apiService.uploadSearch(headers, params); } - } else if(DISCOVER_SEARCH.equals(endPoint)) { + return apiService.uploadSearch(headers, image, params); + } + + if(DISCOVER_SEARCH.equals(endPoint)) { if(image == null) { - call = apiService.discoverSearch(headers, params); - } else { - call = apiService.discoverSearch(headers, image, params); + return apiService.discoverSearch(headers, params); } - } else { - throw new ViSearchException("wrong API method"); + return apiService.discoverSearch(headers, image, params); } - return call; + + if(MULTI_SEARCH.equals(endPoint)) { + if(image == null) { + return apiService.multiSearch(headers, params); + } + return apiService.multiSearch(headers, image, params); + } + + throw new ViSearchException("wrong API method"); } private void handleCallback(Call call, final ViSearch.ResultListener resultListener) { From 69d4347c13f758f05b9ee74ce187b55633e8e889 Mon Sep 17 00:00:00 2001 From: Hung Date: Thu, 23 Nov 2023 18:04:46 +0800 Subject: [PATCH 3/5] add multisearch for product search --- .../visearch/android/ProductSearch.java | 5 +++ .../android/network/APIProductService.java | 7 +++++ .../android/network/ProductSearchService.java | 31 ++++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java index 958e17e..2d4dc82 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java @@ -39,6 +39,11 @@ public void searchById(ProductSearchByIdParams visualSimilarParams, ResultListen productSearchService.searchById(visualSimilarParams, listener); } + public void multisearcch(ProductSearchByImageParams imageSearchParams, ResultListener listener) { + addAnalyticsParams(imageSearchParams); + productSearchService.searchByImage(imageSearchParams, listener, true); + } + public void recommendations(ProductSearchByIdParams visualSimilarParams, ResultListener listener) { searchById(visualSimilarParams, listener); } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java index fd9a49c..b4c1222 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java @@ -28,5 +28,12 @@ public interface APIProductService { @POST("product/search_by_image") Call searchByImage(@Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); + @Retry + @POST("product/multisearch") + Call multisearch(@QueryMap RetrofitQueryMap query); + @Retry + @Multipart + @POST("product/multisearch") + Call multisearch(@Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java index bde7524..381d1d0 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java @@ -39,8 +39,11 @@ public void searchById(ProductSearchByIdParams visualSimilarParams, final Produc handleCallback(call, listener); } - public void searchByImage(ProductSearchByImageParams imageSearchParams, final ProductSearch.ResultListener listener) { + searchByImage(imageSearchParams, listener, false); + } + + public void searchByImage(ProductSearchByImageParams imageSearchParams, final ProductSearch.ResultListener listener, boolean multiSearch) { byte[] imageBytes = null; if (imageSearchParams.getImage() != null) { @@ -50,8 +53,11 @@ public void searchByImage(ProductSearchByImageParams imageSearchParams, final Pr String imageUrl = imageSearchParams.getImUrl(); String imId = imageSearchParams.getImId(); - if (imageBytes == null && (imageUrl == null || imageUrl.isEmpty()) && (imId == null || imId.isEmpty())) { - throw new IllegalArgumentException("Please provide imUrl , imId or image parameter"); + // image is optional for multisearch + if (!multiSearch) { + if (imageBytes == null && (imageUrl == null || imageUrl.isEmpty()) && (imId == null || imId.isEmpty())) { + throw new IllegalArgumentException("Please provide imUrl , imId or image parameter"); + } } RetrofitQueryMap params = buildQueryMap(imageSearchParams); @@ -60,13 +66,28 @@ public void searchByImage(ProductSearchByImageParams imageSearchParams, final Pr if(imageBytes != null) { RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), imageBytes); MultipartBody.Part image = MultipartBody.Part.createFormData("image", "image", imageBody); - call = apiService.searchByImage(image, params); + call = getProductResponseCall(params, image, multiSearch); } else { - call = apiService.searchByImage(params); + call = getProductResponseCall(params, null, multiSearch); } handleCallback(call, listener); } + private Call getProductResponseCall(RetrofitQueryMap params, MultipartBody.Part image, boolean multiSearch) { + if (multiSearch) { + if (image == null) { + return apiService.multisearch(params); + } + + return apiService.multisearch(image, params); + } else { + if (image == null) { + return apiService.searchByImage(params); + } + + return apiService.searchByImage(image, params); + } + } private RetrofitQueryMap buildQueryMap(BaseProductSearchParams params) { From 46c1201ffc14ad90f9261959485953eb58226315 Mon Sep 17 00:00:00 2001 From: Hung Date: Mon, 27 Nov 2023 16:48:53 +0800 Subject: [PATCH 4/5] add product search autocomplete --- .../visearch/android/ProductSearch.java | 10 +- .../android/model/AutoCompleteResponse.java | 96 +++++++++++++ .../android/model/AutoCompleteResultItem.java | 28 ++++ .../visearch/android/model/ErrorData.java | 7 +- .../android/network/APIProductService.java | 10 ++ .../android/network/ProductSearchService.java | 134 ++++++++++++++---- 6 files changed, 251 insertions(+), 34 deletions(-) create mode 100644 visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResponse.java create mode 100644 visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResultItem.java diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java index 2d4dc82..e5e61c3 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java @@ -6,6 +6,7 @@ import com.visenze.datatracking.Tracker; import com.visenze.datatracking.VisenzeAnalytics; import com.visenze.datatracking.data.DataCollection; +import com.visenze.visearch.android.model.AutoCompleteResponse; import com.visenze.visearch.android.model.ErrorData; import com.visenze.visearch.android.model.ProductResponse; import com.visenze.visearch.android.network.ProductSearchService; @@ -39,7 +40,7 @@ public void searchById(ProductSearchByIdParams visualSimilarParams, ResultListen productSearchService.searchById(visualSimilarParams, listener); } - public void multisearcch(ProductSearchByImageParams imageSearchParams, ResultListener listener) { + public void multisearch(ProductSearchByImageParams imageSearchParams, ResultListener listener) { addAnalyticsParams(imageSearchParams); productSearchService.searchByImage(imageSearchParams, listener, true); } @@ -165,9 +166,12 @@ public ProductSearch build(Context context) { } } - public static interface ResultListener { - public void onSearchResult(final ProductResponse response, ErrorData error); + public interface ResultListener { + void onSearchResult(final ProductResponse response, ErrorData error); + } + public interface AutoCompleteResultListener { + void onResult(final AutoCompleteResponse response, ErrorData error); } } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResponse.java b/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResponse.java new file mode 100644 index 0000000..b85a2f3 --- /dev/null +++ b/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResponse.java @@ -0,0 +1,96 @@ +package com.visenze.visearch.android.model; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class AutoCompleteResponse { + + @SerializedName("status") + private String status; + + @SerializedName("method") + private String method; + + @SerializedName("error") + private ErrorData error; + + @SerializedName("result") + private List result; + + @SerializedName("page") + private int page; + + @SerializedName("limit") + private int limit; + + @SerializedName("total") + private int total; + + @SerializedName("reqid") + private String reqId; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public ErrorData getError() { + return error; + } + + public void setError(ErrorData error) { + this.error = error; + } + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public String getReqId() { + return reqId; + } + + public void setReqId(String reqId) { + this.reqId = reqId; + } +} diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResultItem.java b/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResultItem.java new file mode 100644 index 0000000..8968263 --- /dev/null +++ b/visearch-android/src/main/java/com/visenze/visearch/android/model/AutoCompleteResultItem.java @@ -0,0 +1,28 @@ +package com.visenze.visearch.android.model; + +import com.google.gson.annotations.SerializedName; + +public class AutoCompleteResultItem { + + @SerializedName("text") + private String text; + + @SerializedName("score") + private double score; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public double getScore() { + return score; + } + + public void setScore(double score) { + this.score = score; + } +} diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/model/ErrorData.java b/visearch-android/src/main/java/com/visenze/visearch/android/model/ErrorData.java index 3b4e2a0..a76e275 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/model/ErrorData.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/model/ErrorData.java @@ -27,5 +27,10 @@ public void setMessage(String message) { this.message = message; } - + public static ErrorData unknownError(String msg) { + ErrorData error = new ErrorData(); + error.setMessage(msg); + error.setCode(-1); + return error; + } } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java index b4c1222..1db80c8 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/APIProductService.java @@ -1,5 +1,6 @@ package com.visenze.visearch.android.network; +import com.visenze.visearch.android.model.AutoCompleteResponse; import com.visenze.visearch.android.model.ProductResponse; import com.visenze.visearch.android.network.retry.Retry; @@ -36,4 +37,13 @@ public interface APIProductService { @Multipart @POST("product/multisearch") Call multisearch(@Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); + + @Retry + @POST("product/multisearch/autocomplete") + Call multisearchAutocomplete(@QueryMap RetrofitQueryMap query); + + @Retry + @Multipart + @POST("product/multisearch/autocomplete") + Call multisearchAutocomplete(@Part MultipartBody.Part image, @QueryMap RetrofitQueryMap query); } diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java b/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java index 381d1d0..8a71d64 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/network/ProductSearchService.java @@ -5,6 +5,7 @@ import com.visenze.visearch.android.ProductSearchByImageParams; import com.visenze.visearch.android.ProductSearch; import com.visenze.visearch.android.ProductSearchByIdParams; +import com.visenze.visearch.android.model.AutoCompleteResponse; import com.visenze.visearch.android.model.ErrorData; import com.visenze.visearch.android.model.ProductResponse; @@ -44,6 +45,46 @@ public void searchByImage(ProductSearchByImageParams imageSearchParams, final Pr } public void searchByImage(ProductSearchByImageParams imageSearchParams, final ProductSearch.ResultListener listener, boolean multiSearch) { + byte[] imageBytes = validateImageParams(imageSearchParams, multiSearch); + + RetrofitQueryMap params = buildQueryMap(imageSearchParams); + + Call call; + if(imageBytes != null) { + RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), imageBytes); + MultipartBody.Part image = MultipartBody.Part.createFormData("image", "image", imageBody); + call = getProductResponseCall(params, image, multiSearch); + } else { + call = getProductResponseCall(params, null, multiSearch); + } + handleCallback(call, listener); + } + + public void multisearchAutocomplete(ProductSearchByImageParams imageSearchParams, + final ProductSearch.AutoCompleteResultListener listener) { + byte[] imageBytes = validateImageParams(imageSearchParams, true); + + RetrofitQueryMap params = buildQueryMap(imageSearchParams); + + Call call; + if(imageBytes != null) { + RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), imageBytes); + MultipartBody.Part image = MultipartBody.Part.createFormData("image", "image", imageBody); + call = getAutoCompleteResponseCall(params, image); + } else { + call = getAutoCompleteResponseCall(params, null); + } + handleCallback(call, listener); + } + + /** + * If not multi-search, 1 of image, im_url or im_id must be provided, throw Exception if missing + * + * @param imageSearchParams request params + * @param multiSearch whether this is multisearch related API or normal SBI + * @return image file bytes if provided + */ + private byte[] validateImageParams(ProductSearchByImageParams imageSearchParams, boolean multiSearch) { byte[] imageBytes = null; if (imageSearchParams.getImage() != null) { @@ -59,18 +100,7 @@ public void searchByImage(ProductSearchByImageParams imageSearchParams, final Pr throw new IllegalArgumentException("Please provide imUrl , imId or image parameter"); } } - - RetrofitQueryMap params = buildQueryMap(imageSearchParams); - - Call call; - if(imageBytes != null) { - RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), imageBytes); - MultipartBody.Part image = MultipartBody.Part.createFormData("image", "image", imageBody); - call = getProductResponseCall(params, image, multiSearch); - } else { - call = getProductResponseCall(params, null, multiSearch); - } - handleCallback(call, listener); + return imageBytes; } private Call getProductResponseCall(RetrofitQueryMap params, MultipartBody.Part image, boolean multiSearch) { @@ -89,6 +119,14 @@ private Call getProductResponseCall(RetrofitQueryMap params, Mu } } + private Call getAutoCompleteResponseCall(RetrofitQueryMap params, MultipartBody.Part image) { + if (image == null) { + return apiService.multisearchAutocomplete(params); + } + + return apiService.multisearchAutocomplete(image, params); + } + private RetrofitQueryMap buildQueryMap(BaseProductSearchParams params) { RetrofitQueryMap map = params.getQueryMap(); @@ -101,32 +139,28 @@ private void handleCallback(Call call, final ProductSearch.Resu call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { - if(response.isSuccessful() && response.body() !=null) { + if(response.isSuccessful() && response.body() != null) { ProductResponse data = response.body(); handleResponse(data, resultListener); - } else { - if (response.errorBody() != null) { - Gson gson = new Gson(); - ProductResponse resp = gson.fromJson(response.errorBody().charStream(), ProductResponse.class); - if (resp != null && resp.getError()!= null) { - resultListener.onSearchResult(null, resp.getError()); - return; - } + return; + } + + if (response.errorBody() != null) { + Gson gson = new Gson(); + ProductResponse resp = gson.fromJson(response.errorBody().charStream(), ProductResponse.class); + if (resp != null && resp.getError() != null) { + resultListener.onSearchResult(null, resp.getError()); + return; } - ErrorData error = new ErrorData(); - error.setMessage("api failed"); - error.setCode(-1); - resultListener.onSearchResult(null, error); } + + resultListener.onSearchResult(null, ErrorData.unknownError("api failed")); + } @Override public void onFailure(Call call, Throwable t) { - - ErrorData error = new ErrorData(); - error.setMessage(t.getMessage()); - error.setCode(-1); - resultListener.onSearchResult(null, error); + resultListener.onSearchResult(null, ErrorData.unknownError(t.getMessage())); } }); @@ -142,4 +176,44 @@ public void handleResponse(ProductResponse response, final ProductSearch.ResultL } } + private void handleCallback(Call call, final ProductSearch.AutoCompleteResultListener resultListener) { + call.enqueue(new Callback() { + + @Override + public void onResponse(Call call, Response response) { + if(response.isSuccessful() && response.body() != null) { + AutoCompleteResponse data = response.body(); + handleAutoCompleteResponse(data, resultListener); + return; + } + + if (response.errorBody() != null) { + Gson gson = new Gson(); + AutoCompleteResponse resp = gson.fromJson(response.errorBody().charStream(), AutoCompleteResponse.class); + if (resp != null && resp.getError() != null) { + resultListener.onResult(null, resp.getError()); + return; + } + } + + resultListener.onResult(null, ErrorData.unknownError("api failed")); + } + + @Override + public void onFailure(Call call, Throwable t) { + resultListener.onResult(null, ErrorData.unknownError(t.getMessage())); + } + + }); + } + + public void handleAutoCompleteResponse(AutoCompleteResponse response, final ProductSearch.AutoCompleteResultListener listener) { + ErrorData error = response.getError(); + if(error != null) { + listener.onResult(null, error); + } else { + listener.onResult(response, null); + } + } + } From 23793d312f4c4725d09b4dc7186fec4ad21b1c12 Mon Sep 17 00:00:00 2001 From: Hung Date: Mon, 27 Nov 2023 17:07:51 +0800 Subject: [PATCH 5/5] add autocomplete --- .../visearch/android/ProductSearch.java | 5 ++ .../visearch/android/ProductSearchTest.java | 51 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java index e5e61c3..c019d7a 100644 --- a/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java +++ b/visearch-android/src/main/java/com/visenze/visearch/android/ProductSearch.java @@ -45,6 +45,11 @@ public void multisearch(ProductSearchByImageParams imageSearchParams, ResultList productSearchService.searchByImage(imageSearchParams, listener, true); } + public void multisearchAutocomplete(ProductSearchByImageParams imageSearchParams, AutoCompleteResultListener listener) { + addAnalyticsParams(imageSearchParams); + productSearchService.multisearchAutocomplete(imageSearchParams, listener); + } + public void recommendations(ProductSearchByIdParams visualSimilarParams, ResultListener listener) { searchById(visualSimilarParams, listener); } diff --git a/visearch-android/src/test/java/com/visenze/visearch/android/ProductSearchTest.java b/visearch-android/src/test/java/com/visenze/visearch/android/ProductSearchTest.java index f9bf486..3749dd3 100644 --- a/visearch-android/src/test/java/com/visenze/visearch/android/ProductSearchTest.java +++ b/visearch-android/src/test/java/com/visenze/visearch/android/ProductSearchTest.java @@ -6,6 +6,8 @@ import com.google.common.base.Joiner; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.visenze.visearch.android.model.AutoCompleteResponse; +import com.visenze.visearch.android.model.AutoCompleteResultItem; import com.visenze.visearch.android.model.BestImage; import com.visenze.visearch.android.model.Box; import com.visenze.visearch.android.model.ErrorData; @@ -1014,6 +1016,55 @@ public void onSearchResult(ProductResponse response, ErrorData error) { } + @Test + public void testAutocompleteResponse() { + String json = + "{\n" + + " \"result\": [\n" + + " {\n" + + " \"text\": \"red1\",\n" + + " \"score\": 898.0\n" + + " },\n" + + " {\n" + + " \"text\": \"red valentino\",\n" + + " \"score\": 188.0\n" + + " },\n" + + " {\n" + + " \"text\": \"oscar de la renta\",\n" + + " \"score\": 46.0\n" + + " }\n" + + " ],\n" + + " \"method\": \"multisearch/autocomplete\",\n" + + " \"status\": \"OK\",\n" + + " \"page\": 1,\n" + + " \"reqid\": \"14952330933117065212\"\n" + + "}"; + + AutoCompleteResponse response = gson.fromJson(json, AutoCompleteResponse.class); + searchService.handleAutoCompleteResponse(response, new ProductSearch.AutoCompleteResultListener() { + @Override + public void onResult(AutoCompleteResponse response, ErrorData error) { + assertNull(error); + + assertEquals(1, response.getPage()); + assertEquals("14952330933117065212", response.getReqId()); + + AutoCompleteResultItem item = response.getResult().get(0); + assertEquals("red1", item.getText()); + assertTrue(898.0 == item.getScore()); + + AutoCompleteResultItem item2 = response.getResult().get(1); + assertEquals("red valentino", item2.getText()); + assertTrue(188.0 == item2.getScore()); + + AutoCompleteResultItem item3 = response.getResult().get(2); + assertEquals("oscar de la renta", item3.getText()); + assertTrue(46.0 == item3.getScore()); + } + }); + + } + private String getBoxString(Box box) { return box.getX1() + "," + box.getY1() + "," + box.getX2() + "," + box.getY2(); }