From d513f5e0dc36817ae87f2778ab0cc1ca7798d290 Mon Sep 17 00:00:00 2001 From: Lanius Trolling Date: Wed, 17 Jan 2024 08:30:01 -0500 Subject: [PATCH] Add random quote endpoint --- .../kotlin/info/mechyrdia/Factbooks.kt | 14 ++++ .../kotlin/info/mechyrdia/lore/view_bar.kt | 16 +++- .../kotlin/info/mechyrdia/lore/views_quote.kt | 80 +++++++++++++++++++ stuff/fixquotes.py | 26 ++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/jvmMain/kotlin/info/mechyrdia/lore/views_quote.kt create mode 100644 stuff/fixquotes.py diff --git a/src/jvmMain/kotlin/info/mechyrdia/Factbooks.kt b/src/jvmMain/kotlin/info/mechyrdia/Factbooks.kt index f2f6f8e..36316cd 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/Factbooks.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/Factbooks.kt @@ -154,6 +154,20 @@ fun Application.factbooks() { call.respondFile(call.galaxyMapPage()) } + // Random quote + + get("/quote") { + with(call) { respondHtml(HttpStatusCode.OK, randomQuote().toHtml("Random Quote")) } + } + + get("/quote.json") { + call.respondText(randomQuote().toJson(), ContentType.Application.Json) + } + + get("/quote.xml") { + call.respondText(randomQuote().toXml(), ContentType.Application.Xml) + } + // Routes for robots get("/robots.txt") { diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/view_bar.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/view_bar.kt index 5a9346b..2cc0c8c 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/view_bar.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/view_bar.kt @@ -25,7 +25,21 @@ data class NationProfileSidebar(val nationData: NationData) : Sidebar() { img(src = nationData.flag, alt = "Flag of ${nationData.name}", classes = "flag-icon") p { style = "text-align:center" - +nationData.name + a(href = "https://www.nationstates.net/nation=${nationData.id}") { + +nationData.name + } + } + } +} + +data class QuoteOriginSidebar(val author: String, val portrait: String, val link: String) : Sidebar() { + override fun TagConsumer<*>.display() { + img(src = "/assets/images/$portrait", alt = "Portrait of $author") + p { + style = "text-align:center" + a(href = "/lore/$link") { + +author + } } } } diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/views_quote.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/views_quote.kt new file mode 100644 index 0000000..a38ede2 --- /dev/null +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/views_quote.kt @@ -0,0 +1,80 @@ +package info.mechyrdia.lore + +import info.mechyrdia.Configuration +import info.mechyrdia.JsonFileCodec +import io.ktor.server.application.* +import io.ktor.util.* +import kotlinx.html.* +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put +import java.io.File + +@Serializable +data class Quote( + val quote: String, + val author: String, + val portrait: String, + val link: String +) { + val fullPortrait: String + get() = if (portrait.startsWith("http://") || portrait.startsWith("https://")) + portrait + else + "https://mechyrdia.info/assets/images/$portrait" + + val fullLink: String + get() = if (link.startsWith("http://") || link.startsWith("https://")) + link + else + "https://mechyrdia.info/lore/$link" +} + +fun loadQuotes(): List { + val quotesJsonFile = File(Configuration.CurrentConfiguration.rootDir).combineSafe("quotes.json") + return JsonFileCodec.decodeFromString(ListSerializer(Quote.serializer()), quotesJsonFile.readText()) +} + +fun randomQuote(): Quote = loadQuotes().random() + +fun Quote.toXml(standalone: Boolean = true): String { + return buildString { + if (standalone) + appendLine("") + appendLine("") + append("").append(quote.escapeHTML()).appendLine("") + append("").append(author.escapeHTML()).appendLine("") + append("") + append("") + appendLine("") + } +} + +fun Quote.toJson(): String { + return buildJsonObject { + put("text", quote) + put("author", author) + put("portrait", fullPortrait) + put("link", fullLink) + }.toString() +} + +context(ApplicationCall) +suspend fun Quote.toHtml(title: String): HTML.() -> Unit { + return page(title, standardNavBar(), QuoteOriginSidebar(author, portrait, link)) { + section { + a { id = "page-top" } + h1 { +title } + blockQuote { + +quote + } + p { + style = "align:right" + unsafe { raw("―") } + +Entities.nbsp + a(href = "/lore/$link") { +author } + } + } + } +} diff --git a/stuff/fixquotes.py b/stuff/fixquotes.py new file mode 100644 index 0000000..e4e379f --- /dev/null +++ b/stuff/fixquotes.py @@ -0,0 +1,26 @@ +import json +import re + +quote_pattern = re.compile(r"^\"(.*)\" \- (.*?)\|(.*?)\@(.*?)$") + +quote_list = [] + +with open("../test/quotes.json", mode="r", encoding="utf-8") as quotes_json_file: + quote_list.extend(json.load(quotes_json_file)) + +with open("../test/quotes.txt", mode="r", encoding="utf-8") as quotes_file: + for quote in quotes_file: + quote = quote.rstrip() + match = quote_pattern.fullmatch(quote) + + text, author, portrait, link = match.groups() + quote_dict = { + "quote": text, + "author": author, + "portrait": "portrait-" + portrait.lower().replace(" ", "-").replace("'", ""), + "link": link.removeprefix("https://mechyrdia.info/lore/") + } + quote_list.append(quote_dict) + +with open("../test/quotes.json", mode="w", encoding="utf-8") as quotes_json_file: + json.dump(quote_list, quotes_json_file, indent="\t") -- 2.25.1