diff --git a/src/main/java/core_service/modules/library/service/IgdbLookup.java b/src/main/java/core_service/modules/library/service/IgdbLookup.java new file mode 100644 index 0000000..0292dad --- /dev/null +++ b/src/main/java/core_service/modules/library/service/IgdbLookup.java @@ -0,0 +1,54 @@ +package core_service.modules.library.service; + +import core_service.modules.library.domain.GameKeys; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Function; + +/** + * IGDB finds a Steam game by its appid and a game off Steam by its IGDB id: one call per key kind, answers by appid. + */ +final class IgdbLookup { + + /** + * @param answered the appids whose call worked, sorted; an appid without a value in {@code found} has no data + */ + record Answer(Set answered, Map found) {} + + private IgdbLookup() { + } + + static Answer byAppid(Collection appids, + Function, Optional>> bySteamAppid, + Function, Optional>> byIgdbId) { + Set steamAppids = new TreeSet<>(); + Set igdbIds = new TreeSet<>(); + for (Long appid : appids) { + if (GameKeys.isSteam(appid)) { + steamAppids.add(appid); + } else { + igdbIds.add(GameKeys.igdbId(appid)); + } + } + Map found = new HashMap<>(); + Set answered = new TreeSet<>(); + if (!steamAppids.isEmpty()) { + bySteamAppid.apply(steamAppids).ifPresent(values -> { + found.putAll(values); + answered.addAll(steamAppids); + }); + } + if (!igdbIds.isEmpty()) { + byIgdbId.apply(igdbIds).ifPresent(values -> { + values.forEach((igdbId, value) -> found.put(GameKeys.ofIgdb(igdbId), value)); + igdbIds.forEach(igdbId -> answered.add(GameKeys.ofIgdb(igdbId))); + }); + } + return new Answer<>(answered, found); + } +} diff --git a/src/main/java/core_service/modules/library/service/MoodService.java b/src/main/java/core_service/modules/library/service/MoodService.java index ad6b33d..5e21f16 100644 --- a/src/main/java/core_service/modules/library/service/MoodService.java +++ b/src/main/java/core_service/modules/library/service/MoodService.java @@ -1,7 +1,6 @@ package core_service.modules.library.service; import core_service.modules.igdb_adapter.service.IgdbApiService; -import core_service.modules.library.domain.GameKeys; import core_service.modules.library.domain.Mood; import core_service.modules.library.repo.GameMoodsRepository; import core_service.modules.library.repo.UserGameRepository; @@ -14,7 +13,6 @@ import org.springframework.stereotype.Service; import java.time.Duration; import java.time.Instant; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -42,29 +40,10 @@ public class MoodService { stale.removeAll(gameMoodsRepository.findFreshAppids(appids, Instant.now().minus(Duration.ofDays(ttlDays)))); if (stale.isEmpty()) return; - Set steamAppids = new TreeSet<>(); - Set igdbIds = new TreeSet<>(); - for (Long appid : stale) { - if (GameKeys.isSteam(appid)) { - steamAppids.add(appid); - } else { - igdbIds.add(GameKeys.igdbId(appid)); - } - } - Map tags = new HashMap<>(); - Set answered = new TreeSet<>(); - if (!steamAppids.isEmpty()) { - igdbApiService.getGameTags(steamAppids).ifPresent(found -> { - tags.putAll(found); - answered.addAll(steamAppids); - }); - } - if (!igdbIds.isEmpty()) { - igdbApiService.getGameTagsByGameIds(igdbIds).ifPresent(found -> { - found.forEach((igdbId, gameTags) -> tags.put(GameKeys.ofIgdb(igdbId), gameTags)); - igdbIds.forEach(igdbId -> answered.add(GameKeys.ofIgdb(igdbId))); - }); - } + IgdbLookup.Answer answer = IgdbLookup.byAppid(stale, igdbApiService::getGameTags, + igdbApiService::getGameTagsByGameIds); + Set answered = answer.answered(); + Map tags = answer.found(); if (answered.size() < stale.size()) { log.warn("Moods of {} games not refreshed, IGDB did not answer", stale.size() - answered.size()); } diff --git a/src/main/java/core_service/modules/library/service/TimeToBeatService.java b/src/main/java/core_service/modules/library/service/TimeToBeatService.java index 1b147ac..10b056c 100644 --- a/src/main/java/core_service/modules/library/service/TimeToBeatService.java +++ b/src/main/java/core_service/modules/library/service/TimeToBeatService.java @@ -1,7 +1,6 @@ package core_service.modules.library.service; import core_service.modules.igdb_adapter.service.IgdbApiService; -import core_service.modules.library.domain.GameKeys; import core_service.modules.library.repo.GameTimeToBeatRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -12,7 +11,6 @@ import org.springframework.stereotype.Service; import java.time.Duration; import java.time.Instant; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -51,29 +49,10 @@ public class TimeToBeatService { stale.removeAll(gameTimeToBeatRepository.findFreshAppids(appids, Instant.now().minus(Duration.ofDays(ttlDays)))); if (stale.isEmpty()) return; - Set steamAppids = new TreeSet<>(); - Set igdbIds = new TreeSet<>(); - for (Long appid : stale) { - if (GameKeys.isSteam(appid)) { - steamAppids.add(appid); - } else { - igdbIds.add(GameKeys.igdbId(appid)); - } - } - Map times = new HashMap<>(); - Set answered = new TreeSet<>(); - if (!steamAppids.isEmpty()) { - igdbApiService.getTimeToBeat(steamAppids).ifPresent(found -> { - times.putAll(found); - answered.addAll(steamAppids); - }); - } - if (!igdbIds.isEmpty()) { - igdbApiService.getTimeToBeatByGameIds(igdbIds).ifPresent(found -> { - found.forEach((igdbId, time) -> times.put(GameKeys.ofIgdb(igdbId), time)); - igdbIds.forEach(igdbId -> answered.add(GameKeys.ofIgdb(igdbId))); - }); - } + IgdbLookup.Answer answer = IgdbLookup.byAppid(stale, igdbApiService::getTimeToBeat, + igdbApiService::getTimeToBeatByGameIds); + Set answered = answer.answered(); + Map times = answer.found(); if (answered.size() < stale.size()) { log.warn("Time to beat for {} apps not refreshed, IGDB did not answer", stale.size() - answered.size()); }