From 64938a0eb7b5dc59d7226ffebc39457e989fdf50 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Wed, 12 Nov 2025 23:10:00 +0700 Subject: [PATCH] feat(self scraper): try to crawl without country But fail --- README.md | 8 ++ lombok.config | 1 + .../api/apple/AppStoreScraper.java | 95 +++++++++++++++++++ .../api/apple/entity/AppleAppDetail.java | 13 +++ .../apple/request/ITunesLookupRequest.java | 20 ++++ .../apple/response/ITunesLookupResponse.java | 23 +++++ .../api/old/apple/AppStoreScraper.java | 4 +- .../api/old/google/GooglePlayScraper.java | 4 +- .../storescraperbot/bot/StoreScrapeBot.java | 6 +- .../bot/command/AddAppleAppCommand.java | 6 +- .../bot/command/AddGoogleAppCommand.java | 6 +- .../bot/command/AddGroupCommand.java | 4 +- .../bot/command/CheckAppCommand.java | 6 +- .../bot/command/CheckAppScoreCommand.java | 6 +- .../bot/command/DeleteAppleAppCommand.java | 6 +- .../bot/command/DeleteGoogleAppCommand.java | 6 +- .../bot/command/DeleteGroupCommand.java | 4 +- .../bot/command/ListAppCommand.java | 6 +- .../bot/command/ListGroupCommand.java | 2 +- .../bot/command/RawAppleAppCommand.java | 2 +- .../bot/command/RawGoogleAppCommand.java | 2 +- .../storescraperbot/model/AppleApp.java | 2 + .../repository/AbstractRepository.java | 2 +- .../storescraperbot/util/RequestUtil.java | 29 ++++++ .../api/apple/AppStoreScraperTest.java | 27 ++++++ 25 files changed, 254 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java create mode 100644 src/main/java/com/miti99/storescraperbot/api/apple/entity/AppleAppDetail.java create mode 100644 src/main/java/com/miti99/storescraperbot/api/apple/request/ITunesLookupRequest.java create mode 100644 src/main/java/com/miti99/storescraperbot/api/apple/response/ITunesLookupResponse.java create mode 100644 src/main/java/com/miti99/storescraperbot/util/RequestUtil.java create mode 100644 src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java diff --git a/README.md b/README.md index b19d497..665d534 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ # store-scraper-bot Telegram bot that support scrape infos of an app on stores + +## Credits + +Many thanks to [facundoolano](https://github.com/facundoolano)' +s [google-play-scraper](https://github.com/facundoolano/google-play-scraper) +and [app-store-scraper](https://github.com/facundoolano/app-store-scraper), myy api code are based +on +their logics. diff --git a/lombok.config b/lombok.config index 9bb7a6e..b1b08aa 100644 --- a/lombok.config +++ b/lombok.config @@ -1,3 +1,4 @@ +lombok.accessors.fluent = true lombok.addLombokGeneratedAnnotation = true lombok.experimental.flagUsage = error lombok.log.apacheCommons.flagUsage = error diff --git a/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java b/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java new file mode 100644 index 0000000..8cdc5e7 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java @@ -0,0 +1,95 @@ +package com.miti99.storescraperbot.api.apple; + +import com.miti99.storescraperbot.api.apple.entity.AppleAppDetail; +import com.miti99.storescraperbot.api.apple.request.ITunesLookupRequest; +import com.miti99.storescraperbot.api.apple.response.ITunesLookupResponse; +import com.miti99.storescraperbot.repository.AppleAppRepository; +import com.miti99.storescraperbot.util.GsonUtil; +import com.miti99.storescraperbot.util.RequestUtil; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpClient.Redirect; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse.BodyHandlers; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class AppStoreScraper { + private static final String LOOKUP_URL = "https://itunes.apple.com/lookup?"; + + @SneakyThrows + public static String rawLookup(ITunesLookupRequest request) { + var httpRequest = + HttpRequest.newBuilder() + .uri(URI.create(LOOKUP_URL + RequestUtil.makeGetParams(request))) + // .timeout(Duration.ofMillis(TIMEOUT)) + .header("Content-Type", "application/json") + .GET() + .build(); + + try (var httpClient = + HttpClient.newBuilder() + .followRedirects(Redirect.NORMAL) + // .connectTimeout(Duration.ofMillis(TIMEOUT)) + .build()) { + return httpClient.send(httpRequest, BodyHandlers.ofString()).body(); + } catch (Exception e) { + log.error("rawLookup error - request: '{}'", GsonUtil.toJson(request), e); + return null; + } + } + + @SneakyThrows + public static AppleAppDetail app(ITunesLookupRequest request) { + return GsonUtil.fromJson(rawLookup(request), ITunesLookupResponse.class).getAppDetail(); + } + + public static AppleAppDetail app(String appId) { + return app(new ITunesLookupRequest(appId)); + } + + public static AppleAppDetail app(long id) { + return app(new ITunesLookupRequest(id)); + } + + public static AppleAppDetail getAppResponse(String appId) { + boolean isInCache = AppleAppRepository.INSTANCE.exist(appId); + if (isInCache) { + var app = AppleAppRepository.INSTANCE.load(appId); + return app.detail(); + } else { + var response = app(appId); + AppleAppRepository.INSTANCE.init(appId); + var app = AppleAppRepository.INSTANCE.load(appId); + app.detail(response); + AppleAppRepository.INSTANCE.save(appId, app); + return response; + } + } + + public static LocalDate getAppUpdated(String appId) { + var detail = getAppResponse(appId); + if (detail == null) { + log.error("detail is null"); + return LocalDate.ofInstant(Instant.ofEpochMilli(0), ZoneId.systemDefault()); + } + return LocalDate.ofInstant( + Instant.parse(detail.currentVersionReleaseDate()), ZoneId.systemDefault()); + } + + public static double getAppScore(String appId) { + var response = getAppResponse(appId); + if (response == null) { + log.error("response is null"); + return 0.0; + } + return response.averageUserRating(); + } +} diff --git a/src/main/java/com/miti99/storescraperbot/api/apple/entity/AppleAppDetail.java b/src/main/java/com/miti99/storescraperbot/api/apple/entity/AppleAppDetail.java new file mode 100644 index 0000000..79760db --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/api/apple/entity/AppleAppDetail.java @@ -0,0 +1,13 @@ +package com.miti99.storescraperbot.api.apple.entity; + +import lombok.Value; + +/** + * Chỉ define một số field cần thiết nên không đầy đủ. Khi cần thì check raw response để define thêm + */ +@Value +public class AppleAppDetail { + String bundleId; + String currentVersionReleaseDate; + double averageUserRating; +} diff --git a/src/main/java/com/miti99/storescraperbot/api/apple/request/ITunesLookupRequest.java b/src/main/java/com/miti99/storescraperbot/api/apple/request/ITunesLookupRequest.java new file mode 100644 index 0000000..b8bb058 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/api/apple/request/ITunesLookupRequest.java @@ -0,0 +1,20 @@ +package com.miti99.storescraperbot.api.apple.request; + +import lombok.RequiredArgsConstructor; +import lombok.Value; + +@RequiredArgsConstructor +@Value +public class ITunesLookupRequest { + Long id; + String bundleId; + String entity = "software"; + + public ITunesLookupRequest(Long id) { + this(id, null); + } + + public ITunesLookupRequest(String bundleId) { + this(null, bundleId); + } +} diff --git a/src/main/java/com/miti99/storescraperbot/api/apple/response/ITunesLookupResponse.java b/src/main/java/com/miti99/storescraperbot/api/apple/response/ITunesLookupResponse.java new file mode 100644 index 0000000..9e19a14 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/api/apple/response/ITunesLookupResponse.java @@ -0,0 +1,23 @@ +package com.miti99.storescraperbot.api.apple.response; + +import com.miti99.storescraperbot.api.apple.entity.AppleAppDetail; +import com.miti99.storescraperbot.util.GsonUtil; +import java.util.List; +import lombok.Value; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +@Value +public class ITunesLookupResponse { + int resultCount; + List results; + + public AppleAppDetail getAppDetail() { + if (resultCount != 1) { + log.warn("resultCount('{}') != 1", resultCount); + log.warn("results: {}", GsonUtil.toJson(results)); + } + + return results.getFirst(); + } +} diff --git a/src/main/java/com/miti99/storescraperbot/api/old/apple/AppStoreScraper.java b/src/main/java/com/miti99/storescraperbot/api/old/apple/AppStoreScraper.java index a1f626c..35a4370 100644 --- a/src/main/java/com/miti99/storescraperbot/api/old/apple/AppStoreScraper.java +++ b/src/main/java/com/miti99/storescraperbot/api/old/apple/AppStoreScraper.java @@ -54,12 +54,12 @@ public class AppStoreScraper { boolean isInCache = AppleAppRepository.INSTANCE.exist(appId); if (isInCache) { var app = AppleAppRepository.INSTANCE.load(appId); - return app.getApp(); + return app.app(); } else { var response = app(new AppleAppRequest(appId, country)); AppleAppRepository.INSTANCE.init(appId); var app = AppleAppRepository.INSTANCE.load(appId); - app.setApp(response); + app.app(response); AppleAppRepository.INSTANCE.save(appId, app); return response; } diff --git a/src/main/java/com/miti99/storescraperbot/api/old/google/GooglePlayScraper.java b/src/main/java/com/miti99/storescraperbot/api/old/google/GooglePlayScraper.java index 94b1bc7..f0f9d1b 100644 --- a/src/main/java/com/miti99/storescraperbot/api/old/google/GooglePlayScraper.java +++ b/src/main/java/com/miti99/storescraperbot/api/old/google/GooglePlayScraper.java @@ -53,12 +53,12 @@ public class GooglePlayScraper { boolean isInCache = GoogleAppRepository.INSTANCE.exist(appId); if (isInCache) { var app = GoogleAppRepository.INSTANCE.load(appId); - return app.getApp(); + return app.app(); } else { var response = app(new GoogleAppRequest(appId, country)); GoogleAppRepository.INSTANCE.init(appId); var app = GoogleAppRepository.INSTANCE.load(appId); - app.setApp(response); + app.app(response); GoogleAppRepository.INSTANCE.save(appId, app); return response; } diff --git a/src/main/java/com/miti99/storescraperbot/bot/StoreScrapeBot.java b/src/main/java/com/miti99/storescraperbot/bot/StoreScrapeBot.java index a1b72fb..4b5d2cd 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/StoreScrapeBot.java +++ b/src/main/java/com/miti99/storescraperbot/bot/StoreScrapeBot.java @@ -79,7 +79,7 @@ public class StoreScrapeBot extends CommandLongPollingTelegramBot { public void runCheckApp() { var admin = AdminRepository.INSTANCE.load(); - for (var groupId : admin.getGroups()) { + for (var groupId : admin.groups()) { checkAppForGroup(groupId); } } @@ -89,7 +89,7 @@ public class StoreScrapeBot extends CommandLongPollingTelegramBot { var now = LocalDate.now(); var nonUpdatedAppleApps = new ArrayList(); - for (var app : group.getAppleApps()) { + for (var app : group.appleApps()) { var appId = app.appId(); var updated = AppStoreScraper.getAppUpdated(appId, app.country()); long days = ChronoUnit.DAYS.between(updated, now); @@ -98,7 +98,7 @@ public class StoreScrapeBot extends CommandLongPollingTelegramBot { } } var nonUpdatedGoogleApps = new ArrayList(); - for (var app : group.getGoogleApps()) { + for (var app : group.googleApps()) { var appId = app.appId(); var updated = GooglePlayScraper.getLastUpdateOfApp(appId, app.country()); long days = ChronoUnit.DAYS.between(updated, now); diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/AddAppleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/AddAppleAppCommand.java index fc38d00..309c64d 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/AddAppleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/AddAppleAppCommand.java @@ -26,7 +26,7 @@ public class AddAppleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -64,13 +64,13 @@ public class AddAppleAppCommand extends BaseStoreScraperBotCommand { var group = GroupRepository.INSTANCE.load(groupId); var finalAppId = appId; - if (group.getAppleApps().stream().anyMatch(app -> finalAppId.equals(app.appId()))) { + if (group.appleApps().stream().anyMatch(app -> finalAppId.equals(app.appId()))) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Apple app %s is already added".formatted(appId)); return; } - group.getAppleApps().add(new AppleAppInfo(appId, country)); + group.appleApps().add(new AppleAppInfo(appId, country)); GroupRepository.INSTANCE.save(groupId, group); StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/AddGoogleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/AddGoogleAppCommand.java index 12b909f..c2a1eb8 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/AddGoogleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/AddGoogleAppCommand.java @@ -26,7 +26,7 @@ public class AddGoogleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -52,13 +52,13 @@ public class AddGoogleAppCommand extends BaseStoreScraperBotCommand { long groupId = chat.getId(); var group = GroupRepository.INSTANCE.load(groupId); - if (group.getGoogleApps().stream().anyMatch(app -> appId.equals(app.appId()))) { + if (group.googleApps().stream().anyMatch(app -> appId.equals(app.appId()))) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Google app %s is already added".formatted(appId)); return; } - group.getGoogleApps().add(new GoogleAppInfo(appId, country)); + group.googleApps().add(new GoogleAppInfo(appId, country)); GroupRepository.INSTANCE.save(groupId, group); StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/AddGroupCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/AddGroupCommand.java index 2e61d74..776c67a 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/AddGroupCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/AddGroupCommand.java @@ -41,13 +41,13 @@ public class AddGroupCommand extends BaseStoreScraperBotCommand { } var admin = AdminRepository.INSTANCE.load(); - if (admin.getGroups().contains(groupId)) { + if (admin.groups().contains(groupId)) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group is already added"); return; } GroupRepository.INSTANCE.init(groupId); - admin.getGroups().add(groupId); + admin.groups().add(groupId); AdminRepository.INSTANCE.save(admin); StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group added successfully"); } diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppCommand.java index 3a4af7e..258c02c 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppCommand.java @@ -24,7 +24,7 @@ public class CheckAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -43,7 +43,7 @@ public class CheckAppCommand extends BaseStoreScraperBotCommand { sb.append("Apple Apps:\n"); sb.append("\n"); var appleTable = new Table("AppId", "Updated", "Days", "OK"); - for (var app : group.getAppleApps()) { + for (var app : group.appleApps()) { var appId = app.appId(); var updated = AppStoreScraper.getAppUpdated(appId, app.country()); long days = ChronoUnit.DAYS.between(updated, now); @@ -57,7 +57,7 @@ public class CheckAppCommand extends BaseStoreScraperBotCommand { sb.append("Google Apps:\n"); sb.append("\n"); var googleTable = new Table("AppId", "Updated", "Days", "OK"); - for (var app : group.getGoogleApps()) { + for (var app : group.googleApps()) { var appId = app.appId(); var updated = GooglePlayScraper.getLastUpdateOfApp(appId, app.country()); long days = ChronoUnit.DAYS.between(updated, now); diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppScoreCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppScoreCommand.java index ac78789..2a24c92 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppScoreCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/CheckAppScoreCommand.java @@ -23,7 +23,7 @@ public class CheckAppScoreCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -41,7 +41,7 @@ public class CheckAppScoreCommand extends BaseStoreScraperBotCommand { sb.append("Apple Apps:\n"); sb.append("\n"); var appleTable = new Table("AppId", "Score", "Ratings"); - for (var app : group.getAppleApps()) { + for (var app : group.appleApps()) { var appId = app.appId(); var country = app.country(); double score = @@ -55,7 +55,7 @@ public class CheckAppScoreCommand extends BaseStoreScraperBotCommand { sb.append("Google Apps:\n"); sb.append("\n"); var googleTable = new Table("AppId", "Score", "Ratings"); - for (var app : group.getGoogleApps()) { + for (var app : group.googleApps()) { var appId = app.appId(); var country = app.country(); double score = diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteAppleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteAppleAppCommand.java index baa9d1f..9865540 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteAppleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteAppleAppCommand.java @@ -18,7 +18,7 @@ public class DeleteAppleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -33,12 +33,12 @@ public class DeleteAppleAppCommand extends BaseStoreScraperBotCommand { long groupId = chat.getId(); var group = GroupRepository.INSTANCE.load(groupId); - if (group.getAppleApps().stream().noneMatch(app -> appId.equals(app.appId()))) { + if (group.appleApps().stream().noneMatch(app -> appId.equals(app.appId()))) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Apple app is not added"); return; } - group.getAppleApps().removeIf(app -> appId.equals(app.appId())); + group.appleApps().removeIf(app -> appId.equals(app.appId())); GroupRepository.INSTANCE.save(groupId, group); StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Apple app deleted successfully"); diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGoogleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGoogleAppCommand.java index 912e774..ce388e7 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGoogleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGoogleAppCommand.java @@ -18,7 +18,7 @@ public class DeleteGoogleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -33,12 +33,12 @@ public class DeleteGoogleAppCommand extends BaseStoreScraperBotCommand { long groupId = chat.getId(); var group = GroupRepository.INSTANCE.load(groupId); - if (group.getGoogleApps().stream().noneMatch(app -> appId.equals(app.appId()))) { + if (group.googleApps().stream().noneMatch(app -> appId.equals(app.appId()))) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Google app is not added"); return; } - group.getGoogleApps().removeIf(app -> appId.equals(app.appId())); + group.googleApps().removeIf(app -> appId.equals(app.appId())); GroupRepository.INSTANCE.save(groupId, group); StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Google app deleted successfully"); diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGroupCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGroupCommand.java index 5cfd9a6..5cc5400 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGroupCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/DeleteGroupCommand.java @@ -40,12 +40,12 @@ public class DeleteGroupCommand extends BaseStoreScraperBotCommand { } var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(groupId)) { + if (!admin.groups().contains(groupId)) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group is not added"); return; } - admin.getGroups().remove(groupId); + admin.groups().remove(groupId); AdminRepository.INSTANCE.save(admin); StoreScrapeBotTelegramClient.INSTANCE.sendMessage(chat.getId(), "Group deleted successfully"); } diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/ListAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/ListAppCommand.java index 138fc77..896faf5 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/ListAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/ListAppCommand.java @@ -19,7 +19,7 @@ public class ListAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; @@ -38,7 +38,7 @@ public class ListAppCommand extends BaseStoreScraperBotCommand { sb.append("\n"); var appleTable = new Table("#", "AppId", "Country"); int i = 0; - for (var app : group.getAppleApps()) { + for (var app : group.appleApps()) { i++; appleTable.addRow(i, app.appId(), app.country()); } @@ -49,7 +49,7 @@ public class ListAppCommand extends BaseStoreScraperBotCommand { sb.append("\n"); var googleTable = new Table("#", "AppId", "Country"); i = 0; - for (var app : group.getGoogleApps()) { + for (var app : group.googleApps()) { i++; googleTable.addRow(i, app.appId(), app.country()); } diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/ListGroupCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/ListGroupCommand.java index bf1fe52..5c837d7 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/ListGroupCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/ListGroupCommand.java @@ -28,7 +28,7 @@ public class ListGroupCommand extends BaseStoreScraperBotCommand { } var admin = AdminRepository.INSTANCE.load(); - var groups = admin.getGroups(); + var groups = admin.groups(); var sb = new StringBuilder(); sb.append("Groups:\n"); for (var groupId : groups) { diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/RawAppleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/RawAppleAppCommand.java index 7866760..fe1b804 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/RawAppleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/RawAppleAppCommand.java @@ -29,7 +29,7 @@ public class RawAppleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; diff --git a/src/main/java/com/miti99/storescraperbot/bot/command/RawGoogleAppCommand.java b/src/main/java/com/miti99/storescraperbot/bot/command/RawGoogleAppCommand.java index f3aa693..2ac9044 100644 --- a/src/main/java/com/miti99/storescraperbot/bot/command/RawGoogleAppCommand.java +++ b/src/main/java/com/miti99/storescraperbot/bot/command/RawGoogleAppCommand.java @@ -29,7 +29,7 @@ public class RawGoogleAppCommand extends BaseStoreScraperBotCommand { protected void executeCommand( TelegramClient telegramClient, User user, Chat chat, String[] arguments) { var admin = AdminRepository.INSTANCE.load(); - if (!admin.getGroups().contains(chat.getId())) { + if (!admin.groups().contains(chat.getId())) { StoreScrapeBotTelegramClient.INSTANCE.sendMessage( chat.getId(), "Group is not allowed to use bot"); return; diff --git a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java index 4a80210..d542224 100644 --- a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java +++ b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java @@ -1,5 +1,6 @@ package com.miti99.storescraperbot.model; +import com.miti99.storescraperbot.api.apple.entity.AppleAppDetail; import com.miti99.storescraperbot.api.old.apple.response.AppleAppResponse; import lombok.Getter; import lombok.Setter; @@ -8,4 +9,5 @@ import lombok.Setter; @Setter public class AppleApp extends AbstractModel { AppleAppResponse app; + AppleAppDetail detail; } diff --git a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java index 330c3e1..14a367d 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java @@ -71,7 +71,7 @@ public abstract class AbstractRepository> { return; } V data = classV.getDeclaredConstructor().newInstance(); - data.setKey(key); + data.key(key); save(key, data); } catch (Exception e) { log.error("Error while initializing data", e); diff --git a/src/main/java/com/miti99/storescraperbot/util/RequestUtil.java b/src/main/java/com/miti99/storescraperbot/util/RequestUtil.java new file mode 100644 index 0000000..7715348 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/util/RequestUtil.java @@ -0,0 +1,29 @@ +package com.miti99.storescraperbot.util; + +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class RequestUtil { + private static final Type MAP_STRING_STRING_TYPE = + new TypeToken>() {}.getType(); + + private static Map objToMapStringString(Object obj) { + return GsonUtil.GSON.fromJson(GsonUtil.GSON.toJson(obj), MAP_STRING_STRING_TYPE); + } + + public static String makeGetParams(Map params) { + return params.entrySet().stream() + .filter(entry -> entry.getValue() != null) + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("&")); + } + + public static String makeGetParams(Object obj) { + return makeGetParams(objToMapStringString(obj)); + } +} diff --git a/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java b/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java new file mode 100644 index 0000000..3b8c68a --- /dev/null +++ b/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java @@ -0,0 +1,27 @@ +package com.miti99.storescraperbot.api.apple; + +import static org.junit.jupiter.api.Assertions.*; + +import com.miti99.storescraperbot.util.GsonUtil; +import org.junit.jupiter.api.Test; + +class AppStoreScraperTest { + @Test + void testComMptKvtm() { + var response = AppStoreScraper.app("com.mpt.kvtm"); + System.out.println(GsonUtil.toJson(response)); + } + + @Test + void testComMptBuraco() { + // var response = AppStoreScraper.app("com.mpt.buraco"); + var response = AppStoreScraper.app(1638264682); + System.out.println(GsonUtil.toJson(response)); + } + + @Test + void testComMptDoudizhu() { + var response = AppStoreScraper.app("com.mpt.doudizhu"); + System.out.println(GsonUtil.toJson(response)); + } +}