1
0
forked from SPC/spc-site

Implemented binary propagation

This commit is contained in:
Alexander Nozik 2023-03-27 10:23:25 +03:00
parent 6c384b2d7b
commit 1f0d0a8124
11 changed files with 83 additions and 87 deletions

View File

@ -5,7 +5,7 @@ section_title: Как поступить?
language: ru language: ru
--- ---
Чтобы принять участие в программе, необходимо: Чтобы принять участие в программе, необходимо:
* заполнить **[анкету](https://docs.google.com/forms/d/e/1FAIpQLSf9w0zxHY90zI5Mze5XRKHLO7gxa__bro8PDC2PlwsPfcMkfw/viewform?usp=sf_link)**. В анкете надо указать одного или нескольких научных руководителей, с которыми вы бы хотели работать; * заполнить **[анкету](https://forms.yandex.ru/cloud/641ad7fe73cee702c7753776/)**. В анкете надо указать одного или нескольких научных руководителей, с которыми вы бы хотели работать;
* **до 30 июня** пройти собеседование с научными руководителями и согласовать предполагаемый план обучения; * **до 30 июня** пройти собеседование с научными руководителями и согласовать предполагаемый план обучения;
* подать документы в магистратуру МФТИ согласно [правилам поступления](https://pk.mipt.ru/master/) (направление **ЛФИ "Прикладная математика и физика"**, **ЛФИ "Ядерная физика и технологии"** или **ФПМИ "Информатика и вычислительная техника"**). Если есть соглашение с научным руководителем, но не удалось пройти по конкурсу, то обучение с большой вероятностью будет оплачено нашими партнерами. * подать документы в магистратуру МФТИ согласно [правилам поступления](https://pk.mipt.ru/master/) (направление **ЛФИ "Прикладная математика и физика"**, **ЛФИ "Ядерная физика и технологии"** или **ФПМИ "Информатика и вычислительная техника"**). Если есть соглашение с научным руководителем, но не удалось пройти по конкурсу, то обучение с большой вероятностью будет оплачено нашими партнерами.

View File

@ -1,4 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
toolsVersion=0.14.3-kotlin-1.8.10 toolsVersion=0.14.5-kotlin-1.8.20-RC
snarkVersion=0.1.0-dev-1 snarkVersion=0.1.0-dev-1

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,7 +1,7 @@
rootProject.name = "spc-site" rootProject.name = "spc-site"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
enableFeaturePreview("VERSION_CATALOGS") //enableFeaturePreview("VERSION_CATALOGS")
pluginManagement { pluginManagement {

View File

@ -8,12 +8,20 @@ import io.ktor.server.plugins.forwardedheaders.XForwardedHeaders
import io.ktor.server.response.respondRedirect import io.ktor.server.response.respondRedirect
import io.ktor.server.routing.get import io.ktor.server.routing.get
import io.ktor.server.routing.routing import io.ktor.server.routing.routing
import space.kscience.snark.SnarkEnvironment import space.kscience.dataforge.context.Global
import space.kscience.snark.ktor.extractResources import space.kscience.dataforge.context.request
import space.kscience.dataforge.data.DataSet
import space.kscience.dataforge.data.DataTree
import space.kscience.dataforge.data.node
import space.kscience.dataforge.data.populateFrom
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.snark.html.SiteBuilder
import space.kscience.snark.html.SnarkHtmlPlugin
import space.kscience.snark.html.readDirectory
import space.kscience.snark.ktor.prepareSnarkDataCacheDirectory import space.kscience.snark.ktor.prepareSnarkDataCacheDirectory
import space.kscience.snark.ktor.site import space.kscience.snark.ktor.site
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.div
@Suppress("unused") @Suppress("unused")
fun Application.spcModule() { fun Application.spcModule() {
@ -25,38 +33,13 @@ fun Application.spcModule() {
prepareSnarkDataCacheDirectory(dataPath) prepareSnarkDataCacheDirectory(dataPath)
SnarkEnvironment.default.site { val snark = Global.request(SnarkHtmlPlugin)
val siteData = snark.readDirectory(dataPath)
extractResources( site(snark, siteData, block = SiteBuilder::spcSite)
"/common",
dataPath / "common"
)
val homeDataPath = extractResources( routing {
"/home", get("magprog") {
dataPath / "home"
)
spcHome(dataPath = homeDataPath)
val mastersDataPath = extractResources(
"/magprog",
dataPath / "magprog"
)
spcMasters(dataPath = mastersDataPath)
val bmkDataPath = extractResources(
"/bmk",
dataPath / "bmk"
)
bmk(dataPath = bmkDataPath)
}
routing{
get("magprog"){
call.respondRedirect("education/masters") call.respondRedirect("education/masters")
} }
} }

View File

@ -13,7 +13,6 @@ import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.parseAsName
import space.kscience.snark.html.* import space.kscience.snark.html.*
import java.nio.file.Path
private val Data<*>.title: String private val Data<*>.title: String
@ -23,21 +22,21 @@ private val Data<*>.fragment: String
get() = meta["fragment"].string ?: "" get() = meta["fragment"].string ?: ""
internal fun SiteBuilder.bmk(dataPath: Path, prefix: Name = "bmk".parseAsName()) { internal fun SiteBuilder.bmk(data: DataTree<Any>, prefix: Name = "bmk".parseAsName()) {
val data: DataTree<Any> = snark.readDirectory(dataPath.resolve("content")) // val data: DataTree<Any> = snark.readDirectory(dataPath.resolve("content"))
site(prefix, data) { site(prefix, data) {
file(dataPath.resolve("assets")) static("assets")
file(dataPath.resolve("images")) static("images")
file(dataPath.resolve("../common/assets/webfonts"), "assets/webfonts") static("common.assets.webfonts", "assets/webfonts")
file(dataPath.resolve("../common"), "") static("common", "")
val about: Data<HtmlFragment> = data.resolveHtml("about")!! val about: Data<HtmlFragment> = data.resolveHtml("about")
val team: Data<HtmlFragment> = data.resolveHtml("team.index")!! val team: Data<HtmlFragment> = data.resolveHtml("team.index")
val teamData: Map<Name, Data<HtmlFragment>> = data.resolveAllHtml { _, meta -> meta["type"].string == "team" } val teamData: Map<Name, Data<HtmlFragment>> = data.resolveAllHtml { _, meta -> meta["type"].string == "team" }
val solutions: Data<HtmlFragment> = data.resolveHtml("lotSeis")!! val solutions: Data<HtmlFragment> = data.resolveHtml("lotSeis")
val partners: Data<HtmlFragment> = data.resolveHtml("partners")!! val partners: Data<HtmlFragment> = data.resolveHtml("partners")
val partnersData = runBlocking { data.getByType<Meta>("partnersData")!!.await() } val partnersData = runBlocking { data.getByType<Meta>("partnersData")!!.await() }
page { page {

View File

@ -63,12 +63,8 @@ context(WebPage) private fun FlowContent.spcSpotlightContent(
header("major") { header("major") {
h3 { +(entry.meta["title"].string ?: "???") } h3 { +(entry.meta["title"].string ?: "???") }
} }
val infoData = data.resolveHtml(name.withIndex("info")) val infoData = data.resolveHtmlOrNull(name.replaceLast { NameToken(it.body + "[info]") }) ?: entry
if (infoData == null) {
htmlData(entry)
} else {
htmlData(infoData) htmlData(infoData)
}
ul("actions") { ul("actions") {
li { li {
a(classes = "button") { a(classes = "button") {
@ -92,8 +88,8 @@ internal fun SiteBuilder.spcSpotlight(
) { ) {
val pageName = address.parseAsName() val pageName = address.parseAsName()
val languagePrefix = languagePrefix val languagePrefix = languagePrefix
val body = data.resolveHtml(languagePrefix + pageName) val body = data.resolveHtmlOrNull(languagePrefix + pageName)
?: data.resolveHtml(pageName) ?: error("Could not find body for $pageName") ?: data.resolveHtmlOrNull(pageName) ?: error("Could not find body for $pageName")
val content: Map<Name, Data<HtmlFragment>> = val content: Map<Name, Data<HtmlFragment>> =
data.resolveAllHtml { name, meta -> name.startsWith(languagePrefix) && contentFilter(name, meta) } data.resolveAllHtml { name, meta -> name.startsWith(languagePrefix) && contentFilter(name, meta) }

View File

@ -9,7 +9,6 @@ import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.startsWith
import space.kscience.snark.html.* import space.kscience.snark.html.*
import java.nio.file.Path
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
@ -68,7 +67,7 @@ internal val FortyDataRenderer: DataRenderer = object : DataRenderer {
} }
page(name, dataMeta) { page(name, dataMeta) {
spcPageContent{ spcPageContent {
htmlData(data) htmlData(data)
} }
} }
@ -77,7 +76,7 @@ internal val FortyDataRenderer: DataRenderer = object : DataRenderer {
} }
context(WebPage) private fun HTML.spcHome() { context(WebPage) private fun HTML.spcHomePage() {
spcHead() spcHead()
body("is-preload") { body("is-preload") {
wrapper { wrapper {
@ -264,21 +263,20 @@ context(WebPage) private fun HTML.spcHome() {
} }
} }
internal fun SiteBuilder.spcHome(dataPath: Path, prefix: Name = Name.EMPTY) { internal fun SiteBuilder.spcHome(homePageData: DataTree<Any>, prefix: Name = Name.EMPTY) {
val homePageData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content")) //val homePageData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content"))
site(prefix, homePageData) { site(prefix, homePageData) {
file(dataPath.resolve("assets")) static("assets")
file(dataPath.resolve("images")) static("images")
file(dataPath.resolve("../common/assets/webfonts"), "assets/webfonts") static("common", "")
file(dataPath.resolve("../common"), "")
withLanguages( withLanguages(
"en" to "", "en" to "",
"ru" to "ru" "ru" to "ru"
) { ) {
page { spcHome() } page { spcHomePage() }
localizedPages("consulting", dataRenderer = FortyDataRenderer) localizedPages("consulting", dataRenderer = FortyDataRenderer)
@ -293,5 +291,4 @@ internal fun SiteBuilder.spcHome(dataPath: Path, prefix: Name = Name.EMPTY) {
} }
} }
} }
} }

View File

@ -12,7 +12,6 @@ import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.* import space.kscience.dataforge.names.*
import space.kscience.snark.SnarkContext import space.kscience.snark.SnarkContext
import space.kscience.snark.html.* import space.kscience.snark.html.*
import java.nio.file.Path
import kotlin.collections.component1 import kotlin.collections.component1
import kotlin.collections.component2 import kotlin.collections.component2
import kotlin.collections.set import kotlin.collections.set
@ -70,8 +69,8 @@ private val RECOMMENDED_COURSES_PATH: Name = CONTENT_NODE_NAME + "recommendedCou
private val PARTNERS_PATH: Name = CONTENT_NODE_NAME + "partners" private val PARTNERS_PATH: Name = CONTENT_NODE_NAME + "partners"
context(WebPage) private fun FlowContent.programSection() { context(WebPage) private fun FlowContent.programSection() {
val programBlock = data.resolveHtml(PROGRAM_PATH)!! val programBlock = data.resolveHtmlOrNull(PROGRAM_PATH)!!
val recommendedBlock = data.resolveHtml(RECOMMENDED_COURSES_PATH)!! val recommendedBlock = data.resolveHtmlOrNull(RECOMMENDED_COURSES_PATH)!!
div("inner") { div("inner") {
h2 { +"Учебная программа" } h2 { +"Учебная программа" }
htmlData(programBlock) htmlData(programBlock)
@ -199,7 +198,7 @@ context(WebPage) private fun FlowContent.mentors() {
h2 { h2 {
a(href = ref) { +mentor.name } a(href = ref) { +mentor.name }
} }
val info = data.resolveHtml(name.withIndex("info")) val info = data.resolveHtmlOrNull(name.replaceLast { NameToken(it.body + "[info]") })
if (info != null) { if (info != null) {
htmlData(info) htmlData(info)
} }
@ -300,19 +299,18 @@ context(WebPage) internal fun BODY.magProgFooter() {
context(SnarkContext) private val HtmlData.mentorPageId get() = "mentor-${id}" context(SnarkContext) private val HtmlData.mentorPageId get() = "mentor-${id}"
internal fun SiteBuilder.spcMasters(dataPath: Path, prefix: Name = "education.masters".parseAsName()) { internal fun SiteBuilder.spcMasters(magProgData: DataTree<Any>, prefix: Name = "education.masters".parseAsName()) {
val magProgData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content")) //val magProgData: DataTree<Any> = snark.readDirectory(dataPath.resolve("content"))
site(prefix, magProgData) { site(prefix, magProgData) {
file(dataPath.resolve("assets")) static("assets")
file(dataPath.resolve("images")) static("images")
file(dataPath.resolve("../common/assets/webfonts"), "assets/webfonts") static("common", "")
file(dataPath.resolve("../common"), "")
page { page {
val sections = listOf<MagProgSection>( val sections = listOf<MagProgSection>(
wrapSection(data.resolveHtml(INTRO_PATH)!!, "intro"), wrapSection(page.data.resolveHtmlOrNull(INTRO_PATH)!!, "intro"),
MagProgSection( MagProgSection(
id = "partners", id = "partners",
title = "Партнеры", title = "Партнеры",
@ -335,9 +333,9 @@ internal fun SiteBuilder.spcMasters(dataPath: Path, prefix: Name = "education.ma
) { ) {
programSection() programSection()
}, },
wrapSection(data.resolveHtml(ENROLL_PATH)!!, "enroll"), wrapSection(page.data.resolveHtmlOrNull(ENROLL_PATH)!!, "enroll"),
wrapSection(id = "contacts", title = "Контакты") { wrapSection(id = "contacts", title = "Контакты") {
htmlData(data.resolveHtml(CONTACTS_PATH)!!) htmlData(page.data.resolveHtmlOrNull(CONTACTS_PATH)!!)
team() team()
} }
) )

View File

@ -0,0 +1,21 @@
package center.sciprog
import space.kscience.dataforge.data.*
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.snark.html.SiteBuilder
@OptIn(DFExperimental::class)
private fun <T : Any> DataSet<T>.siteData(branchName: String): DataTree<T> = DataTree(dataType) {
populateFrom(branch(Name.of(branchName, "content")))
node("common", branch("common"))
node("assets", branch(Name.of(branchName, "assets")))
node("images", branch(Name.of(branchName, "images")))
}
fun SiteBuilder.spcSite() {
// val commonData = data.branch("common")
spcHome(data.siteData("home"))
spcMasters(data.siteData("magprog"))
// bmk(data.branch("bmk").withBranch("common", commonData))
}

View File

@ -1,14 +1,16 @@
package center.sciprog package center.sciprog
import space.kscience.snark.SnarkEnvironment import space.kscience.dataforge.context.Global
import space.kscience.dataforge.context.request
import space.kscience.snark.html.SiteBuilder
import space.kscience.snark.html.SnarkHtmlPlugin
import space.kscience.snark.html.readResourceDirectory
import space.kscience.snark.html.static import space.kscience.snark.html.static
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.toPath
fun main() { fun main() {
SnarkEnvironment.default.static(Path.of("build/public"), siteUrl = "") { val snark = Global.request(SnarkHtmlPlugin)
spcHome(dataPath = javaClass.getResource("/home")!!.toURI().toPath()) val siteData = snark.readResourceDirectory()
spcMasters(dataPath = javaClass.getResource("/magprog")!!.toURI().toPath())
bmk(dataPath = javaClass.getResource("/bmk")!!.toURI().toPath()) snark.static(siteData, Path.of("build/public"), siteUrl = "", block = SiteBuilder::spcSite)
}
} }