Improve error logging in IGDB plugin

This commit is contained in:
grimsi
2025-05-06 13:11:16 +02:00
parent 82394a9416
commit 8368a68d81
@@ -1,6 +1,7 @@
package de.grimsi.gameyfin.plugins.igdb package de.grimsi.gameyfin.plugins.igdb
import com.api.igdb.apicalypse.APICalypse import com.api.igdb.apicalypse.APICalypse
import com.api.igdb.exceptions.RequestException
import com.api.igdb.request.IGDBWrapper import com.api.igdb.request.IGDBWrapper
import com.api.igdb.request.TwitchAuthenticator import com.api.igdb.request.TwitchAuthenticator
import com.api.igdb.request.games import com.api.igdb.request.games
@@ -12,6 +13,7 @@ import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadataProvider
import me.xdrop.fuzzywuzzy.FuzzySearch import me.xdrop.fuzzywuzzy.FuzzySearch
import org.pf4j.Extension import org.pf4j.Extension
import org.pf4j.PluginWrapper import org.pf4j.PluginWrapper
import org.slf4j.LoggerFactory
import proto.Game import proto.Game
import java.time.Instant import java.time.Instant
@@ -61,70 +63,66 @@ class IgdbPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
@Extension @Extension
class IgdbMetadataProvider : GameMetadataProvider { class IgdbMetadataProvider : GameMetadataProvider {
private val QUERY_FIELDS = listOf( companion object {
"slug", private val log = LoggerFactory.getLogger(this::class.java)
"name",
"summary", private val QUERY_FIELDS = listOf(
"first_release_date", "slug",
"rating", "name",
"aggregated_rating", "summary",
"total_rating", "first_release_date",
"category", "rating",
"multiplayer_modes.lancoop", "aggregated_rating",
"game_modes.slug", "total_rating",
"game_modes.name", "category",
"cover.image_id", "multiplayer_modes.lancoop",
"screenshots.image_id", "game_modes.slug",
"videos.video_id", "game_modes.name",
"involved_companies.company.slug", "cover.image_id",
"involved_companies.company.name", "screenshots.image_id",
"involved_companies.developer", "videos.video_id",
"involved_companies.publisher", "involved_companies.company.slug",
"involved_companies.company.logo.image_id", "involved_companies.company.name",
"genres.slug", "involved_companies.developer",
"genres.name", "involved_companies.publisher",
"keywords.slug", "involved_companies.company.logo.image_id",
"keywords.name", "genres.slug",
"themes.slug", "genres.name",
"themes.name", "keywords.slug",
"player_perspectives.slug", "keywords.name",
"player_perspectives.name", "themes.slug",
"platforms.slug", "themes.name",
"platforms.name", "player_perspectives.slug",
"platforms.platform_logo.image_id" "player_perspectives.name",
).joinToString(",") "platforms.slug",
"platforms.name",
"platforms.platform_logo.image_id"
).joinToString(",")
}
override fun fetchMetadata(gameId: String, maxResults: Int): List<GameMetadata> { override fun fetchMetadata(gameId: String, maxResults: Int): List<GameMetadata> {
val findBySlugQuery = APICalypse() try {
.fields(QUERY_FIELDS) // Note: Limit is intentionally set high because IGDBs ranking algorithm is not very good
.where("slug = \"${guessSlug(gameId)}\"")
// First step: Try to find the game by guessing the slug
var games = IGDBWrapper.games(findBySlugQuery)
// Second step: Try a fuzzy search
// Note: Limit is intentionally set high because IGDBs ranking algorithm is not very good
if (games.isEmpty()) {
val searchByNameQuery = APICalypse() val searchByNameQuery = APICalypse()
.fields(QUERY_FIELDS) .fields(QUERY_FIELDS)
.limit(100) .limit(100)
.search(gameId) .search(gameId)
// Use IGDBs search function to get a list of games that match the search query // Use IGDBs search function to get a list of games that match the search query
games = IGDBWrapper.games(searchByNameQuery) var games = IGDBWrapper.games(searchByNameQuery)
if (games.isEmpty()) return emptyList() if (games.isEmpty()) return emptyList()
// Use fuzzy search to find the best matching game name // Use fuzzy search to find the best matching game name
val bestMatchingTitles = FuzzySearch.extractTop(gameId, games.map { it.name }, maxResults) val bestMatchingTitles = FuzzySearch.extractTop(gameId, games.map { it.name }, maxResults)
games = bestMatchingTitles.mapNotNull { title -> games.find { it.name == title.string } } games = bestMatchingTitles.mapNotNull { title -> games.find { it.name == title.string } }
return games.map { toGameMetadata(it) }
} catch (e: RequestException) {
log.error("Request to IGDB API failed with HTTP ${e.statusCode}")
} }
return games.map { toGameMetadata(it) } return emptyList()
}
private fun guessSlug(gameId: String): String {
return gameId.replace(" ", "-").lowercase()
} }
private fun toGameMetadata(game: Game): GameMetadata { private fun toGameMetadata(game: Game): GameMetadata {