mirror of
https://github.com/grimsi/gameyfin.git
synced 2026-02-06 11:27:07 +00:00
Try to parse release date from store page
Use short_description because of relevance of content
This commit is contained in:
parent
249065a90b
commit
ed95400d2d
@ -22,4 +22,5 @@ dependencies {
|
||||
}
|
||||
|
||||
implementation("me.xdrop:fuzzywuzzy:1.4.0")
|
||||
implementation("org.jsoup:jsoup:1.20.1")
|
||||
}
|
||||
@ -19,10 +19,13 @@ import org.gameyfin.plugins.metadata.steam.dto.SteamDetailsResultWrapper
|
||||
import org.gameyfin.plugins.metadata.steam.dto.SteamGame
|
||||
import org.gameyfin.plugins.metadata.steam.dto.SteamSearchResult
|
||||
import org.gameyfin.plugins.metadata.steam.mapper.Mapper
|
||||
import org.gameyfin.plugins.metadata.steam.util.SteamDateSerializer
|
||||
import org.jsoup.Jsoup
|
||||
import org.pf4j.Extension
|
||||
import org.pf4j.PluginWrapper
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
||||
class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
|
||||
@ -31,6 +34,8 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
isLenient = true
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
|
||||
val dateSerializer = SteamDateSerializer()
|
||||
}
|
||||
|
||||
@Extension(ordinal = 3)
|
||||
@ -114,9 +119,9 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
val metadata = GameMetadata(
|
||||
originalId = id.toString(),
|
||||
title = sanitizeTitle(game.name),
|
||||
description = game.detailedDescription,
|
||||
description = game.shortDescription, // Using short description since the detailed description often contains just some ads for the Battle Pass etc.
|
||||
coverUrls = game.headerImage?.let { URI(it) }?.let { listOf(it) },
|
||||
release = game.releaseDate?.date,
|
||||
release = parseOriginalReleaseDateFromStorePage(id) ?: game.releaseDate?.date,
|
||||
developedBy = game.developers?.toSet(),
|
||||
publishedBy = game.publishers?.toSet(),
|
||||
genres = game.genres?.let { genre -> genre.map { Mapper.genre(it) }.toSet() },
|
||||
@ -128,6 +133,28 @@ class SteamPlugin(wrapper: PluginWrapper) : GameyfinPlugin(wrapper) {
|
||||
return metadata
|
||||
}
|
||||
|
||||
/**
|
||||
* The API only provides the release date on Steam, not the original release date.
|
||||
* However, it is possible to get the original release date from the Steam store page.
|
||||
*/
|
||||
private suspend fun parseOriginalReleaseDateFromStorePage(appId: Int): Instant? {
|
||||
val response = client.get("https://store.steampowered.com/app/$appId") {
|
||||
// Set language to English to avoid issues with different languages
|
||||
cookie("Steam_Language", "english")
|
||||
// Skip Steam age check
|
||||
cookie("birthtime", "-2208989360")
|
||||
cookie("lastagecheckage", "1-January-1900")
|
||||
}
|
||||
|
||||
if (response.status != HttpStatusCode.OK) return null
|
||||
|
||||
val html: String = response.bodyAsText(Charsets.UTF_8)
|
||||
val document = Jsoup.parse(html)
|
||||
val releaseDateText = document.selectFirst("div.release_date div.date") ?: return null
|
||||
|
||||
return dateSerializer.deserialize(releaseDateText.text())
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Often titles on Steam contain copyright symbols which makes matching between different providers harder
|
||||
|
||||
@ -15,6 +15,7 @@ data class SteamDetailsResultWrapper(
|
||||
data class SteamGameDetails(
|
||||
val type: String,
|
||||
val name: String,
|
||||
@SerialName("short_description") val shortDescription: String? = null,
|
||||
@SerialName("detailed_description") val detailedDescription: String? = null,
|
||||
@SerialName("header_image") val headerImage: String? = null,
|
||||
val developers: List<String>? = null,
|
||||
|
||||
@ -27,9 +27,26 @@ class SteamDateSerializer : KSerializer<Instant?> {
|
||||
val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("d MMM, yyyy", Locale.ENGLISH)
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): Instant? = fromString(decoder.decodeString())
|
||||
override fun serialize(encoder: Encoder, value: Instant?) {
|
||||
if (value == null) {
|
||||
encoder.encodeNull()
|
||||
} else {
|
||||
encoder.encodeString(value.toString())
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Instant?) = encoder.encodeString(value.toString())
|
||||
override fun deserialize(decoder: Decoder): Instant? {
|
||||
return if (decoder.decodeNotNullMark()) {
|
||||
fromString(decoder.decodeString())
|
||||
} else {
|
||||
decoder.decodeNull()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun deserialize(dateString: String): Instant? {
|
||||
return fromString(dateString)
|
||||
}
|
||||
|
||||
private fun fromString(dateString: String): Instant? {
|
||||
return try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user