Document usage on about page

This commit is contained in:
kageru 2019-09-29 11:50:14 +02:00
parent 96c335c41a
commit ede3297808
7 changed files with 107 additions and 14 deletions

View File

@ -1 +1,2 @@
database.password=12345 database.password=12345
server.domain=localhost

View File

@ -17,6 +17,9 @@ import io.ktor.response.respondText
import io.ktor.routing.Routing import io.ktor.routing.Routing
import io.ktor.routing.get import io.ktor.routing.get
import io.ktor.routing.post import io.ktor.routing.post
import moe.kageru.kodeshare.config.ServerSpec
import moe.kageru.kodeshare.config.config
import moe.kageru.kodeshare.pages.AboutPage
import moe.kageru.kodeshare.pages.Css import moe.kageru.kodeshare.pages.Css
import moe.kageru.kodeshare.pages.Homepage import moe.kageru.kodeshare.pages.Homepage
import moe.kageru.kodeshare.pages.PastePage import moe.kageru.kodeshare.pages.PastePage
@ -39,6 +42,9 @@ object Routes {
get("/favicon.ico") { get("/favicon.ico") {
call.respond(HttpStatusCode.NotFound) call.respond(HttpStatusCode.NotFound)
} }
get("/about") {
call.respond(HttpStatusCode.OK, AboutPage.content)
}
get<PasteRequest> { req -> get<PasteRequest> { req ->
call.handleGet(req) call.handleGet(req)
} }
@ -79,7 +85,7 @@ object Routes {
respond(HttpStatusCode.BadRequest, "Empty pastes are not allowed") respond(HttpStatusCode.BadRequest, "Empty pastes are not allowed")
return null return null
} }
if (content.length > 1 * 1024 * 1024) { if (content.length > 1024 * 1024) {
Log.info("Rejecting paste over 1MB") Log.info("Rejecting paste over 1MB")
respond(HttpStatusCode.BadRequest, "Pastes are limited to 1MB each") respond(HttpStatusCode.BadRequest, "Pastes are limited to 1MB each")
return null return null
@ -89,7 +95,7 @@ object Routes {
// while also redirecting browser uploads to the newly created paste. // while also redirecting browser uploads to the newly created paste.
// May seem odd to return code 302, but it seems to be the only way. // May seem odd to return code 302, but it seems to be the only way.
response.headers.append(HttpHeaders.Location, uri) response.headers.append(HttpHeaders.Location, uri)
respond(HttpStatusCode.Found, uri) respond(HttpStatusCode.Found, "${config[ServerSpec.domain]}/$uri")
return uri return uri
} }

View File

@ -18,4 +18,6 @@ object DatabaseSpec : ConfigSpec() {
object ServerSpec : ConfigSpec() { object ServerSpec : ConfigSpec() {
val port by optional(9092) val port by optional(9092)
// this is needed to return full URLs when uploading via curl and for the AboutPage
val domain by required<String>()
} }

View File

@ -0,0 +1,69 @@
package moe.kageru.kodeshare.pages
import io.ktor.html.HtmlContent
import io.ktor.http.HttpStatusCode
import kotlinx.html.*
import moe.kageru.kodeshare.config.ServerSpec
import moe.kageru.kodeshare.config.config
object AboutPage {
private val domain = "https://${config[ServerSpec.domain]}"
val content = HtmlContent(HttpStatusCode.OK) {
head {
link(rel = "stylesheet", href = "/style.css", type = "text/css")
}
body {
div("wrapper") {
h2 { +"kodeshare - yet another paste service" }
a("/") { div(Css.FLOATY_CLASS) { +"Back" } }
p {
+"Hi. I’m kageru, and I didn’t want to rely on hastebin and the likes anymore."
br
+"I had a few hours to spare on a train trip, so I decided to try "
a("https://ktor.io") { +"ktor" }
+" for web programming in Kotlin."
br
+"If you’re interested, the source code can be found "
a("https://git.kageru.moe/kageru/kodeshare") { +"on my Gitea." }
}
h3 { +"Usage" }
p {
+"Everything you see here can also be used via CLI."
div("framed") {
+"$ curl -F'file=@someFile' $domain/"
br
+"# returns"
br
+"$domain/rx78"
}
+"If you need to download or view a file as plain text, simply add /r/ after the domain name. "
br
+"Using our earlier example, the raw link would be:"
div("framed") {
+"$domain/r/rx78"
}
+" The HTML view uses "
a("https://highlightjs.org/") { +"highlight.js" }
+" for syntax highlighting. "
+"If the automatic detection fails, you can override it by appending the file extension to the url."
br
div("framed") {
+"$domain/rx78/kt"
}
+"I wanted to use “/<id>.<ext>”, but it looks like ktor locations don’t work like that. Or I’m just bad at this."
br
br
+"If you choose to disable Javascript entirely, everything other than the syntax highlighting will still work as intended. "
+"Pastes will simply be monochrome."
}
h3 { +"Expiration & limits" }
p {
+"All pastes are limited to 1 MiB, and empty pastes are rejected."
br
+"Right now, pastes are not pruned or deleted at all. "
+"If more people start using this, I might add something that deletes unaccessed pastes after a few months. We’ll see."
}
}
}
}
}

View File

@ -1,12 +1,10 @@
package moe.kageru.kodeshare.pages package moe.kageru.kodeshare.pages
import kotlinx.css.* import kotlinx.css.*
import kotlinx.css.properties.TextDecoration import kotlinx.css.properties.*
import kotlinx.css.properties.border
import kotlinx.css.properties.ms
import kotlinx.css.properties.transition
object Css { object Css {
const val FLOATY_CLASS = "floatything"
private val accent1 = Color("#e6db74") private val accent1 = Color("#e6db74")
private val accent2 = Color("#a6e22e") private val accent2 = Color("#a6e22e")
private val fontcolor = Color.lightGrey private val fontcolor = Color.lightGrey
@ -20,6 +18,9 @@ object Css {
backgroundColor = bgcolor backgroundColor = bgcolor
color = fontcolor color = fontcolor
} }
form {
marginTop = 1.em
}
textarea { textarea {
fontFamily = "Hack, Fira Code, Noto Mono, monospace" fontFamily = "Hack, Fira Code, Noto Mono, monospace"
backgroundColor = bgcolor backgroundColor = bgcolor
@ -31,7 +32,7 @@ object Css {
borderStyle = BorderStyle.solid borderStyle = BorderStyle.solid
padding = "5px" padding = "5px"
minWidth = 70.pct minWidth = 70.pct
maxWidth = 100.pct maxWidth = 97.pct
} }
// this doesn’t inherit the style from anything else for some reason // this doesn’t inherit the style from anything else for some reason
rule(".hljs, pre, code") { rule(".hljs, pre, code") {
@ -55,7 +56,7 @@ object Css {
cursor = Cursor.pointer cursor = Cursor.pointer
transition(duration = 500.ms) transition(duration = 500.ms)
} }
rule("div.back") { rule("div.$FLOATY_CLASS") {
position = Position.absolute position = Position.absolute
padding = "5px" padding = "5px"
border(2.px, BorderStyle.solid, accent1) border(2.px, BorderStyle.solid, accent1)
@ -65,6 +66,22 @@ object Css {
right = 1.em right = 1.em
zIndex = 1 zIndex = 1
} }
rule("div.$FLOATY_CLASS:hover") {
color = accent2
borderColor = accent2
}
rule("div.wrapper") {
margin = "auto"
lineHeight = LineHeight("140%")
width = 70.pct
textAlign = TextAlign.left
}
rule(".framed") {
border(1.px, BorderStyle.solid, fontcolor)
padding = "0.3em"
margin = "0.5em"
marginBottom = 1.em
}
rule("input[type=\"submit\"]:hover") { rule("input[type=\"submit\"]:hover") {
backgroundColor = Color.transparent backgroundColor = Color.transparent
borderColor = accent2 borderColor = accent2

View File

@ -13,13 +13,11 @@ object Homepage {
} }
} }
body { body {
h1 { +"kodeshare - yet another paste service" } a("/about") { div(Css.FLOATY_CLASS) { +"About" } }
form("/", encType = FormEncType.multipartFormData, method = FormMethod.post) { form("/", encType = FormEncType.multipartFormData, method = FormMethod.post) {
acceptCharset = "utf-8" acceptCharset = "utf-8"
p {
label { +"Enter or paste your text here " }
}
textArea { textArea {
autoFocus = true
name = "input" name = "input"
rows = "20" rows = "20"
cols = "100" cols = "100"

View File

@ -22,8 +22,8 @@ object PastePage {
+content +content
} }
} }
div("back") { a("/") {
a("/") { div(Css.FLOATY_CLASS) {
+"New paste" +"New paste"
} }
} }