Document usage on about page
This commit is contained in:
parent
96c335c41a
commit
ede3297808
@ -1 +1,2 @@
|
|||||||
database.password=12345
|
database.password=12345
|
||||||
|
server.domain=localhost
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>()
|
||||||
}
|
}
|
69
src/main/kotlin/moe/kageru/kodeshare/pages/AboutPage.kt
Normal file
69
src/main/kotlin/moe/kageru/kodeshare/pages/AboutPage.kt
Normal 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."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -22,8 +22,8 @@ object PastePage {
|
|||||||
+content
|
+content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div("back") {
|
|
||||||
a("/") {
|
a("/") {
|
||||||
|
div(Css.FLOATY_CLASS) {
|
||||||
+"New paste"
|
+"New paste"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user