Resolving paths for static sites.

This commit is contained in:
Alexander Nozik 2022-06-22 23:35:16 +03:00
parent bafc75086a
commit d657282a33
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
7 changed files with 102 additions and 64 deletions

View File

@ -8,7 +8,7 @@ import kotlinx.html.style
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.fetch
import space.kscience.snark.SnarkPlugin
import space.kscience.snark.mountSnark
import space.kscience.snark.site
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
@ -50,7 +50,7 @@ fun Application.spcModule() {
val context = Context("spc-site") {
plugin(SnarkPlugin)
}
val snarkPlugin = context.fetch(SnarkPlugin)
val snark = context.fetch(SnarkPlugin)
val dataPath = Path.of("data")
@ -86,16 +86,16 @@ fun Application.spcModule() {
dataPath.resolve(DEPLOY_DATE_FILE).writeText(date)
}
mountSnark(snarkPlugin) {
snark.site {
val homeDataPath = resolveData(
javaClass.getResource("/home")!!.toURI(),
this@spcModule.javaClass.getResource("/home")!!.toURI(),
dataPath / "home"
)
spcHome(rootPath = homeDataPath)
val mastersDataPath = resolveData(
javaClass.getResource("/magprog")!!.toURI(),
this@spcModule.javaClass.getResource("/magprog")!!.toURI(),
dataPath / "magprog"
)

View File

@ -221,7 +221,7 @@ context(SiteData) internal fun HTML.magProgHead(title: String) {
}
link {
rel = "stylesheet"
href = resolveRef("css/main.css")
href = resolveRef("assets/css/main.css")
}
link {
rel = "shortcut icon"
@ -230,7 +230,7 @@ context(SiteData) internal fun HTML.magProgHead(title: String) {
noScript {
link {
rel = "stylesheet"
href = resolveRef("css/noscript.css")
href = resolveRef("assets/css/noscript.css")
}
}
}
@ -253,25 +253,25 @@ context(SiteData) internal fun BODY.magProgFooter() {
}
}
script {
src = resolveRef("js/jquery.min.js")
src = resolveRef("assets/js/jquery.min.js")
}
script {
src = resolveRef("js/jquery.scrollex.min.js")
src = resolveRef("assets/js/jquery.scrollex.min.js")
}
script {
src = resolveRef("js/jquery.scrolly.min.js")
src = resolveRef("assets/js/jquery.scrolly.min.js")
}
script {
src = resolveRef("js/browser.min.js")
src = resolveRef("assets/js/browser.min.js")
}
script {
src = resolveRef("js/breakpoints.min.js")
src = resolveRef("assets/js/breakpoints.min.js")
}
script {
src = resolveRef("js/util.js")
src = resolveRef("assets/js/util.js")
}
script {
src = resolveRef("js/main.js")
src = resolveRef("assets/js/main.js")
}
}
@ -282,7 +282,7 @@ internal fun SiteBuilder.spcMaster(dataPath: Path, prefix: Name = "magprog".asNa
val magProgSiteContext = snark.readDirectory(dataPath.resolve("content"))
mountSite(prefix, magProgSiteContext) {
assetDirectory("", dataPath.resolve("assets"))
assetDirectory("assets", dataPath.resolve("assets"))
assetDirectory("images", dataPath.resolve("images"))
page {

View File

@ -0,0 +1,15 @@
package ru.mipt.spc
import space.kscience.dataforge.context.Global
import space.kscience.dataforge.context.fetch
import space.kscience.snark.SnarkPlugin
import space.kscience.snark.static
import java.nio.file.Path
import kotlin.io.path.toPath
fun main() {
Global.fetch(SnarkPlugin).static(Path.of("build/out")) {
spcHome(rootPath = javaClass.getResource("/home")!!.toURI().toPath())
spcMaster(dataPath = javaClass.getResource("/magprog")!!.toURI().toPath())
}
}

View File

@ -1,11 +1,19 @@
package space.kscience.snark
import io.ktor.http.URLBuilder
import io.ktor.http.URLProtocol
import io.ktor.server.application.Application
import io.ktor.server.application.call
import io.ktor.server.html.respondHtml
import io.ktor.server.http.content.*
import io.ktor.server.plugins.origin
import io.ktor.server.request.ApplicationRequest
import io.ktor.server.request.host
import io.ktor.server.request.port
import io.ktor.server.routing.Route
import io.ktor.server.routing.createRouteFromPath
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import kotlinx.html.HTML
import space.kscience.dataforge.names.Name
import java.nio.file.Path
@ -44,3 +52,36 @@ class KtorSiteBuilder(override val data: SiteData, private val ktorRoute: Route)
override fun withData(newData: SiteData): SiteBuilder = KtorSiteBuilder(newData, ktorRoute)
}
@PublishedApi
internal fun SiteData.copyWithRequestHost(request: ApplicationRequest): SiteData {
val uri = URLBuilder(
protocol = URLProtocol.createOrDefault(request.origin.scheme),
host = request.host(),
port = request.port(),
pathSegments = baseUrlPath.split("/"),
)
return copy(baseUrlPath = uri.buildString())
}
inline fun Route.snarkSite(
data: SiteData,
block: SiteBuilder.() -> Unit,
) {
block(KtorSiteBuilder(data, this@snarkSite))
}
fun Application.snarkSite(
data: SiteData,
block: SiteBuilder.() -> Unit,
) {
routing {
snarkSite(data, block)
}
}
context (Application) fun SnarkPlugin.site(
block: SiteBuilder.() -> Unit,
) {
snarkSite(SiteData.empty(this), block)
}

View File

@ -1,8 +1,5 @@
package space.kscience.snark
import io.ktor.server.application.Application
import io.ktor.server.routing.Route
import io.ktor.server.routing.routing
import kotlinx.html.HTML
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.ContextAware
@ -66,27 +63,3 @@ public fun SiteBuilder.mountSite(route: Name, dataRoot: DataTree<*>, block: Site
withData(mountedData).block()
}
}
inline fun Route.mountSnark(
data: SiteData,
block: context(SiteData, SiteBuilder)() -> Unit,
) {
block(data, KtorSiteBuilder(data, this@mountSnark))
}
fun Application.mountSnark(
data: SiteData,
block: context(SiteData, SiteBuilder)() -> Unit,
) {
routing {
mountSnark(data, block)
}
}
fun Application.mountSnark(
snarkPlugin: SnarkPlugin,
block: context(SiteData, SiteBuilder)() -> Unit,
) {
mountSnark(SiteData.empty(snarkPlugin), block)
}

View File

@ -1,11 +1,5 @@
package space.kscience.snark
import io.ktor.http.URLBuilder
import io.ktor.http.URLProtocol
import io.ktor.server.plugins.origin
import io.ktor.server.request.ApplicationRequest
import io.ktor.server.request.host
import io.ktor.server.request.port
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.ContextAware
import space.kscience.dataforge.data.*
@ -93,14 +87,3 @@ internal val Data<*>.published: Boolean get() = meta["published"].string != "fal
//
// return readData(parsedData, rootUrl)
//}
@PublishedApi
internal fun SiteData.copyWithRequestHost(request: ApplicationRequest): SiteData {
val uri = URLBuilder(
protocol = URLProtocol.createOrDefault(request.origin.scheme),
host = request.host(),
port = request.port(),
pathSegments = baseUrlPath.split("/"),
)
return copy(baseUrlPath = uri.buildString())
}

View File

@ -4,26 +4,44 @@ import kotlinx.html.HTML
import kotlinx.html.html
import kotlinx.html.stream.createHTML
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.isEmpty
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.copyTo
import kotlin.io.path.createDirectories
import kotlin.io.path.relativeTo
import kotlin.io.path.writeText
class StaticSiteBuilder(override val data: SiteData, private val path: Path) : SiteBuilder {
private fun Path.copyRecursively(target: Path) {
Files.walk(this).forEach { source: Path ->
val destination: Path = target.resolve(source.relativeTo(this))
source.copyTo(destination,true)
}
}
override fun assetFile(remotePath: String, file: Path) {
file.copyTo(path.resolve(remotePath))
val targetPath = path.resolve(remotePath)
targetPath.parent.createDirectories()
file.copyTo(targetPath, true)
}
override fun assetDirectory(remotePath: String, directory: Path) {
directory.copyTo(path.resolve(remotePath))
val targetPath = path.resolve(remotePath)
targetPath.parent.createDirectories()
directory.copyRecursively(targetPath)
}
override fun assetResourceFile(remotePath: String, resourcesPath: String) {
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path.resolve(remotePath))
val targetPath = path.resolve(remotePath)
targetPath.parent.createDirectories()
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(targetPath,true)
}
override fun assetResourceDirectory(resourcesPath: String) {
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyTo(path)
path.parent.createDirectories()
javaClass.getResource(resourcesPath)?.let { Path.of(it.toURI()) }?.copyRecursively(path)
}
override fun page(route: Name, content: context(SiteData, HTML) () -> Unit) {
@ -33,7 +51,11 @@ class StaticSiteBuilder(override val data: SiteData, private val path: Path) : S
content(data, this)
}
val newPath = path.resolve(route.toWebPath() + ".html")
val newPath = if (route.isEmpty()) {
path.resolve("index.html")
} else {
path.resolve(route.toWebPath() + ".html")
}
newPath.parent.createDirectories()
newPath.writeText(htmlBuilder.finalize())
@ -44,3 +66,7 @@ class StaticSiteBuilder(override val data: SiteData, private val path: Path) : S
override fun withData(newData: SiteData): SiteBuilder = StaticSiteBuilder(newData, path)
}
fun SnarkPlugin.static(path: Path, block: SiteBuilder.() -> Unit) {
StaticSiteBuilder(SiteData.empty(this), path).block()
}