Switched from in-memory DB to file-based DB

Fixed a few bugs linked to unmapped files
This commit is contained in:
grimsi
2022-07-16 18:02:34 +02:00
parent 64485bf3f0
commit 9803a9dc0a
6 changed files with 44 additions and 14 deletions
+3
View File
@@ -32,3 +32,6 @@ build/
### VS Code ###
.vscode/
/.mvn/
### Custom ###
/data/
@@ -5,8 +5,8 @@ import java.util.List;
public class IgdbApiProperties {
public static final String IGDB_ENPOINT_GAMES_PROTOBUF = "games.pb";
public static final List<String> GAME_QUERY_FIELDS = List.of(
"slug", "name", "summary", "first_release_date", "rating", "aggregated_rating", "total_rating", "category", "multiplayer_modes", "cover", "screenshots", "videos", // All top-level fields
private static final List<String> GAME_QUERY_FIELDS = List.of(
"slug", "name", "summary", "first_release_date", "rating", "aggregated_rating", "total_rating", "category", "multiplayer_modes", "cover", "screenshots", "videos",
"involved_companies.company.slug", "involved_companies.company.name", "involved_companies.company.logo.id",
"genres.slug", "genres.name",
"keywords.slug", "keywords.name",
@@ -14,4 +14,6 @@ public class IgdbApiProperties {
"player_perspectives.slug", "player_perspectives.name"
);
public static final String GAME_QUERY_FIELDS_STRING = String.join(",", GAME_QUERY_FIELDS);
}
@@ -68,7 +68,7 @@ public class IgdbWrapper {
public Optional<Igdb.Game> getGameById(Long id) {
Igdb.GameResult gameResult = queryIgdbApi(
IgdbApiProperties.IGDB_ENPOINT_GAMES_PROTOBUF,
"fields *; where id = %d; limit 1;".formatted(id),
"fields %s; where id = %d; limit 1;".formatted(IgdbApiProperties.GAME_QUERY_FIELDS_STRING, id),
Igdb.GameResult.class
);
@@ -80,7 +80,7 @@ public class IgdbWrapper {
public Optional<Igdb.Game> getGameBySlug(String slug) {
Igdb.GameResult gameResult = queryIgdbApi(
IgdbApiProperties.IGDB_ENPOINT_GAMES_PROTOBUF,
"fields *; where slug = \"%s\"; limit 1;".formatted(slug),
"fields %s; where slug = \"%s\"; limit 1;".formatted(IgdbApiProperties.GAME_QUERY_FIELDS_STRING, slug),
Igdb.GameResult.class
);
@@ -93,7 +93,7 @@ public class IgdbWrapper {
Igdb.GameResult gameResult = queryIgdbApi(
IgdbApiProperties.IGDB_ENPOINT_GAMES_PROTOBUF,
"search \"%s\"; fields %s; where platforms = (%s);"
.formatted(searchTerm, String.join(",", IgdbApiProperties.GAME_QUERY_FIELDS), preferredPlatforms),
.formatted(searchTerm, IgdbApiProperties.GAME_QUERY_FIELDS_STRING, preferredPlatforms),
Igdb.GameResult.class
);
@@ -1,9 +1,21 @@
package de.grimsi.gameyfin.repositories;
import de.grimsi.gameyfin.entities.DetectedGame;
import de.grimsi.gameyfin.entities.UnmappableFile;
import org.springframework.data.jpa.repository.JpaRepository;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
public interface UnmappableFileRepository extends JpaRepository<UnmappableFile, Long> {
boolean existsByPath(String path);
List<UnmappableFile> getAllByPathNotIn(Collection<String> paths);
default List<UnmappableFile> getAllByPathNotIn(List<Path> paths) {
List<String> pathStrings = paths.stream().map(Path::toString).toList();
return getAllByPathNotIn(pathStrings);
}
}
@@ -74,6 +74,12 @@ public class FilesystemService {
// This would include renamed files, but they will be re-detected by the next step
List<DetectedGame> deletedGames = detectedGameRepository.getAllByPathNotIn(gameFiles);
detectedGameRepository.deleteAll(deletedGames);
deletedGames.forEach(g -> log.info("Game '{}' has been moved or deleted.", g.getPath()));
// Now check if there are any unmapped files that have been removed from the file system
List<UnmappableFile> deletedUnmappableFiles = unmappableFileRepository.getAllByPathNotIn(gameFiles);
unmappableFileRepository.deleteAll(deletedUnmappableFiles);
deletedUnmappableFiles.forEach(g -> log.info("Unmapped file '{}' has been moved or deleted.", g.getPath()));
// Filter out the games we already know and the ones we already tried to map to a game without success
gameFiles = gameFiles.stream()
@@ -104,13 +110,8 @@ public class FilesystemService {
stopWatch.stop();
String scanDuration = "%dmin : %ds".formatted(
TimeUnit.MILLISECONDS.toMinutes(stopWatch.getLastTaskTimeMillis()),
TimeUnit.MILLISECONDS.toSeconds(stopWatch.getLastTaskTimeMillis()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(stopWatch.getLastTaskTimeMillis()))
);
log.info("Scan finished in {}: Found {} new games, deleted {} games, could not map {} files/folders, {} games total.",
scanDuration, newDetectedGames.size(), deletedGames.size(), newUnmappedFilesCounter.get(), detectedGameRepository.count());
log.info("Scan finished in {} seconds: Found {} new games, deleted {} games, could not map {} files/folders, {} games total.",
(int) stopWatch.getTotalTimeSeconds(), newDetectedGames.size(), deletedGames.size() + deletedUnmappableFiles.size(), newUnmappedFilesCounter.get(), detectedGameRepository.count());
}
private String getFilename(Path p) {
+14 -2
View File
@@ -1,5 +1,17 @@
server.port: 8080
spring.jackson.default-property-inclusion: non_null
server:
port: 8080
error.include-stacktrace: never
spring:
jackson.default-property-inclusion: non_null
datasource.db-name: gameyfin_db
datasource.url: jdbc:h2:file:./data/${spring.datasource.db-name};AUTO_SERVER=TRUE
datasource.username: gfadmin
datasource.password: gameyfin
datasource.driverClassName: org.h2.Driver
jpa.database-platform: org.hibernate.dialect.H2Dialect
jpa.hibernate.ddl-auto: update
jpa.open-in-view: true
gameyfin:
root: ""