aboutsummaryrefslogtreecommitdiff
path: root/server/core
diff options
context:
space:
mode:
Diffstat (limited to 'server/core')
-rw-r--r--server/core/build.gradle.kts23
-rw-r--r--server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt53
-rw-r--r--server/core/src/main/kotlin/moe/nea/ledger/server/core/api/BaseApi.kt50
3 files changed, 109 insertions, 17 deletions
diff --git a/server/core/build.gradle.kts b/server/core/build.gradle.kts
index 87f613a..6300a4b 100644
--- a/server/core/build.gradle.kts
+++ b/server/core/build.gradle.kts
@@ -2,19 +2,21 @@ plugins {
kotlin("jvm")
kotlin("plugin.serialization")
application
+ id("com.github.gmazzo.buildconfig")
}
-val ktor_version = "3.0.3"
dependencies {
- implementation(platform("io.ktor:ktor-bom:$ktor_version"))
- implementation("io.ktor:ktor-server-netty")
- implementation("io.ktor:ktor-server-status-pages")
- implementation("io.ktor:ktor-server-content-negotiation")
- implementation("io.ktor:ktor-server-openapi")
- implementation("io.ktor:ktor-serialization-kotlinx-json")
- implementation("io.ktor:ktor-server-compression")
- implementation(project(":database:impl"))
+ declareKtorVersion()
+ api("io.ktor:ktor-server-netty")
+ api("io.ktor:ktor-server-status-pages")
+ api("io.ktor:ktor-server-content-negotiation")
+ api("io.ktor:ktor-serialization-kotlinx-json")
+ api("io.ktor:ktor-server-compression")
+ api("io.ktor:ktor-server-cors")
+ api("sh.ondr:kotlin-json-schema:0.1.1")
+ api(project(":database:impl"))
+ api(project(":server:swagger"))
runtimeOnly("ch.qos.logback:logback-classic:1.5.16")
runtimeOnly("org.xerial:sqlite-jdbc:3.45.3.0")
@@ -29,3 +31,6 @@ application {
"-Dledger.databasefolder=${project(":mod").file("run/money-ledger").absoluteFile}")
mainClass.set("moe.nea.ledger.server.core.ApplicationKt")
}
+buildConfig {
+ packageName("moe.nea.ledger.gen")
+}
diff --git a/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt b/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
index 0ea6ed3..23b2a6a 100644
--- a/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
+++ b/server/core/src/main/kotlin/moe/nea/ledger/server/core/Application.kt
@@ -6,29 +6,76 @@ import io.ktor.server.application.install
import io.ktor.server.netty.EngineMain
import io.ktor.server.plugins.compression.Compression
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
+import io.ktor.server.plugins.cors.routing.CORS
+import io.ktor.server.response.respondRedirect
+import io.ktor.server.routing.Routing
+import io.ktor.server.routing.get
import io.ktor.server.routing.route
import io.ktor.server.routing.routing
+import kotlinx.serialization.json.Json
import moe.nea.ledger.database.Database
+import moe.nea.ledger.gen.BuildConfig
+import moe.nea.ledger.server.core.api.Documentation
+import moe.nea.ledger.server.core.api.Info
+import moe.nea.ledger.server.core.api.Server
import moe.nea.ledger.server.core.api.apiRouting
+import moe.nea.ledger.server.core.api.openApiDocsJson
+import moe.nea.ledger.server.core.api.openApiUi
+import moe.nea.ledger.server.core.api.setApiRoot
import java.io.File
fun main(args: Array<String>) {
EngineMain.main(args)
}
+interface AIOProvider {
+ fun Routing.installExtraRouting()
+ fun Application.module()
+}
fun Application.module() {
+ val aio = runCatching {
+ Class.forName("moe.nea.ledger.server.aio.AIO")
+ .newInstance() as AIOProvider
+ }.getOrNull()
+ aio?.run { module() }
install(Compression)
+ install(Documentation) {
+ info = Info(
+ "Ledger Analysis Server",
+ "Your local API for loading ledger data",
+ BuildConfig.VERSION
+ )
+ servers.add(
+ Server("http://localhost:8080/api", "Your Local Server")
+ )
+ }
install(ContentNegotiation) {
- json()
+ json(Json {
+ this.explicitNulls = false
+ this.encodeDefaults = true
+ })
// cbor()
}
- val database = Database(File(System.getProperty("ledger.databasefolder")))
+ install(CORS) {
+ anyHost()
+ }
+ val database = Database(File(System.getProperty("ledger.databasefolder",
+ "/home/nea/.local/share/PrismLauncher/instances/Skyblock/.minecraft/money-ledger")))
database.loadAndUpgrade()
routing {
route("/api") {
- this.apiRouting(database)
+ setApiRoot()
+ get { call.respondRedirect("/openapi/") }
+ apiRouting(database)
+ }
+ route("/api.json") {
+ openApiDocsJson()
+ }
+ route("/openapi") {
+ openApiUi("/api.json")
}
+ aio?.run { installExtraRouting() }
}
}
diff --git a/server/core/src/main/kotlin/moe/nea/ledger/server/core/api/BaseApi.kt b/server/core/src/main/kotlin/moe/nea/ledger/server/core/api/BaseApi.kt
index 264f74b..c58763f 100644
--- a/server/core/src/main/kotlin/moe/nea/ledger/server/core/api/BaseApi.kt
+++ b/server/core/src/main/kotlin/moe/nea/ledger/server/core/api/BaseApi.kt
@@ -1,18 +1,21 @@
package moe.nea.ledger.server.core.api
+import io.ktor.http.Url
+import io.ktor.http.toURI
import io.ktor.server.response.respond
-import io.ktor.server.response.respondText
import io.ktor.server.routing.Route
-import io.ktor.server.routing.Routing
import io.ktor.server.routing.get
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.async
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.decodeFromStream
import moe.nea.ledger.database.DBLogEntry
import moe.nea.ledger.database.Database
import moe.nea.ledger.server.core.Profile
+import sh.ondr.jsonschema.jsonSchema
fun Route.apiRouting(database: Database) {
- get("/") {
- call.respondText("K")
- }
get("/profiles") {
val profiles = DBLogEntry.from(database.connection)
.select(DBLogEntry.playerId, DBLogEntry.profileId)
@@ -21,5 +24,42 @@ fun Route.apiRouting(database: Database) {
Profile(it[DBLogEntry.playerId], it[DBLogEntry.profileId])
}
call.respond(profiles)
+ }.docs {
+ summary = "List all profiles and players known to ledger"
+ operationId = "listProfiles"
+ tag(Tags.PROFILE)
+ respondsOk {
+ schema<List<Profile>>()
+ }
+ }
+ @OptIn(DelicateCoroutinesApi::class)
+ val itemNames = GlobalScope.async {
+ val itemNamesUrl =
+ Url("https://github.com/nea89o/ledger-auxiliary-data/raw/refs/heads/master/data/item_names.json")
+ Json.decodeFromStream<Map<String, String>>(itemNamesUrl.toURI().toURL().openStream())
+ }
+ get("/item") {
+ val itemIds = call.queryParameters.getAll("itemId")?.toSet() ?: emptySet()
+ val itemNameMap = itemNames.await()
+ call.respond(itemIds.associateWith { itemNameMap[it] })
+ }.docs {
+ summary = "Get item names for item ids"
+ operationId = "getItemNames"
+ tag(Tags.HYPIXEL)
+ queryParameter<List<String>>("itemId")
+ respondsOk {
+ schema<Map<String, String?>>()
+ }
}
}
+
+enum class Tags : IntoTag {
+ PROFILE,
+ HYPIXEL,
+ MANAGEMENT,
+ ;
+
+ override fun intoTag(): String {
+ return name
+ }
+} \ No newline at end of file