From b3479587726cce417eb02231c6b9e1d1498a52cc Mon Sep 17 00:00:00 2001 From: vladp Date: Sun, 22 Feb 2026 02:40:28 +0700 Subject: [PATCH] dev add another client for google and yandex --- .../service/search/SearchImageService.java | 176 +++++++++--------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java b/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java index b90a79b..c96b9c0 100644 --- a/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java +++ b/src/main/java/ru/soune/nocopy/service/search/SearchImageService.java @@ -49,10 +49,10 @@ public class SearchImageService { public SearchImageService() { this.yandexHttpClient = new OkHttpClient.Builder() - .connectTimeout(18, TimeUnit.SECONDS) - .writeTimeout(18, TimeUnit.SECONDS) - .readTimeout(18, TimeUnit.SECONDS) - .callTimeout(18, TimeUnit.SECONDS) + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .callTimeout(15, TimeUnit.SECONDS) .followRedirects(true) .followSslRedirects(true) .retryOnConnectionFailure(true) @@ -61,10 +61,10 @@ public class SearchImageService { .build(); this.googleHttpClient = new OkHttpClient.Builder() - .connectTimeout(18, TimeUnit.SECONDS) - .writeTimeout(18, TimeUnit.SECONDS) - .readTimeout(18, TimeUnit.SECONDS) - .callTimeout(18, TimeUnit.SECONDS) + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(15, TimeUnit.SECONDS) + .readTimeout(15, TimeUnit.SECONDS) + .callTimeout(15, TimeUnit.SECONDS) .followRedirects(true) .followSslRedirects(true) .retryOnConnectionFailure(true) @@ -127,6 +127,72 @@ public class SearchImageService { return mimeType != null && mimeType.startsWith("image"); } +// private String callReverseImageApiByUrl(String imageUrl, String engine, String searchType) throws IOException { +// if (searchApiKey == null || searchApiKey.isBlank()) { +// throw new IllegalStateException("SearchAPI key not configured"); +// } +// +// OkHttpClient client = engine.contains("yandex_reverse_image") ? yandexHttpClient : googleHttpClient; +// +// HttpUrl url = HttpUrl.parse("https://www.searchapi.io/api/v1/search") +// .newBuilder() +// .addQueryParameter("engine", engine) +// .addQueryParameter("api_key", searchApiKey) +// .addQueryParameter("url", imageUrl) +// .addQueryParameter("search_type", searchType) +// .addQueryParameter("t_", String.valueOf(System.currentTimeMillis())) +// .build(); +// +// Request request = new Request.Builder() +// .url(url) +// .header("Accept", "application/json") +// .header("User-Agent", "Mozilla/5.0") +// .build(); +// +// int maxAttempts = 2; +// IOException lastException = null; +// +// for (int attempt = 1; attempt <= maxAttempts; attempt++) { +// long start = System.currentTimeMillis(); +// +// try (Response response = client.newCall(request).execute()) { +// long duration = System.currentTimeMillis() - start; +// log.info("Yandex response code={}, duration={}ms, attempt={}", +// response.code(), duration, attempt); +// +// if (!response.isSuccessful()) { +// throw new IOException("API error: " + response.code()); +// } +// +// ResponseBody body = response.body(); +// if (body == null) { +// throw new IOException("Empty response body"); +// } +// +// return body.string(); +// +// } catch (IOException e) { +// lastException = e; +// log.warn("Attempt {} failed for image: {}, error: {}", +// attempt, imageUrl, e.getMessage()); +// +// if (attempt == maxAttempts) { +// log.error("All {} attempts failed for image: {}", maxAttempts, imageUrl); +// throw lastException; +// } +// +// try { +// Thread.sleep(500L * attempt); +// } catch (InterruptedException ie) { +// Thread.currentThread().interrupt(); +// throw new IOException("Retry interrupted", ie); +// } +// } +// } +// +// throw lastException; +// } + private String callReverseImageApiByUrl(String imageUrl, String engine, String searchType) throws IOException { if (searchApiKey == null || searchApiKey.isBlank()) { throw new IllegalStateException("SearchAPI key not configured"); @@ -149,91 +215,27 @@ public class SearchImageService { .header("User-Agent", "Mozilla/5.0") .build(); - int maxAttempts = 3; - IOException lastException = null; + long start = System.currentTimeMillis(); - for (int attempt = 1; attempt <= maxAttempts; attempt++) { - long start = System.currentTimeMillis(); + try (Response response = client.newCall(request).execute()) { + long duration = System.currentTimeMillis() - start; + log.info("SearchAPI response code={}, duration={}ms, engine={}", + response.code(), duration, engine); - try (Response response = client.newCall(request).execute()) { - long duration = System.currentTimeMillis() - start; - log.info("Yandex response code={}, duration={}ms, attempt={}", - response.code(), duration, attempt); - - if (!response.isSuccessful()) { - throw new IOException("API error: " + response.code()); - } - - ResponseBody body = response.body(); - if (body == null) { - throw new IOException("Empty response body"); - } - - return body.string(); - - } catch (IOException e) { - lastException = e; - log.warn("Attempt {} failed for image: {}, error: {}", - attempt, imageUrl, e.getMessage()); - - if (attempt == maxAttempts) { - log.error("All {} attempts failed for image: {}", maxAttempts, imageUrl); - throw lastException; - } - - try { - Thread.sleep(500L * attempt); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - throw new IOException("Retry interrupted", ie); - } + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "null"; + throw new IOException("API error " + response.code() + ": " + errorBody); } + + ResponseBody body = response.body(); + if (body == null) { + throw new IOException("Empty response body"); + } + + return body.string(); } - - throw lastException; } - -// private String callReverseImageApiByUrl(String imageUrl, String engine, String searchType) throws IOException { -// -// if (searchApiKey == null || searchApiKey.isBlank()) { -// throw new IllegalStateException("SearchAPI key not configured"); -// } -// -// HttpUrl url = HttpUrl.parse("https://searchapi.io/api/v1/search") -// .newBuilder() -// .addQueryParameter("engine", engine) -// .addQueryParameter("api_key", searchApiKey) -// .addQueryParameter("url", imageUrl) -// .addQueryParameter("search_type", searchType) -// .build(); -// -// Request request = new Request.Builder() -// .url(url) -// .header("Accept", "application/json") -// .header("User-Agent", "Mozilla/5.0") -// .build(); -// -// long start = System.currentTimeMillis(); -// -// try (Response response = httpClient.newCall(request).execute()) { -// -// long duration = System.currentTimeMillis() - start; -// log.info("Yandex response code={}, duration={}ms", response.code(), duration); -// -// if (!response.isSuccessful()) { -// throw new IOException("API error: " + response.code()); -// } -// -// ResponseBody body = response.body(); -// if (body == null) { -// throw new IOException("Empty response body"); -// } -// -// return body.string(); -// } -// } - public List getAllImagesWithoutPagination(String searchApiJson, String findType) throws IOException { JsonNode root = objectMapper.readTree(searchApiJson);