🚧 Add filter for free games from the Epic store
[rhynodge.git] / src / main / kotlin / net / pterodactylus / rhynodge / filters / webpages / epicgames / EpicGamesFilter.kt
diff --git a/src/main/kotlin/net/pterodactylus/rhynodge/filters/webpages/epicgames/EpicGamesFilter.kt b/src/main/kotlin/net/pterodactylus/rhynodge/filters/webpages/epicgames/EpicGamesFilter.kt
new file mode 100644 (file)
index 0000000..31bb11f
--- /dev/null
@@ -0,0 +1,49 @@
+package net.pterodactylus.rhynodge.filters.webpages.epicgames
+
+import com.fasterxml.jackson.databind.JsonNode
+import net.pterodactylus.rhynodge.Filter
+import net.pterodactylus.rhynodge.State
+import net.pterodactylus.rhynodge.states.AbstractState
+import net.pterodactylus.rhynodge.states.JsonState
+import java.time.Instant
+
+class EpicGamesFilter : Filter {
+
+       override fun filter(state: State): State {
+               state as? JsonState ?: throw IllegalArgumentException("state must be a JSON state")
+               return state.jsonNode.at("/data/Catalog/searchStore/elements").map { gameJson: JsonNode ->
+                       val title = gameJson.get("title").asText()
+                       val imageUrl = gameJson.at("/keyImages/1/url").asText()
+                       val startDate = getPromotionalOfferStartDate(gameJson)
+                       val endDate = getPromotionalOfferEndDate(gameJson)
+                       FreeGame(title, imageUrl, startDate, endDate)
+               }.let { FreeGamesState(it.toSet()) }
+       }
+
+       private fun getPromotionalOfferEndDate(gameJson: JsonNode) = getPromotionalOfferDate(gameJson, "endDate")
+       private fun getPromotionalOfferStartDate(gameJson: JsonNode) = getPromotionalOfferDate(gameJson, "startDate")
+
+       private fun getPromotionalOfferDate(gameJson: JsonNode, date: String) = listOf("promotionalOffers", "upcomingPromotionalOffers")
+               .map { "/promotions/$it/0/promotionalOffers/0/$date" }
+               .map { gameJson.at(it) }
+               .filter { !it.isMissingNode }
+               .map { it.asText() }
+               .map(Instant::parse)
+               .first()
+
+}
+
+data class FreeGame(
+       val title: String,
+       val imageUrl: String,
+       val startDate: Instant,
+       val endDate: Instant
+)
+
+class FreeGamesState(val games: Set<FreeGame>) : AbstractState(true) {
+
+       override fun plainText(): String {
+               TODO("Not yet implemented")
+       }
+
+}