Use ratings date in cache filename
This commit is contained in:
@@ -2,13 +2,17 @@ package org.jeudego.pairgoth.ratings
|
||||
|
||||
import com.republicate.kson.Json
|
||||
import java.net.URL
|
||||
import java.time.LocalDate
|
||||
|
||||
object AGARatingsHandler: RatingsHandler(RatingsManager.Ratings.AGA) {
|
||||
override val defaultURL: URL by lazy {
|
||||
throw Error("No URL for AGA...")
|
||||
throw Error("No functional URL for AGA...")
|
||||
}
|
||||
override val active = false
|
||||
override fun parsePayload(payload: String): Json.Array {
|
||||
return Json.Array()
|
||||
override fun parsePayload(payload: String): Pair<LocalDate, Json.Array> {
|
||||
return Pair(
|
||||
LocalDate.MIN,
|
||||
Json.Array()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -2,11 +2,18 @@ package org.jeudego.pairgoth.ratings
|
||||
|
||||
import com.republicate.kson.Json
|
||||
import java.net.URL
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object EGFRatingsHandler: RatingsHandler(RatingsManager.Ratings.EGF) {
|
||||
val ratingsDateFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy")
|
||||
override val defaultURL = URL("https://www.europeangodatabase.eu/EGD/EGD_2_0/downloads/allworld_lp.html")
|
||||
override fun parsePayload(payload: String): Json.Array {
|
||||
return payload.lines().filter {
|
||||
override fun parsePayload(payload: String): Pair<LocalDate, Json.Array> {
|
||||
val ratingsDateString = payload.lines().filter { it.startsWith("(") }.first().trim().removeSurrounding("(", ")")
|
||||
val ratingsDate = LocalDate.parse(ratingsDateString, ratingsDateFormatter)
|
||||
return Pair(
|
||||
ratingsDate,
|
||||
payload.lines().filter {
|
||||
it.matches(Regex("\\s+\\d+(?!.*\\(undefined\\)|Anonymous).*"))
|
||||
}.mapNotNullTo(Json.MutableArray()) {
|
||||
val match = linePattern.matchEntire(it)
|
||||
@@ -29,6 +36,7 @@ object EGFRatingsHandler: RatingsHandler(RatingsManager.Ratings.EGF) {
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
// 19574643 Abad Jahin FR 38GJ 20k -- 15 2 T200202B
|
||||
var linePattern =
|
||||
|
@@ -1,17 +1,20 @@
|
||||
package org.jeudego.pairgoth.ratings
|
||||
|
||||
import com.republicate.kson.Json
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.net.URL
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object FFGRatingsHandler: RatingsHandler(RatingsManager.Ratings.FFG) {
|
||||
val ratingsDateFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
|
||||
override val defaultURL = URL("https://ffg.jeudego.org/echelle/echtxt/ech_ffg_V3.txt")
|
||||
override fun parsePayload(payload: String): Json.Array {
|
||||
return payload.lines().mapNotNullTo(Json.MutableArray()) { line ->
|
||||
override fun parsePayload(payload: String): Pair<LocalDate, Json.Array> {
|
||||
val ratingsDateString = payload.lineSequence().first().substringAfter("#Echelle au ").substringBefore(" ")
|
||||
val ratingsDate = LocalDate.parse(ratingsDateString, ratingsDateFormatter)
|
||||
return Pair(
|
||||
ratingsDate,
|
||||
payload.lines().mapNotNullTo(Json.MutableArray()) { line ->
|
||||
val match = linePattern.matchEntire(line)
|
||||
if (match == null) {
|
||||
logger.error("could not parse line: $line")
|
||||
@@ -31,6 +34,7 @@ object FFGRatingsHandler: RatingsHandler(RatingsManager.Ratings.FFG) {
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun defaultCharset() = StandardCharsets.ISO_8859_1
|
||||
|
@@ -6,18 +6,27 @@ import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.jeudego.pairgoth.web.WebappManager
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.text.DateFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.useDirectoryEntries
|
||||
|
||||
abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
|
||||
|
||||
companion object {
|
||||
private val delay = TimeUnit.HOURS.toMillis(1L)
|
||||
private val ymd = DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
}
|
||||
private val client = OkHttpClient()
|
||||
abstract val defaultURL: URL
|
||||
open val active = true
|
||||
val cacheFile = RatingsManager.path.resolve("${origin.name}.json").toFile()
|
||||
// val cacheFile = RatingsManager.path.resolve("${origin.name}.json").toFile()
|
||||
lateinit var players: Json.Array
|
||||
private var updated = false
|
||||
|
||||
@@ -25,23 +34,38 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
|
||||
WebappManager.properties.getProperty("ratings.${origin.name.lowercase(Locale.ROOT)}")?.let { URL(it) } ?: defaultURL
|
||||
}
|
||||
|
||||
private fun getRatingsFiles() = RatingsManager.path.useDirectoryEntries("${origin.name}-*.json") { entries ->
|
||||
entries.sortedBy { it.fileName.name }.map {
|
||||
it.toFile()
|
||||
}.toList()
|
||||
}
|
||||
|
||||
private fun getLatestRatingsFile() = getRatingsFiles().lastOrNull()
|
||||
|
||||
private fun initIfNeeded(ratingsFile: File): Boolean {
|
||||
return if (!this::players.isInitialized) {
|
||||
players = Json.parse(ratingsFile.readText())?.asArray() ?: Json.Array()
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
fun updateIfNeeded(): Boolean {
|
||||
return if (Date().time - cacheFile.lastModified() > delay) {
|
||||
RatingsManager.logger.info("Updating $origin cache from $url")
|
||||
val latestRatingsFile = getLatestRatingsFile()
|
||||
if (latestRatingsFile != null && Date().time - latestRatingsFile.lastModified() < delay) {
|
||||
return initIfNeeded(latestRatingsFile)
|
||||
}
|
||||
val payload = fetchPayload()
|
||||
players = parsePayload(payload).also {
|
||||
val cachePayload = it.toString()
|
||||
cacheFile.printWriter().use { out ->
|
||||
out.println(cachePayload)
|
||||
val (lastUpdated, lastPlayers) = parsePayload(payload)
|
||||
val targetRatingsFilename = "${origin.name}-${ymd.format(lastUpdated)}.json"
|
||||
if (latestRatingsFile != null && latestRatingsFile.name == targetRatingsFilename) {
|
||||
return initIfNeeded(latestRatingsFile)
|
||||
}
|
||||
RatingsManager.logger.info("Updating $origin cache from $url")
|
||||
RatingsManager.path.resolve(targetRatingsFilename).toFile().printWriter().use { out ->
|
||||
out.println(lastPlayers.toString())
|
||||
}
|
||||
true
|
||||
} else if (!this::players.isInitialized) {
|
||||
players = Json.parse(cacheFile.readText())?.asArray() ?: Json.Array()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
players = lastPlayers
|
||||
return true
|
||||
}
|
||||
|
||||
fun fetchPlayers(): Json.Array {
|
||||
@@ -62,7 +86,7 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
|
||||
}
|
||||
open fun defaultCharset() = StandardCharsets.UTF_8
|
||||
fun updated() = updated
|
||||
abstract fun parsePayload(payload: String): Json.Array
|
||||
abstract fun parsePayload(payload: String): Pair<LocalDate, Json.Array>
|
||||
val logger = LoggerFactory.getLogger(origin.name)
|
||||
val atom = "[-._`'a-zA-ZÀ-ÿ]"
|
||||
}
|
||||
|
Reference in New Issue
Block a user