From 130ec4565d3abbf37a719afa7aaac84f19d611bb Mon Sep 17 00:00:00 2001 From: shawly Date: Wed, 19 Oct 2022 23:35:24 +0200 Subject: [PATCH] feat(refresh): added refresh button on game detail view to refresh metadata Resolves grimsi/gameyfin#45 --- .../grimsi/gameyfin/rest/GamesController.java | 7 ++++++- .../grimsi/gameyfin/service/GameService.java | 15 +++++++++++++-- frontend/src/app/api/GamesApi.ts | 1 + .../game-detail-view.component.html | 3 +++ .../game-detail-view.component.ts | 18 ++++++++++++++++++ frontend/src/app/services/games.service.ts | 4 ++++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/de/grimsi/gameyfin/rest/GamesController.java b/backend/src/main/java/de/grimsi/gameyfin/rest/GamesController.java index 156988a..25661f8 100644 --- a/backend/src/main/java/de/grimsi/gameyfin/rest/GamesController.java +++ b/backend/src/main/java/de/grimsi/gameyfin/rest/GamesController.java @@ -44,7 +44,7 @@ public class GamesController { return gameService.getAllMappings(); } - @GetMapping(value="/game/{slug}/download") + @GetMapping(value = "/game/{slug}/download") public ResponseEntity downloadGameFiles(@PathVariable String slug) { DetectedGame game = gameService.getDetectedGame(slug); @@ -57,4 +57,9 @@ public class GamesController { .body(out -> downloadService.sendGamefilesToClient(game, out)); } + @GetMapping(value = "/game/{slug}/refresh", produces = MediaType.APPLICATION_JSON_VALUE) + public DetectedGame refreshGame(@PathVariable String slug) { + return gameService.refreshGame(slug); + } + } diff --git a/backend/src/main/java/de/grimsi/gameyfin/service/GameService.java b/backend/src/main/java/de/grimsi/gameyfin/service/GameService.java index 3fd2a82..0c36729 100644 --- a/backend/src/main/java/de/grimsi/gameyfin/service/GameService.java +++ b/backend/src/main/java/de/grimsi/gameyfin/service/GameService.java @@ -9,6 +9,7 @@ import de.grimsi.gameyfin.mapper.GameMapper; import de.grimsi.gameyfin.repositories.DetectedGameRepository; import de.grimsi.gameyfin.repositories.UnmappableFileRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @@ -20,6 +21,7 @@ import java.util.Optional; import java.util.stream.Collectors; @RequiredArgsConstructor +@Slf4j @Service public class GameService { @@ -87,6 +89,17 @@ public class GameService { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Path '%s' not in database".formatted(path)); } + public DetectedGame refreshGame(String slug) { + Optional optionalDetectedGame = detectedGameRepository.findById(slug); + + if (optionalDetectedGame.isPresent()) { + log.info("Refreshing game with slug '{}'", slug); + return mapDetectedGame(optionalDetectedGame.get(), slug); + } + + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Game with slug '%s' not found in database".formatted(slug)); + } + private DetectedGame mapUnmappableFile(UnmappableFile unmappableFile, String slug) { Igdb.Game igdbGame = igdbWrapper.getGameBySlug(slug) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Game with slug '%s' does not exist on IGDB.".formatted(slug))); @@ -106,8 +119,6 @@ public class GameService { DetectedGame game = gameMapper.toDetectedGame(igdbGame, Path.of(existingGame.getPath())); game = detectedGameRepository.save(game); - detectedGameRepository.deleteById(existingGame.getSlug()); - return game; } } diff --git a/frontend/src/app/api/GamesApi.ts b/frontend/src/app/api/GamesApi.ts index b198553..aa24c14 100644 --- a/frontend/src/app/api/GamesApi.ts +++ b/frontend/src/app/api/GamesApi.ts @@ -7,4 +7,5 @@ export interface GamesApi { getGame(slug: String): Observable; getGameOverviews(): Observable; getAllGameMappings(): Observable>; + refreshGame(slug: String): Observable; } diff --git a/frontend/src/app/components/game-detail-view/game-detail-view.component.html b/frontend/src/app/components/game-detail-view/game-detail-view.component.html index 8d2d39b..e9798f7 100644 --- a/frontend/src/app/components/game-detail-view/game-detail-view.component.html +++ b/frontend/src/app/components/game-detail-view/game-detail-view.component.html @@ -33,6 +33,9 @@
+ diff --git a/frontend/src/app/components/game-detail-view/game-detail-view.component.ts b/frontend/src/app/components/game-detail-view/game-detail-view.component.ts index 444f1b0..88f6db7 100644 --- a/frontend/src/app/components/game-detail-view/game-detail-view.component.ts +++ b/frontend/src/app/components/game-detail-view/game-detail-view.component.ts @@ -48,6 +48,24 @@ export class GameDetailViewComponent { this.gamesService.downloadGame(this.game.slug); } + public refreshGame(): void { + this.gamesService.refreshGame(this.game.slug).subscribe({ + next: game => { + this.game = game; + if(game.companies !== undefined) { + this.companiesWithLogo = game.companies.filter(c => c.logoId !== undefined && c.logoId.length > 0); + } + }, + error: error => { + if (error.status === 404) { + this.router.navigate(['/library']); + } else { + console.error(error); + } + } + }); + } + public bytesAsHumanReadableString(bytes: number): string { const thresh = 1024; diff --git a/frontend/src/app/services/games.service.ts b/frontend/src/app/services/games.service.ts index 87bd6f4..ea7a5b8 100644 --- a/frontend/src/app/services/games.service.ts +++ b/frontend/src/app/services/games.service.ts @@ -92,6 +92,10 @@ export class GamesService implements GamesApi { window.open(`v1${this.apiPath}/game/${slug}/download`, '_top'); } + refreshGame(slug: String): Observable { + return this.http.get(`${this.apiPath}/game/${slug}/refresh`); + } + getGameOverviews(): Observable { return this.http.get(`${this.apiPath}/game-overviews`); }