From bcade0e4f1750cc8de8471e085537ed08ca99474 Mon Sep 17 00:00:00 2001 From: grimsi <9295182+grimsi@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:39:53 +0200 Subject: [PATCH] Minor matching algorithm improvement Add "Clear DB" button to UI --- gameyfin/src/main/frontend/views/TestView.tsx | 12 ++++++++++++ .../src/main/kotlin/de/grimsi/gameyfin/core/Utils.kt | 11 ++++++++++- .../kotlin/de/grimsi/gameyfin/games/GameService.kt | 10 ++++++++-- .../de/grimsi/gameyfin/libraries/LibraryEndpoint.kt | 9 ++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/gameyfin/src/main/frontend/views/TestView.tsx b/gameyfin/src/main/frontend/views/TestView.tsx index 935199e..47852cf 100644 --- a/gameyfin/src/main/frontend/views/TestView.tsx +++ b/gameyfin/src/main/frontend/views/TestView.tsx @@ -16,6 +16,17 @@ export default function TestView() { }); } + function removeGames() { + LibraryEndpoint.removeGames().then(() => { + setGame(undefined); + addToast({ + title: "Success", + description: "Games removed", + color: "success" + }) + }); + } + return (
@@ -46,6 +57,7 @@ export default function TestView() {
+
{game && } {game && <>{JSON.stringify(game, null, 2)}} diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/Utils.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/Utils.kt index d4aa5dc..c953e88 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/Utils.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/core/Utils.kt @@ -51,5 +51,14 @@ class Utils { } } +/** + * Converts a map with nullable values to a map with non-nullable values by filtering out null values + */ @Suppress("UNCHECKED_CAST") -fun Map.filterValuesNotNull() = filterValues { it != null } as Map \ No newline at end of file +fun Map.filterValuesNotNull() = filterValues { it != null } as Map + +/** + * Converts a string to an alphanumeric string by removing all non-alphanumeric characters (except whitespaces) + * and converting it to lowercase + */ +fun String.alphaNumeric() = filter { it.isLetterOrDigit() || it.isWhitespace() }.lowercase() \ No newline at end of file diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt index 75731c1..dc5b8cf 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/games/GameService.kt @@ -1,5 +1,6 @@ package de.grimsi.gameyfin.games +import de.grimsi.gameyfin.core.alphaNumeric import de.grimsi.gameyfin.core.filterValuesNotNull import de.grimsi.gameyfin.core.plugins.management.PluginManagementEntry import de.grimsi.gameyfin.core.plugins.management.PluginManagementService @@ -83,6 +84,10 @@ class GameService( gameRepository.delete(game) } + fun deleteAll() { + gameRepository.deleteAll() + } + private fun getById(id: Long): Game { return gameRepository.findByIdOrNull(id) ?: throw IllegalArgumentException("Game with id $id not found") } @@ -110,7 +115,8 @@ class GameService( } /** - * Determines the closest matching title from the results and filters out any other results + * Determines the closest matching title from the results + * Filters the results to only include the best matching title (using an alphanumeric comparison) */ private fun filterResults( originalQuery: String, @@ -121,7 +127,7 @@ class GameService( log.info { "Best matching title: '$bestMatchingTitle' for '$originalQuery' determined from $availableTitles" } - return results.filter { it.value.title == bestMatchingTitle } + return results.filter { it.value.title.alphaNumeric() == bestMatchingTitle.alphaNumeric() } } /** diff --git a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryEndpoint.kt b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryEndpoint.kt index 3dc9912..44fc0d4 100644 --- a/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryEndpoint.kt +++ b/gameyfin/src/main/kotlin/de/grimsi/gameyfin/libraries/LibraryEndpoint.kt @@ -2,12 +2,14 @@ package de.grimsi.gameyfin.libraries import com.vaadin.hilla.Endpoint import de.grimsi.gameyfin.core.Role +import de.grimsi.gameyfin.games.GameService import de.grimsi.gameyfin.games.dto.GameDto import jakarta.annotation.security.RolesAllowed @Endpoint class LibraryEndpoint( - private val libraryService: LibraryService + private val libraryService: LibraryService, + private val gameService: GameService ) { @RolesAllowed(Role.Names.ADMIN) fun getAllLibraries(): Collection { @@ -23,4 +25,9 @@ class LibraryEndpoint( fun test(testString: String): GameDto { return libraryService.test(testString) } + + @RolesAllowed(Role.Names.ADMIN) + fun removeGames() { + return gameService.deleteAll() + } } \ No newline at end of file