mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 08:15:48 +00:00
Preparations for plugin prioritisation and metadata merging
This commit is contained in:
@@ -7,7 +7,7 @@ import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadataProvider
|
||||
import de.grimsi.gameyfin.plugins.steam.dto.SteamDetailsResultWrapper
|
||||
import de.grimsi.gameyfin.plugins.steam.dto.SteamGame
|
||||
import de.grimsi.gameyfin.plugins.steam.dto.SteamSearchResult
|
||||
import de.grimsi.gameyfin.plugins.steam.mapper.toGenre
|
||||
import de.grimsi.gameyfin.plugins.steam.mapper.Mapper
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
@@ -18,9 +18,6 @@ import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
import org.pf4j.Extension
|
||||
import org.pf4j.PluginWrapper
|
||||
@@ -29,16 +26,12 @@ import org.slf4j.LoggerFactory
|
||||
import java.net.URI
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
|
||||
class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
override val configMetadata: List<PluginConfigElement> = emptyList()
|
||||
|
||||
override fun validateConfig(config: Map<String, String?>): Boolean {
|
||||
// No config to validate
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -52,6 +45,10 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Steam Store API I am using provides far less info than IGDB for example
|
||||
* See it more as a proof of concept than a fully functional plugin
|
||||
**/
|
||||
override fun fetchMetadata(gameId: String): GameMetadata? {
|
||||
val searchResult: List<SteamGame> = runBlocking { searchStore(gameId) }
|
||||
if (searchResult.isEmpty()) return null
|
||||
@@ -91,9 +88,11 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
val steamDetailsResultWrapper: Map<Int, SteamDetailsResultWrapper> = Json.decodeFromString(responseBody)
|
||||
|
||||
if (!steamDetailsResultWrapper.containsKey(id)) return null
|
||||
if (steamDetailsResultWrapper[id]?.success != true) return null
|
||||
|
||||
val game = steamDetailsResultWrapper[id]?.data ?: return null
|
||||
|
||||
// This is as much as I can get from the Steam Store API
|
||||
val metadata = GameMetadata(
|
||||
title = game.name,
|
||||
description = game.detailedDescription,
|
||||
@@ -101,7 +100,7 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
release = game.releaseDate?.date,
|
||||
developedBy = game.developers.toSet(),
|
||||
publishedBy = game.publishers.toSet(),
|
||||
genres = game.genres.map { toGenre(it) }.toSet(),
|
||||
genres = game.genres.map { Mapper.genre(it) }.toSet(),
|
||||
keywords = game.categories.mapNotNull { it.description }.toSet(),
|
||||
screenshotUrls = game.screenshots.map { URI(it.pathFull!!) }.toSet(),
|
||||
videoUrls = game.movies.map { URI(it.webm?.max!!) }.toSet()
|
||||
@@ -109,19 +108,5 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
|
||||
return metadata
|
||||
}
|
||||
|
||||
private fun string(json: JsonObject, key: String): String {
|
||||
return json[key]?.jsonPrimitive?.content ?: ""
|
||||
}
|
||||
|
||||
private fun stringList(json: JsonObject, key: String): List<String> {
|
||||
return json[key]?.jsonArray?.map { it.jsonPrimitive.content } ?: emptyList()
|
||||
}
|
||||
|
||||
fun date(dateString: String): Instant {
|
||||
val formatter = DateTimeFormatter.ofPattern("dd MMM, yyyy", Locale.ENGLISH)
|
||||
val localDate = LocalDate.parse(dateString, formatter)
|
||||
return localDate.atStartOfDay().toInstant(ZoneOffset.UTC)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ data class SteamGameDetails(
|
||||
val type: String,
|
||||
val name: String,
|
||||
@SerialName("steam_appid") val steamAppId: Int,
|
||||
@SerialName("required_age") val requiredAge: String,
|
||||
@SerialName("required_age") val requiredAge: Int,
|
||||
@SerialName("is_free") val isFree: Boolean,
|
||||
@SerialName("controller_support") val controllerSupport: String?,
|
||||
val dlc: List<Int>?,
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package de.grimsi.gameyfin.plugins.steam.mapper
|
||||
|
||||
import de.grimsi.gameyfin.pluginapi.gamemetadata.Genre
|
||||
import de.grimsi.gameyfin.plugins.steam.dto.SteamGenre
|
||||
|
||||
fun toGenre(steamGenre: SteamGenre): Genre {
|
||||
return when (steamGenre.id) {
|
||||
1 -> Genre.ACTION
|
||||
2 -> Genre.STRATEGY
|
||||
25 -> Genre.ADVENTURE
|
||||
23 -> Genre.INDIE
|
||||
3 -> Genre.ROLE_PLAYING
|
||||
28 -> Genre.SIMULATOR
|
||||
29 -> Genre.MMO
|
||||
9 -> Genre.RACING
|
||||
18 -> Genre.SPORT
|
||||
37 -> Genre.UNKNOWN // Free to Play doesn't match any genre directly
|
||||
51 -> Genre.UNKNOWN // Animation & Modeling doesn't match any genre directly
|
||||
58 -> Genre.UNKNOWN // Video Production doesn't match any genre directly
|
||||
4 -> Genre.UNKNOWN // Casual doesn't match any genre directly
|
||||
73 -> Genre.UNKNOWN // Violent doesn't map directly to a genre
|
||||
72 -> Genre.UNKNOWN // Nudity doesn't match any genre directly
|
||||
70 -> Genre.UNKNOWN // Early Access doesn't map directly to a genre
|
||||
74 -> Genre.UNKNOWN // Gore doesn't match any genre directly
|
||||
57 -> Genre.UNKNOWN // Utilities doesn't match any genre directly
|
||||
52 -> Genre.UNKNOWN // Audio Production doesn't match any genre directly
|
||||
53 -> Genre.UNKNOWN // Design & Illustration doesn't match any genre directly
|
||||
59 -> Genre.UNKNOWN // Web Publishing doesn't map directly to a genre
|
||||
55 -> Genre.UNKNOWN // Photo Editing doesn't map directly to a genre
|
||||
54 -> Genre.UNKNOWN // Education doesn't match any genre directly
|
||||
56 -> Genre.UNKNOWN // Software Training doesn't map directly to a genre
|
||||
71 -> Genre.UNKNOWN // Sexual Content doesn't match any genre directly
|
||||
60 -> Genre.UNKNOWN // Game Development doesn't map directly to a genre
|
||||
50 -> Genre.UNKNOWN // Accounting doesn't map directly to a genre
|
||||
81 -> Genre.UNKNOWN // Documentary doesn't map directly to a genre
|
||||
84 -> Genre.UNKNOWN // Tutorial doesn't map directly to a genre
|
||||
else -> Genre.UNKNOWN
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package de.grimsi.gameyfin.plugins.steam.mapper
|
||||
|
||||
import de.grimsi.gameyfin.pluginapi.gamemetadata.Genre
|
||||
import de.grimsi.gameyfin.plugins.steam.dto.SteamGenre
|
||||
|
||||
class Mapper {
|
||||
companion object {
|
||||
fun genre(steamGenre: SteamGenre): Genre {
|
||||
return when (steamGenre.id) {
|
||||
1 -> Genre.ACTION
|
||||
2 -> Genre.STRATEGY
|
||||
25 -> Genre.ADVENTURE
|
||||
23 -> Genre.INDIE
|
||||
3 -> Genre.ROLE_PLAYING
|
||||
28 -> Genre.SIMULATOR
|
||||
29 -> Genre.MMO
|
||||
9 -> Genre.RACING
|
||||
18 -> Genre.SPORT
|
||||
37 -> Genre.UNKNOWN // Free to Play doesn't match any genre directly
|
||||
51 -> Genre.UNKNOWN // Animation & Modeling doesn't match any genre directly
|
||||
58 -> Genre.UNKNOWN // Video Production doesn't match any genre directly
|
||||
4 -> Genre.UNKNOWN // Casual doesn't match any genre directly
|
||||
73 -> Genre.UNKNOWN // Violent doesn't map directly to a genre
|
||||
72 -> Genre.UNKNOWN // Nudity doesn't match any genre directly
|
||||
70 -> Genre.UNKNOWN // Early Access doesn't map directly to a genre
|
||||
74 -> Genre.UNKNOWN // Gore doesn't match any genre directly
|
||||
57 -> Genre.UNKNOWN // Utilities doesn't match any genre directly
|
||||
52 -> Genre.UNKNOWN // Audio Production doesn't match any genre directly
|
||||
53 -> Genre.UNKNOWN // Design & Illustration doesn't match any genre directly
|
||||
59 -> Genre.UNKNOWN // Web Publishing doesn't map directly to a genre
|
||||
55 -> Genre.UNKNOWN // Photo Editing doesn't map directly to a genre
|
||||
54 -> Genre.UNKNOWN // Education doesn't match any genre directly
|
||||
56 -> Genre.UNKNOWN // Software Training doesn't map directly to a genre
|
||||
71 -> Genre.UNKNOWN // Sexual Content doesn't match any genre directly
|
||||
60 -> Genre.UNKNOWN // Game Development doesn't map directly to a genre
|
||||
50 -> Genre.UNKNOWN // Accounting doesn't map directly to a genre
|
||||
81 -> Genre.UNKNOWN // Documentary doesn't map directly to a genre
|
||||
84 -> Genre.UNKNOWN // Tutorial doesn't map directly to a genre
|
||||
else -> Genre.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user