diff --git a/build.gradle.kts b/build.gradle.kts index ce4690d..09c35fd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import ru.mipt.npm.gradle.KScienceVersions +import java.time.LocalDateTime plugins { id("ru.mipt.npm.gradle.project") @@ -11,7 +12,7 @@ repositories { } group = "ru.mipt.npm" -version = "0.0.1-SNAPSHOT" +version = "0.1.0-SNAPSHOT" application { mainClass.set("io.ktor.server.netty.EngineMain") @@ -54,4 +55,12 @@ sourceSets { main { resources.srcDir(project.rootDir.resolve("data")) } +} + +//write build time in build to check outdated external data directory +tasks.getByName("processResources") { + doFirst { + val deployDate = LocalDateTime.now() + project.buildDir.resolve("resources/main/buildDate").writeText(deployDate.toString()) + } } \ No newline at end of file diff --git a/data/magprog/content/intro.md b/data/magprog/content/intro.md index ac775e8..d2df0dd 100644 --- a/data/magprog/content/intro.md +++ b/data/magprog/content/intro.md @@ -5,7 +5,7 @@ section_title: О программе language: ru --- -Магистерская программа МФТИ **"Научное программное обеспечение"** (старое название: **"Разработка и применение программного обеспечения в физических исследованиях"**) создана при поддержке двух школ МФТИ: Физтех-школы физики и исследований им. Ландау ([ЛФИ](https://mipt.ru/education/departments/lpr/)) и Физтех-школы прикладной математики и информатики ([ФПМИ](https://mipt.ru/education/departments/fpmi/)) и ряда академических и промышленных партнеров. В ее основе лежит взаимодействие студента и [научного руководителя](#mentors). +Магистерская программа МФТИ **"Научное программное обеспечение"** (старое название: **"Разработка и применение программного обеспечения в физических исследованиях"**) создана при поддержке двух школ МФТИ: Физтех-школы физики и исследований им. Ландау ([ЛФИ](https://mipt.ru/education/departments/lpr/)), Физтех-школы прикладной математики и информатики ([ФПМИ](https://mipt.ru/education/departments/fpmi/)) а также ряда академических и промышленных партнеров. В ее основе лежит взаимодействие студента и [научного руководителя](#mentors). Цель создания программы — объединение усилий ученых и программистов для разработки лучших компьютерных решений и применения этих решений в области фундаментальной и прикладной науки и инженерии. @@ -15,16 +15,22 @@ language: ru * нахождение оптимальной траектории для задач в георазведке; * разработка инструментов анализа данных для нефтяных компаний и количество прикладных учебных задач от реальных заказчиков постоянно растет. +
+ **Почему же** это направление так актуально? Существенная часть работы ученых так или иначе связана с компьютером. Компьютеры и программы используются на всех этапах экспериментального или теоретического исследования. Любой работе предшествует **компьютерное моделирование**, затем требуется **автоматизация сбора и хранения данных**, **анализ данных** и, наконец, **представление результатов**. На всех этих этапах нужны компьютеры и программное обеспечение. Качество программного обеспечения — ключевой фактор в исследованиях и разработках. Современная разработка программного обеспечения — это отдельная инженерная дисциплина, требующая опыта и погружения в технологию и соответствующие профессиональные сообщества. Несмотря на то, что современное программирование зародилось в научных исследованиях, с тех пор прошло много времени, и ученые во многих областях в среднем уже не могут похвастаться хорошими знаниями в этой области. Качество программного обеспечения в естественных науках низкое. Те же проблемы свойственны инженерной индустрии. +
+ **Зачем** для этого нужны ученые? Прошлые попытки поручить разработку программного обеспечения профессиональным программистам не увенчались успехом. Чтобы сформулировать задачу программисту, надо знать современные компьютерные технологии и понимать, как их лучше применять. +
+ **Зачем** все это программистам? Задачи, возникающие на стыке физики и программирования, на порядок интереснее тех, что ожидают инженера-программиста в повседневной рабочей жизни. Также работа с учеными — это хороший повод опробовать все самые свежие и экспериментальные технологии. Кроме того, опыт в моделировании, обработке данных и работе с приборами является бесценным в IT-среде. diff --git a/data/magprog/content/mentors/Oliinychenko.md b/data/magprog/content/mentors/Oliinychenko.md index 30b7d16..e66ecf8 100644 --- a/data/magprog/content/mentors/Oliinychenko.md +++ b/data/magprog/content/mentors/Oliinychenko.md @@ -1,6 +1,6 @@ --- content_type: magprog_mentor -name: Олийниченко Дмитрий Робертович +name: Дмитрий Робертович Олийниченко id: Oliinychenko photo: images/mentors/Oliinychenko.jpg language: ru diff --git a/data/magprog/content/mentors/Pantuev.md b/data/magprog/content/mentors/Pantuev.md index 5c18eaa..9ae7a0b 100644 --- a/data/magprog/content/mentors/Pantuev.md +++ b/data/magprog/content/mentors/Pantuev.md @@ -1,6 +1,6 @@ --- content_type: magprog_mentor -name: Пантуев Владислав Сергеевич +name: Владислав Сергеевич Пантуев id: Pantuev photo: images/mentors/Pantuev.jpg language: ru diff --git a/data/magprog/content/mentors/Zinoviev.md b/data/magprog/content/mentors/Zinoviev.md index 18ab63b..0ef7ad6 100644 --- a/data/magprog/content/mentors/Zinoviev.md +++ b/data/magprog/content/mentors/Zinoviev.md @@ -1,6 +1,6 @@ --- content_type: magprog_mentor -name: Зиновьев Алексей Викторович +name: Алексей Викторович Зиновьев id: Zinoviev photo: images/mentors/Zinoviev.jpg language: ru diff --git a/data/magprog/content/mentors/nizovtseva.md b/data/magprog/content/mentors/nizovtseva.md index 27eded8..4a1b63c 100644 --- a/data/magprog/content/mentors/nizovtseva.md +++ b/data/magprog/content/mentors/nizovtseva.md @@ -1,6 +1,6 @@ --- content_type: magprog_mentor -name: Низовцева Ирина Геннадьевна +name: Ирина Геннадьевна Низовцева id: Nizovtseva photo: images/mentors/Nizovtseva.jpg language: ru diff --git a/data/magprog/content/mentors/svetlichny.md b/data/magprog/content/mentors/svetlichny.md index 0ecc145..4dd4237 100644 --- a/data/magprog/content/mentors/svetlichny.md +++ b/data/magprog/content/mentors/svetlichny.md @@ -1,6 +1,6 @@ --- content_type: magprog_mentor -name: Светличный Александр +name: Александр Светличный id: Svetlichny photo: images/mentors/Svetlichny.jpg language: ru diff --git a/data/magprog/content/partners.yaml b/data/magprog/content/partners.yaml index dafa512..0ee2e12 100644 --- a/data/magprog/content/partners.yaml +++ b/data/magprog/content/partners.yaml @@ -1,25 +1,28 @@ title: Партнеры content: - title: ЛФИ МФТИ - link: https://mipt.ru/education/departments/lpr/ + link: "https://mipt.ru/education/departments/lpr/" logo: /images/partners/LPI.jpg - title: ФПМИ МФТИ - link: https://mipt.ru/education/departments/fpmi/ + link: "https://mipt.ru/education/departments/fpmi/" logo: /images/partners/FPMI.jpg + - title: MIPT-NPM + link: "https://npm.mipt.ru/" + logo: /images/partners/npm-logo-no-text-white.png - title: JetBrains Research (до 2022) - link: https://research.jetbrains.org/groups/npm/ + link: "https://research.jetbrains.org/groups/npm/" logo: /images/partners/JBR.png - title: Таврида Электрик - link: https://www.tavrida.com/ter/ + link: "https://www.tavrida.com/ter/" logo: /images/partners/Tavrida.png - title: ИЯИ РАН - link: https://www.inr.ru/ + link: "https://www.inr.ru/" logo: /images/partners/inr_logo.png - title: ИКИ РАН - link: http://www.iki.rssi.ru/ + link: "http://www.iki.rssi.ru/" logo: /images/partners/iki.jpg - title: ОИЯИ - link: https://bmn.jinr.ru/ + link: "https://bmn.jinr.ru/" logo: /images/partners/jinr.png # - title: ВШЭ # link: https://www.hse.ru/en/ @@ -28,8 +31,8 @@ content: # link: https://www.desy.de/research/cooperations__institutes/hzg/index_eng.html # logo: /images/partners/desy.svg - title: Тинькофф - link: https://fintech.tinkoff.ru/ + link: "https://fintech.tinkoff.ru/" logo: /images/partners/tink.jpg - title: ФИЦ Биотехнологии РАН - link: https://www.fbras.ru/ + link: "https://www.fbras.ru/" logo: /images/partners/biotech.png diff --git a/data/magprog/content/team/Aivazov.md b/data/magprog/content/team/Aivazov.md index c349aa9..fba4a54 100644 --- a/data/magprog/content/team/Aivazov.md +++ b/data/magprog/content/team/Aivazov.md @@ -6,4 +6,4 @@ order: 4 photo: images/team/Aivazov.jpg language: ru --- -**Консультант от ФПМИ** +Консультант от ФПМИ diff --git a/data/magprog/content/team/Muhina.md b/data/magprog/content/team/Muhina.md index e5a83e4..850458d 100644 --- a/data/magprog/content/team/Muhina.md +++ b/data/magprog/content/team/Muhina.md @@ -7,4 +7,4 @@ photo: images/team/muhina.jpg language: ru --- -Менеджер образовательных проектов. \ No newline at end of file +Менеджер образовательных проектов \ No newline at end of file diff --git a/data/magprog/content/team/Nozik.md b/data/magprog/content/team/Nozik.md index 418cd03..1fbe7ce 100644 --- a/data/magprog/content/team/Nozik.md +++ b/data/magprog/content/team/Nozik.md @@ -8,8 +8,4 @@ language: ru --- **Руководитель программы** -Заместитель заведующего ЛМЯФЭ МФТИ. - -Руководитель направления в JetBrains Research. - -Преподаватель общей физики, статистических методов и программирования на Kotlin в МФТИ. \ No newline at end of file +Директор центра научного программирования \ No newline at end of file diff --git a/data/magprog/content/team/Svetlichnii.md b/data/magprog/content/team/Svetlichnii.md index 40f7b32..96bc56b 100644 --- a/data/magprog/content/team/Svetlichnii.md +++ b/data/magprog/content/team/Svetlichnii.md @@ -9,6 +9,3 @@ language: ru **Заместитель руководителя** -Преподаватель кафедры общей физики МФТИ. - -Аспирант ИЯИ РАН. diff --git a/data/magprog/images/partners/npm-logo-no-text-white.png b/data/magprog/images/partners/npm-logo-no-text-white.png new file mode 100644 index 0000000..6e41233 Binary files /dev/null and b/data/magprog/images/partners/npm-logo-no-text-white.png differ diff --git a/src/main/kotlin/ru/mipt/spc/Application.kt b/src/main/kotlin/ru/mipt/spc/Application.kt index 4ce98b5..83d6ab3 100644 --- a/src/main/kotlin/ru/mipt/spc/Application.kt +++ b/src/main/kotlin/ru/mipt/spc/Application.kt @@ -11,10 +11,8 @@ import java.net.URI import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path -import kotlin.io.path.createDirectories -import kotlin.io.path.div -import kotlin.io.path.isRegularFile -import kotlin.io.path.relativeTo +import java.time.LocalDateTime +import kotlin.io.path.* fun CommonAttributeGroupFacade.css(block: CssBuilder.() -> Unit) { style = CssBuilder().block().toString() @@ -42,6 +40,9 @@ private fun Application.resolveData(uri: URI, targetPath: Path): Path { return targetPath } +const val DEPLOY_DATE_FILE = "deployDate" +const val BUILD_DATE_FILE = "buildDate" + @Suppress("unused") fun Application.spcModule() { val context = Context("spc-site") { @@ -50,6 +51,20 @@ fun Application.spcModule() { val dataPath = Path.of("data") + // Clear data directory if it is outdated + val deployDate = dataPath.resolve(DEPLOY_DATE_FILE).takeIf { it.exists() } + ?.readText()?.let { LocalDateTime.parse(it) } + val buildDate = javaClass.getResource(BUILD_DATE_FILE)?.readText()?.let { LocalDateTime.parse(it) } + + if (deployDate != null && buildDate != null && buildDate.isAfter(deployDate)) { + log.info("Outdated data. Resetting data directory.") + dataPath.deleteIfExists() + + //Writing deploy date file + dataPath.createDirectories() + dataPath.resolve(DEPLOY_DATE_FILE).writeText(LocalDateTime.now().toString()) + } + val homeDataPath = resolveData( javaClass.getResource("/home")!!.toURI(), dataPath / "home" diff --git a/src/main/kotlin/ru/mipt/spc/master.kt b/src/main/kotlin/ru/mipt/spc/master.kt index bad772a..abcae5f 100644 --- a/src/main/kotlin/ru/mipt/spc/master.kt +++ b/src/main/kotlin/ru/mipt/spc/master.kt @@ -128,34 +128,55 @@ context(PageContext) private fun FlowContent.team() { val team = findByType("magprog_team").map { Person(it.value) }.sortedBy { it.order } div("inner") { - h2 { - +"Команда" - } - } - team.forEach { member -> - section { - id = member.id - a(classes = "image", href = resolveRef("mentor-${member.id}")) { - member.photo?.let { photoPath -> - img( - src = resolveRef(photoPath), - alt = member.name - ) { - attributes["data-position"] = "center center" + h2 { +"Команда" } + div("features") { + team.forEach { member -> + section { + a { + val imagePath = member.photo?.let { resolveRef(it) } + img( + classes = "icon major", + src = imagePath, + alt = imagePath + ) { + h3 { +member.name } + htmlData(member.data) + } } } } + } + } - div("content") { - div("inner") { - h3 { - a(href = "#team_${member.id}") { +member.name } - } - htmlData(member) - } - } - } - } +// div("inner") { +// h2 { +// +"Команда" +// } +// } +// team.forEach { member -> +// section { +// id = member.id +// a(classes = "image") { +// member.photo?.let { photoPath -> +// img( +// src = resolveRef(photoPath), +// alt = member.name +// ) { +// attributes["data-position"] = "center center" +// } +// } +// } +// +// div("content") { +// div("inner") { +// h3 { +// a(href = "#team_${member.id}") { +member.name } +// } +// htmlData(member) +// } +// } +// } +// } } context(PageContext) private fun FlowContent.mentors() { @@ -195,6 +216,10 @@ context(PageContext) private fun FlowContent.mentors() { } } +context(PageContext) internal fun FlowContent.contacts() { + +} + context(PageContext) internal fun HTML.magProgHead(title: String) { head { @@ -273,7 +298,7 @@ internal fun Application.spcMaster(context: Context, dataPath: Path, prefix: Str routing { route(prefix) { with(magProgPageContext) { - static{ + static { files(dataPath.resolve("assets").toFile()) static("images") { @@ -309,14 +334,10 @@ internal fun Application.spcMaster(context: Context, dataPath: Path, prefix: Str programSection() }, wrapSection(resolveHtml(ENROLL_PATH)!!, "enroll"), - MagProgSection( - id = "team", - title = "Команда", - style = "wrapper style2 spotlights", - ) { + wrapSection(id = "contacts", title = "Контакты") { + htmlData(resolveHtml(CONTACTS_PATH)!!) team() - }, - wrapSection(resolveHtml(CONTACTS_PATH)!!, "contacts"), + } ) magProgHead("Магистратура \"Научное программирование\"") body("is-preload magprog-body") { @@ -367,13 +388,13 @@ internal fun Application.spcMaster(context: Context, dataPath: Path, prefix: Str href = "$homeRef#mentors" +"Научные руководители" } - nav() { + nav{ ul { mentors.forEach { li { a { href = resolveRef(it.mentorPageId) - +it.name + +it.name.substringAfterLast(" ") } } } diff --git a/src/main/kotlin/space/kscience/snark/SnarkPlugin.kt b/src/main/kotlin/space/kscience/snark/SnarkPlugin.kt index 54f1b92..b06ae73 100644 --- a/src/main/kotlin/space/kscience/snark/SnarkPlugin.kt +++ b/src/main/kotlin/space/kscience/snark/SnarkPlugin.kt @@ -68,24 +68,6 @@ class SnarkPlugin : AbstractPlugin() { context.gather(SnarkParser.TYPE, true) } -// val parseAction: Action = Action.map { -// val parser: SnarkParser<*>? = parsers.values.filter { parser -> -// parser.contentType.toString() == meta["contentType"].string || -// meta[META_FILE_EXTENSION_KEY].string in parser.fileExtensions -// }.maxByOrNull { -// it.priority -// } -// -// //ensure that final type is correct -// if (parser == null) { -// logger.warn { "The parser is not found for data with meta $meta" } -// result { it } -// } else { -// result(parser.resultType) { bytes -> -// parser.parse(bytes, meta) -// } -// } -// } fun readDirectory(path: Path): DataTree = io.readDataDirectory(path) { dataPath, meta -> val fileExtension = meta[FileData.META_FILE_EXTENSION_KEY].string ?: dataPath.extension