From 2ea83ee242788ada47e24bc4f19a9365bf77f5bb Mon Sep 17 00:00:00 2001 From: jay-tux Date: Fri, 25 Apr 2025 10:17:54 +0200 Subject: [PATCH] GET /version endpoint --- api/build.gradle.kts | 1 + api/gradle/libs.versions.toml | 1 + api/src/main/kotlin/data/Loader.kt | 22 ++++++++++++++-------- api/src/main/kotlin/server/Endpoints.kt | 15 +++++++++++++++ api/src/main/kotlin/server/Routing.kt | 1 + 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 229f287..3b2d57e 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -32,6 +32,7 @@ dependencies { implementation(libs.dotenv) implementation(libs.json) + implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) implementation(libs.ksoup) implementation(libs.logback.classic) diff --git a/api/gradle/libs.versions.toml b/api/gradle/libs.versions.toml index ceb7578..c936479 100644 --- a/api/gradle/libs.versions.toml +++ b/api/gradle/libs.versions.toml @@ -32,6 +32,7 @@ ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx dotenv = { module = "io.github.cdimascio:dotenv-kotlin", version.ref = "dotenv" } json = { module = "org.json:json", version.ref = "json" } kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version = "0.6.2" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } ksoup = { module = "com.fleeksoft.ksoup:ksoup", version.ref = "ksoup" } logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } diff --git a/api/src/main/kotlin/data/Loader.kt b/api/src/main/kotlin/data/Loader.kt index c00332b..872b259 100644 --- a/api/src/main/kotlin/data/Loader.kt +++ b/api/src/main/kotlin/data/Loader.kt @@ -3,6 +3,8 @@ package com.jaytux.simd.data import com.fleeksoft.ksoup.Ksoup import com.jaytux.simd.data.IntrinsicInstructions.xed import kotlinx.coroutines.coroutineScope +import kotlinx.datetime.* +import kotlinx.datetime.format.MonthNames import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject @@ -16,12 +18,16 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.Date import java.util.prefs.Preferences -import java.time.Instant object Loader { private val cache = Preferences.userNodeForPackage(this::class.java) - private val intelDateTimeFormat = SimpleDateFormat("MM/dd/yyyy") - private val dateFormat = SimpleDateFormat("dd-MMMM-yyyy") + private val intelDateTimeFormat = LocalDate.Format { + monthNumber(); chars("/"); dayOfMonth(); chars("/"); year(); + } + private val dateFormat = LocalDate.Format { + dayOfMonth(); chars("-"); monthName(MonthNames.ENGLISH_FULL); chars("-"); year() + } + private val zero = LocalDate(1970, 1, 1) data class XmlIntrinsic(val name: String, val tech: String, val retType: String, val retVar: String?, val args: List>, val desc: String, val op: String?, @@ -46,14 +52,14 @@ object Loader { } } - data class DatedVersion(val version: Version, val releaseDate: Date, val updateDate: Date) { + data class DatedVersion(val version: Version, val releaseDate: LocalDate, val updateDate: LocalDate) { override fun toString(): String = "$version (remote released ${dateFormat.format(releaseDate)}; local updated ${dateFormat.format(updateDate)})" companion object { fun fromPrefs(): DatedVersion { val v = cache.get("version", null)?.let { Version.fromString(it) } ?: Version(0, 0, 0) - val r = cache.get("release", null)?.let { dateFormat.parse(it) } ?: Date.from(Instant.ofEpochMilli(0)) - val u = cache.get("update", null)?.let { dateFormat.parse(it) } ?: Date.from(Instant.ofEpochMilli(0)) + val r = cache.get("release", null)?.let { dateFormat.parse(it) } ?: zero + val u = cache.get("update", null)?.let { dateFormat.parse(it) } ?: zero return DatedVersion(v, r, u) } @@ -100,14 +106,14 @@ object Loader { } version to date - } ?: Version(0, 0, 0) to Date() + } ?: Version(0, 0, 0) to LocalDate.fromEpochDays(0) // dummy data if(errors.isNotEmpty()) { errors.forEach { System.err.println(it) } throw Exception("XML file is (partially) invalid") } - val update = Date() + val update = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date xml.getElementsByTag("intrinsic").forEachIndexed { i, it -> val name = it.attribute("name")?.value diff --git a/api/src/main/kotlin/server/Endpoints.kt b/api/src/main/kotlin/server/Endpoints.kt index 9e6816e..5b9cbf4 100644 --- a/api/src/main/kotlin/server/Endpoints.kt +++ b/api/src/main/kotlin/server/Endpoints.kt @@ -1,7 +1,10 @@ package com.jaytux.simd.server import com.jaytux.simd.data.* +import io.ktor.http.content.* +import io.ktor.server.response.* import io.ktor.server.routing.* +import kotlinx.datetime.LocalDate import kotlinx.serialization.Serializable import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.like @@ -37,6 +40,11 @@ data class IntrinsicDetails( val performance: List? ) +@Serializable +data class Versioning( + val intelVersion: String, val intelUpdate: LocalDate, val scrapeDate: LocalDate +) + fun Routing.installGetAll() { getPagedUrl("/all", { 100 }, { IntrinsicSummary(it.id.value, it.mnemonic) }) { Intrinsic.all().orderAsc(Intrinsics.mnemonic) @@ -125,4 +133,11 @@ fun Routing.installDetails() { } } } +} + +fun Routing.installVersion() { + get("/version") { + val upd = Loader.DatedVersion.fromPrefs() + call.respond(Versioning(upd.version.toString(), intelUpdate = upd.releaseDate, upd.updateDate)) + } } \ No newline at end of file diff --git a/api/src/main/kotlin/server/Routing.kt b/api/src/main/kotlin/server/Routing.kt index 15925c4..12dc2fd 100644 --- a/api/src/main/kotlin/server/Routing.kt +++ b/api/src/main/kotlin/server/Routing.kt @@ -63,6 +63,7 @@ fun Application.configureRouting() { installGetAll() installSearch() installDetails() + installVersion() } }