mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-13 16:40:01 +00:00
Switched from in-memory DB to file-based DB
Fixed a few bugs linked to unmapped files
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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: ""
|
||||
|
||||
Reference in New Issue
Block a user