i20n and universalization for config
Some checks failed
/ build-installer (push) Failing after 2s

This commit is contained in:
Gregory Bednov 2026-09-14 14:21:08 +03:00
commit 4aae45f13b
10 changed files with 588 additions and 180 deletions

View file

@ -11,7 +11,8 @@ jobs:
SERVER: ${{ forgejo.server_url }} SERVER: ${{ forgejo.server_url }}
REPO: ${{ forgejo.repository }} REPO: ${{ forgejo.repository }}
run: | run: |
ISO="result/iso/mirea-nixos-installer.iso" ISO_NAME=$(nix eval --raw ./installer#nixosConfigurations.installer.config.isoImage.isoName)
ISO="result/iso/$ISO_NAME"
NEW_SHA=$(sha256sum "$ISO" | awk '{print $1}') NEW_SHA=$(sha256sum "$ISO" | awk '{print $1}')
LATEST_BODY=$(curl -sf \ LATEST_BODY=$(curl -sf \
@ -37,7 +38,7 @@ jobs:
curl -sf -X POST \ curl -sf -X POST \
-H "Authorization: token $TOKEN" \ -H "Authorization: token $TOKEN" \
-H "Content-Type: application/octet-stream" \ -H "Content-Type: application/octet-stream" \
"$SERVER/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=mirea-nixos-installer.iso" \ "$SERVER/api/v1/repos/$REPO/releases/$RELEASE_ID/assets?name=$ISO_NAME" \
--data-binary "@$ISO" --data-binary "@$ISO"
echo "Published release $TAG (sha256: $NEW_SHA)" echo "Published release $TAG (sha256: $NEW_SHA)"

View file

@ -7,7 +7,12 @@
}: }:
let let
serverIP = "10.0.174.12"; serverIP = "10.0.174.12";
serverAddress = "kafpi.local";
buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903"; buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903";
sshKeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyBYo/E/FkFZVABzMixLS2TWaipfN5T24y8f+E6Px1t+IG8PLnQ38dLJiCR8k971DOycLuJUfKWsC06BK3XLWTO0+PmpfGKNT4NI6dwP2REl/umaignP/QQSs2w9Ff49WqPjIYTSmATTsCNZSVB0VtM0eJ+Y9Ff4CXb1frtt4GYztk6XB3jc3TxV72qzB0g6DqrHkf6pT5YAq2UeuFGZYSZCqBvVXCGcvKHkO1KBubuo95itVA5XbzK3INQTZpQowbtK4ULhUYlaGBcX5tYq1bdiTCDlTcLt6MfxYfFHSFiHbJOzdGPd+mXM7urOQhq49uQOf07dHt9qAzQHajItQb+X3FOgyFt4n6Y9Q37gn/6KC3PH1zClldq9DtgttuG/Xk15q+uvCldji9YIgb80aRHBIp6DY8PlYodmGGesBLiBMGQ7hgKupfkqszjfMkxnMYIkZodUCQVgaqsxsEQ7lD84JJMgBY8HkNLxKhy+6dP6kTc4vTtrpjezq/Ph95PFE= bednov@kafpi-108-1-mainserver2"
];
hasBootPartition = config.fileSystems ? "/boot"; hasBootPartition = config.fileSystems ? "/boot";
isNvidia = isNvidia =
(builtins.readFile ( (builtins.readFile (
@ -21,8 +26,23 @@ let
${pkgs.pciutils}/bin/lspci | ${pkgs.busybox}/bin/grep ADATA | ${pkgs.busybox}/bin/grep -i NVMe > $out || true ${pkgs.pciutils}/bin/lspci | ${pkgs.busybox}/bin/grep ADATA | ${pkgs.busybox}/bin/grep -i NVMe > $out || true
'' ''
)) != ""; )) != "";
# any MIREA Uuniversity specifics (apps, wallpapers) are located in ./mirea-specific
# other uuniversities can use their own files there
#
# всё, что специфично именно для МИРЭА (брендирование, герб, номер учебной недели),
# вынесено в mirea-specific/ — другой вуз может подставить свои значения/файлы.
university = import ./mirea-specific/university.nix;
mireaweek = pkgs.callPackage ./mirea-specific/mireaweek.nix { };
desktop = inputs.mireadesktop.lib.mkDesktop {
wallpaper = university.wallpaper;
extraTint2Widgets = import ./mirea-specific/tint2-widget.nix { inherit mireaweek; };
};
in in
{ {
# local versions for stm32cubemx and staruml installers
# локальные версии stm32cubemx и staruml
nixpkgs.overlays = [ nixpkgs.overlays = [
(final: prev: { (final: prev: {
staruml = prev.staruml.overrideAttrs (old: { staruml = prev.staruml.overrideAttrs (old: {
@ -32,19 +52,32 @@ in
}; };
}); });
stm32cubemx = prev.stm32cubemx.override { stm32cubemx = prev.stm32cubemx.override {
fetchzip = args: prev.fetchzip (args // { fetchzip =
args:
prev.fetchzip (
args
// {
url = "http://${serverIP}/stm32cube_mx_v6111-lin.zip"; url = "http://${serverIP}/stm32cube_mx_v6111-lin.zip";
hash = "sha256-By9T43GLM1J63TkRi3kl05h1RflBorU1QHgYOrXQ9N0="; hash = "sha256-By9T43GLM1J63TkRi3kl05h1RflBorU1QHgYOrXQ9N0=";
}); }
buildFHSEnv = args: prev.buildFHSEnv ( args // { );
buildFHSEnv =
args:
prev.buildFHSEnv (
args
// {
unshareNet = true; unshareNet = true;
}); }
);
}; };
}) })
]; ];
users.users.student = { users.users.student = {
isNormalUser = true; isNormalUser = true;
initialPassword = "student"; # вход беспарольный, но пароль student
# login is passwordless, however password is 'student' too
# вход беспарольный, но пароль student
initialPassword = "student";
extraGroups = [ extraGroups = [
"video" "video"
"sound" "sound"
@ -54,7 +87,8 @@ in
]; ];
packages = packages =
let let
# определение как скачивать плагины jetbrains (скачивать с нашего сервера копию) # local copies of plugins
# скачивать с нашего сервера копии плагинов jetbrains
customJBPlugin = customJBPlugin =
nam: ver: sha: nam: ver: sha:
pkgs.stdenv.mkDerivation { pkgs.stdenv.mkDerivation {
@ -73,8 +107,8 @@ in
[ [
(pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-community ( (pkgs.jetbrains.plugins.addPlugins pkgs.jetbrains.idea-community (
# набор плагинов, я бы сказал, богат до избыточности, но главное есть Python # wide plugin set. PythonCore and Database Navigator is a key difference to stock IDEA CE
# и Database Nagivator. Остальное - любителям и любознательным. # богатый набор плагинов, главное есть Python и Database Nagivator. Остальное - любителям и любознательным.
(with inputs.nix-jetbrains-plugins.plugins."${system}"; [ (with inputs.nix-jetbrains-plugins.plugins."${system}"; [
idea-community."2024.1"."mobi.hsz.idea.gitignore" idea-community."2024.1"."mobi.hsz.idea.gitignore"
#idea-community."2024.1"."org.jetbrains.erlang" #idea-community."2024.1"."org.jetbrains.erlang"
@ -96,53 +130,86 @@ in
idea-community."2024.1"."com.redhat.devtools.lsp4ij" idea-community."2024.1"."com.redhat.devtools.lsp4ij"
]) ])
++ [ ++ [
# поддежка фреймворка Spring через opensource-плагин Explyt. пусть будет # russian opensource Explyt Spring plugin out of Jetbrains Marketplace
# поддежка фреймворка Spring через opensource-плагин Explyt
(customJBPlugin "spring-tool" "241-b3085-signed" (customJBPlugin "spring-tool" "241-b3085-signed"
"sha256-u9Hqy4BN1johA7e8proMekyERXkE6gXRnqGRNR7FouE=" "sha256-u9Hqy4BN1johA7e8proMekyERXkE6gXRnqGRNR7FouE="
) )
] ]
)) ))
chromium # браузер # browser
pinta # графический редактор # браузер
sakura # терминал chromium
unzipNLS # поддержка zip
unrar # поддержка rar
mate.engrampa
gtk3
whitesur-icon-theme # необходимо для иконок
(pkgs.writeShellScriptBin "powermenu" (
builtins.readFile inputs.mireadesktop.packages.x86_64-linux.powermenu
))
(pkgs.writeShellScriptBin "resethome" (
builtins.readFile inputs.mireadesktop.packages.x86_64-linux.resethome
))
inputs.kompas3d.packages.${pkgs.system}.default # KOMPAS-3D # graphics editor
freecad elmerfem gmsh # FEM calculation # графический редактор
pinta
# terminal emulator
# терминал
sakura
# GUI archive/unarchive tool with zip and rar support
# Архиватор с поддержкой zip и rar
mate.engrampa
unzipNLS
unrar
gtk3
# icon theme
# тема иконок
whitesur-icon-theme
# powermenu GUI util for poweroff or reboot
# графическое меню выключения или перезагрузки компьютера
(pkgs.writeShellScriptBin "powermenu" (builtins.readFile desktop.powermenu))
# resethome reset student home, deleting most of files, user caches and configs, leaving only default options
# useful for resetting vandal settings
#
# resethome позволяет удалить содержимое домашней директории пользователя student,
# сбрасывая нефунциональные настройки, установленные студентами в том числе из хулиганских побуждений
(pkgs.writeShellScriptBin "resethome" (builtins.readFile desktop.resethome))
inputs.kompas3d.packages.${pkgs.system}.default # KOMPAS-3D CAD
freecad
elmerfem
gmsh # FEM calculation
inputs.nix-wine-experiments.packages.x86_64-linux.nbdesigner inputs.nix-wine-experiments.packages.x86_64-linux.nbdesigner
pandoc pandoc
onlyoffice-desktopeditors onlyoffice-desktopeditors
# -----
# Seafile client for department cloud drive
# Напоминаю что у нас есть СЕТЕВОЙ ДИСК по адресу 10.0.174.12 # Напоминаю что у нас есть СЕТЕВОЙ ДИСК по адресу 10.0.174.12
# и для студентов пока есть единая учётка student@mirea.ru, # и для студентов пока есть единая учётка (домен и SSO — см. mirea-specific/university.nix),
# рассматривается вариант авторизации через sso.mirea.ru. # рассматривается вариант авторизации через SSO вуза.
# Преподаватели могут зарегистрироваться ОТДЕЛЬНО # Преподаватели могут зарегистрироваться ОТДЕЛЬНО
seafile-client seafile-client
# ------
# developer utils
# утилиты разработчика # утилиты разработчика
git git
cmakeWithGui cmakeWithGui
gnumake gnumake
###### PROGRAMMING LANGUAGES #####
###### ЯЗЫКИ ПРОГРАММИРОВАНИЯ ##### ###### ЯЗЫКИ ПРОГРАММИРОВАНИЯ #####
# Python enviroment, for full abilites list see
# https://forgejo.gregorbednov.ru/gregorbednov/mireapython
# поставка Python, полный список возможностей # поставка Python, полный список возможностей
# см. на github.com/gregorybednov/mireapython # см. на https://forgejo.gregorbednov.ru/gregorbednov/mireapython
inputs.mireapython.packages.x86_64-linux.mireapython inputs.mireapython.packages.x86_64-linux.mireapython
# basic C/C++ support and debug
# базовая поддержка C/C++ и дебага # базовая поддержка C/C++ и дебага
clang clang
clang-tools clang-tools
@ -150,55 +217,82 @@ in
valgrind valgrind
cpplint cpplint
cppcheck cppcheck
gcc-arm-embedded # компиляция С/C++ под STM32 и прочие arm
# C/C++ toolchain for STM32 and other ARM chips
# компиляция С/C++ под STM32 и прочие arm
gcc-arm-embedded
octaveFull # GNU Octave octaveFull # GNU Octave
shellcheck # проверка шелл-кода (bash, POSIX sh, ...) # static shell code analyzer (bash, POSIX sh, ...)
# проверка шелл-кода (bash, POSIX sh, ...)
shellcheck
# Other possible languages and tools, e.g.:
# Другие возможные языки и инструменты, например: # Другие возможные языки и инструменты, например:
# rustc # - Rust # rustc # - Rust
# go gopls delve golint go-tools # - Go # go gopls delve golint go-tools # - Go
jdk jdk
kotlin # - Java, Kotlin (идут вместе с IJ IDEA) kotlin # - Java, Kotlin (needed for IJ IDEA)
# ghc haskell-language-server # - Haskell # ghc haskell-language-server # - Haskell
# nodePackages.intelephense # - PHP # nodePackages.intelephense # - PHP
# dotnet-sdk # - C# # dotnet-sdk # - C#
####### DB modeling and development ##########
####### Проектирование и разработка баз данных, ИУС, ... ####### ####### Проектирование и разработка баз данных, ИУС, ... #######
# EACH nixos has its own local mysql and postgres servers
# with root access by students, see below for details
#
# у КАЖДОГО nixos есть свой локальный сервер mysql и postgres,
# у студентов есть root-доступ, см. ниже по файлу
# Workbench for ER modeling and wrigin MySQL code
# Workbench для управления и ER-моделирования БД на mysql # Workbench для управления и ER-моделирования БД на mysql
# у КАЖДОГО nixos есть свой локальный сервер mysql, см. ниже по файлу
mysql-workbench mysql-workbench
# BPMN Modeler, just like Bizagi Modeler we used before, but cross-platform
# btw has web-version on https://bpmn.io
#
# аналог Bizagi Modeler, расширенный вариант bpmn.io # аналог Bizagi Modeler, расширенный вариант bpmn.io
camunda-modeler camunda-modeler
# GUI UML, BPMN, ER, etc. modeling
#
# графическое моделирование UML-диаграмм # графическое моделирование UML-диаграмм
# также доступно моделирование BPMN и ER # также доступно моделирование BPMN и ER
(staruml.overrideAttrs (oldAttrs: { (staruml.overrideAttrs (oldAttrs: {
nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ]; nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
postFixup = # бесконечный триал
(oldAttrs.postFixup or "") postFixup = (oldAttrs.postFixup or "") + ''
+ ''
# Rename the original binary
mv $out/bin/staruml $out/bin/.staruml-org mv $out/bin/staruml $out/bin/.staruml-org
# Create the wrapper script
makeWrapper ${pkgs.bash}/bin/bash $out/bin/staruml \ makeWrapper ${pkgs.bash}/bin/bash $out/bin/staruml \
--add-flags "-c 'rm -rf \$HOME/.config/StarUML && exec $out/bin/.staruml-org \"\$@\"'" --add-flags "-c 'rm -rf \$HOME/.config/StarUML && exec $out/bin/.staruml-org \"\$@\"'"
''; '';
})) }))
# declarative text to UML diagrams visualizer
# very useful for software developers (bc inserting diagrams into code)
# has VSCode and IJ IDEA CE support
#
# Язык текстового описания UML-диаграмм # Язык текстового описания UML-диаграмм
# актуально для разработчиков ПО (встраивание диаграмм в код) # актуально для разработчиков ПО (встраивание диаграмм в код)
# поддерживается нашей поставкой IJ IDEA CE # поддерживается нашей поставкой IJ IDEA CE
plantuml plantuml
# graph visualizer
# it is necessary for plantuml
#
# визуализатор графов общего назначения
# обязателен для plantuml
graphviz graphviz
archi # поддержка archimate # archimate diagrams support
# поддержка archimate
archi
##### Utils and apps for STM32 #####
##### Утилиты и программы для STM32 ##### ##### Утилиты и программы для STM32 #####
stm32cubemx stm32cubemx
stlink stlink
@ -206,19 +300,41 @@ in
stm32loader stm32loader
openocd openocd
##### NETWORK APPS AND UTILS ######
##### СЕТЕВЫЕ УТИЛИТЫ ###### ##### СЕТЕВЫЕ УТИЛИТЫ ######
# установлен Cisco Packet Tracer, обернут в firejail чтобы не стучался на Netacad.com
nodePackages.node-red # - лоукод-платформа программирования устройств, в частности интернета вещей
httpie
httpie-desktop # - передовой клиент HTTP-запросов
netcat
socat # - низкоуровневые простейшие утилиты установления TCP или UDP между компьютерами или с ПЛК
opcua-client-gui # - простой графический клиент OPC UA
# Cisco Packet Tracer 7 was installed but it was firejailed to work without Netacad.com accounts
# установлен Cisco Packet Tracer 7, обернут в firejail чтобы не стучался на Netacad.com
# lowcode for IoT programming used in IIoT and IoT practices in uuniversity
# лоукод-платформа программирования устройств, в частности интернета вещей
nodePackages.node-red
# probably best http request client
# передовой клиент HTTP-запросов
httpie
httpie-desktop
# simple network and socket level utils for practicing simple TCP and UDP between PCs, IoT devices and PLCs
# низкоуровневые простейшие утилиты установления TCP или UDP между компьютерами или с ПЛК
netcat
socat
# simple OPC UA GUI client
# простой графический клиент OPC UA
opcua-client-gui
###### OTHER SOFTWARE ####
###### Другой софт ####### ###### Другой софт #######
logisim-evolution logisim-evolution
unityhub # UnityHub - 3D-моделирование, визуализация, геймдев, AR/VR
# UnityHub - 3D modeling, visualisation, gamedev, AR/VR
# UnityHub - 3D моделирование, визуализация, геймдев, AR/VR
unityhub
# DWSim for chemical techology simulation and modeling
# DWSIM - симулятор химических технологических процессов
(pkgs.stdenv.mkDerivation rec { (pkgs.stdenv.mkDerivation rec {
pname = "dwsim"; pname = "dwsim";
version = "9.0.5"; version = "9.0.5";
@ -332,6 +448,8 @@ in
''; '';
}) })
# shareware CNC VMC 3D-graphical simulator
(pkgs.stdenv.mkDerivation rec { (pkgs.stdenv.mkDerivation rec {
pname = "cnc_vmc_sim"; pname = "cnc_vmc_sim";
version = "1.0.0-share"; version = "1.0.0-share";
@ -372,6 +490,9 @@ in
startupNotify = false; startupNotify = false;
}; };
}) })
# ramus educational for IDEF0 and DFD modeling
# ramus educational для моделирования в нотациях IDEF0, DFD
(pkgs.stdenv.mkDerivation rec { (pkgs.stdenv.mkDerivation rec {
pname = "ramus"; pname = "ramus";
version = "0.1.3"; version = "0.1.3";
@ -388,6 +509,10 @@ in
''; '';
}) })
# SimInTech (russian matlab simulink alternative)
# C code generation works, but dynamic libraries are NOT
# compatible with Windows DLL!
#
# поставка SimInTech. Кодогенерация библиотек для ПК работает, # поставка SimInTech. Кодогенерация библиотек для ПК работает,
# но несовместима с .dll из windows! # но несовместима с .dll из windows!
(pkgs.stdenv.mkDerivation rec { (pkgs.stdenv.mkDerivation rec {
@ -441,6 +566,8 @@ in
''; '';
}) })
# ErLu is a modern Qt-based opensource alternative to Ramus and Erwin Process Modeler
# ErLu - современная альтернатива с октрытым исходным кодом для Ramus и Erwin Process Modeler
(stdenv.mkDerivation { (stdenv.mkDerivation {
pname = "erlu-idef0-editor"; pname = "erlu-idef0-editor";
version = "1.0.1"; version = "1.0.1";
@ -495,7 +622,11 @@ in
runHook postInstall runHook postInstall
''; '';
qtWrapperArgs = [ "--set" "QT_LOGGING_RULES" "qt.qpa.wayland.textinput=false" ]; qtWrapperArgs = [
"--set"
"QT_LOGGING_RULES"
"qt.qpa.wayland.textinput=false"
];
meta = with lib; { meta = with lib; {
description = "IDEF0 diagram editor built with Qt 6 Widgets"; description = "IDEF0 diagram editor built with Qt 6 Widgets";
license = licenses.lgpl3Plus; license = licenses.lgpl3Plus;
@ -504,15 +635,19 @@ in
}; };
}) })
# student & teacher's userspace alias gcc = clang, g++ = clang++
# i know it looks crazy but sometimes we have to match someone's wrong expectations.
# Of course you can delete this shit if you want to
(pkgs.writeShellScriptBin "gcc" ''${pkgs.clang}/bin/clang "$@"'') (pkgs.writeShellScriptBin "gcc" ''${pkgs.clang}/bin/clang "$@"'')
(pkgs.writeShellScriptBin "g++" ''${pkgs.clang}/bin/clang++ "$@"'') (pkgs.writeShellScriptBin "g++" ''${pkgs.clang}/bin/clang++ "$@"'')
# VS Code
(vscode-with-extensions.override { (vscode-with-extensions.override {
vscodeExtensions = vscodeExtensions =
with vscode-extensions; with vscode-extensions;
[ [
ms-vscode.cpptools-extension-pack ms-vscode.cpptools-extension-pack
ms-dotnettools.csharp #ms-dotnettools.csharp
formulahendry.code-runner formulahendry.code-runner
tomoki1207.pdf tomoki1207.pdf
ms-vscode.hexeditor ms-vscode.hexeditor
@ -529,6 +664,7 @@ in
ms-vscode-remote.remote-ssh ms-vscode-remote.remote-ssh
timonwong.shellcheck timonwong.shellcheck
] ]
# QT, STM32, ARM, debug
++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
{ {
name = "vscode-cppcheck"; name = "vscode-cppcheck";
@ -560,12 +696,6 @@ in
version = "3.2.13"; version = "3.2.13";
sha256 = "sha256-Dzj++F0xTDOaL9VA3X/bVtAhkxd8kPPl3Oz8LWrXpAA="; sha256 = "sha256-Dzj++F0xTDOaL9VA3X/bVtAhkxd8kPPl3Oz8LWrXpAA=";
} }
{
name = "qt-cpp-pack";
publisher = "TheQtCompany";
version = "1.0.2";
sha256 = "sha256-Kd2/kk3qJUOahz71Uh3mUI1wDuwS8/t84tgdWorRPG4";
}
{ {
name = "debug-tracker-vscode"; name = "debug-tracker-vscode";
publisher = "mcu-debug"; publisher = "mcu-debug";
@ -590,19 +720,31 @@ in
version = "1.6.0"; version = "1.6.0";
sha256 = "sha256-nKK8HRzeqDixpdKmgacjhNzanJaTsAnYLC6nCbmWXuU="; sha256 = "sha256-nKK8HRzeqDixpdKmgacjhNzanJaTsAnYLC6nCbmWXuU=";
} }
{
name = "qt-cpp-pack";
publisher = "TheQtCompany";
version = "1.0.2";
sha256 = "sha256-Kd2/kk3qJUOahz71Uh3mUI1wDuwS8/t84tgdWorRPG4";
}
]; ];
}) })
# QT
qtcreator qtcreator
qt6.full qt6.full
qt6.qtbase qt6.qtbase
# debugging
gdb gdb
isort black # Python-related things
# доп.утилиты для Python
isort
black
# POSIX утилиты для совместимости с предметами про POSIX
# POSIX утилиты для совместимости # POSIX utils to align POSIX-related university courses and subjects
om4 om4
pax pax
mailutils mailutils
@ -618,15 +760,18 @@ in
]; ];
}; };
# inserted USB sticks mounts automatically
# вставленные флешки автоматически монтируются # вставленные флешки автоматически монтируются
services.devmon.enable = true; services.devmon.enable = true;
# POSIX at
# необходимо для совместимости с POSIX по команде at, при отсутствии необходимости можно удалить # необходимо для совместимости с POSIX по команде at, при отсутствии необходимости можно удалить
services.atd = { services.atd = {
enable = true; enable = true;
allowEveryone = true; allowEveryone = true;
}; };
# each PC has its own mysql and postgresql
# на каждой машине свой сервер mysql и postgresql # на каждой машине свой сервер mysql и postgresql
services.mysql = { services.mysql = {
enable = true; enable = true;
@ -640,6 +785,7 @@ in
''; '';
}; };
# each mysql and psql support root without password for student
# и оба поддерживают вход без пароля в "руты" # и оба поддерживают вход без пароля в "руты"
system.userActivationScripts.mycnf = { system.userActivationScripts.mycnf = {
text = '' text = ''
@ -648,26 +794,29 @@ in
''; '';
deps = [ ]; deps = [ ];
}; };
environment = { environment.variables = {
etc."gtk-3.0/settings.ini" = { PGUSER = "postgres";
};
# whitesur icons
environment.etc."gtk-3.0/settings.ini" = {
text = '' text = ''
[Settings] [Settings]
gtk-icon-theme-name = WhiteSur gtk-icon-theme-name = WhiteSur
''; '';
mode = "0644"; mode = "0644";
}; };
variables = {
PGUSER = "postgres";
};
};
# STM32CubeMX STM32F107VCT6 automatic on-login firmware setup
systemd.user.services.stm32cubemx-repo = systemd.user.services.stm32cubemx-repo =
let let
stm32f1-v180 = builtins.fetchTarball { url = "http://${serverIP}/STM32Cube.tar.gz"; sha256 = "sha256:1zlcp82xq16anx02ghiv9xa5bi2fsz78h945miqmi26bwcjxdagn"; }; stm32f1-v180 = builtins.fetchTarball {
url = "http://${serverIP}/STM32Cube.tar.gz";
sha256 = "sha256:1zlcp82xq16anx02ghiv9xa5bi2fsz78h945miqmi26bwcjxdagn";
};
in { in
{
description = "STM32CubeMX firmware repository setup"; description = "STM32CubeMX firmware repository setup";
wantedBy = [ "default.target" ]; wantedBy = [ "default.target" ];
serviceConfig = { serviceConfig = {
@ -679,6 +828,8 @@ in
''; '';
}; };
}; };
# russian licensing service for Kompas-3D CAD
services.grdcontrol.enable = true; services.grdcontrol.enable = true;
imports = [ imports = [
@ -706,8 +857,14 @@ in
}; };
}; };
# if it also has Windows partition, then it should allow
# choose OS for 30 sec
#
# otherwise, it should boot in 5 sec
# ----------
# если машина установлена на диск с Windows, # если машина установлена на диск с Windows,
# то она позволяет "увидеть" и выбрать Windows в течение 30 с # то она позволяет "увидеть" и выбрать Windows в течение 30 с
#
# иначе - 5 c таймаута (для виртуалок) # иначе - 5 c таймаута (для виртуалок)
boot.loader = boot.loader =
if hasBootPartition then if hasBootPartition then
@ -741,12 +898,13 @@ in
}; };
time.hardwareClockInLocalTime = hasBootPartition; time.hardwareClockInLocalTime = hasBootPartition;
# настройки Nix # Nix settings
nixpkgs.config = { nixpkgs.config = {
allowUnfree = true; allowUnfree = true;
nvidia.acceptLicense = true; nvidia.acceptLicense = true;
}; };
nix.settings = { nix.settings = {
# Local cache is asked before global because most of packages are already built
# Локальный кэш идёт первым — большинство пакетов уже собраны на build-ноде # Локальный кэш идёт первым — большинство пакетов уже собраны на build-ноде
substituters = [ substituters = [
"http://nixos.builds.node" "http://nixos.builds.node"
@ -758,9 +916,15 @@ in
]; ];
trusted-substituters = [ "http://nixos.builds.node" ]; trusted-substituters = [ "http://nixos.builds.node" ];
auto-optimise-store = true; auto-optimise-store = true;
# If build node is unavailiable then go to cache.nixos.org with no hanging
# Если build-нода временно недоступна — переходим к cache.nixos.org, не зависаем # Если build-нода временно недоступна — переходим к cache.nixos.org, не зависаем
connect-timeout = 5; connect-timeout = 5;
experimental-features = [ "nix-command" "flakes" ]; experimental-features = [
"nix-command"
"flakes"
];
# For 50 GiB partition use auto-GC if no space left
# На дисках 50 GiB автоматически запускать GC при нехватке места # На дисках 50 GiB автоматически запускать GC при нехватке места
min-free = 2147483648; # 2 GiB — порог запуска GC min-free = 2147483648; # 2 GiB — порог запуска GC
max-free = 5368709120; # 5 GiB — цель освобождения max-free = 5368709120; # 5 GiB — цель освобождения
@ -768,17 +932,24 @@ in
nix.gc = { nix.gc = {
automatic = true; automatic = true;
dates = "weekly"; dates = "weekly";
randomizedDelaySec = "45min"; # машины не запускают GC одновременно randomizedDelaySec = "45min"; # PCs don't launch GC at the same time
options = "--delete-older-than 14d"; options = "--delete-older-than 14d";
}; };
# Периодический TRIM для SSD (безопасен и на HDD — просто no-op) # periodic TRIM for SSD (safe for HDD)
# Периодический TRIM для SSD (безопасен на HDD)
services.fstrim.enable = true; services.fstrim.enable = true;
# nix-daemon starts after Yggdrasil does, otherwise nixos.builds.node will be unavailiable
# nix-daemon стартует только после Yggdrasil, иначе nixos.builds.node недостижим # nix-daemon стартует только после Yggdrasil, иначе nixos.builds.node недостижим
systemd.services.nix-daemon = { systemd.services.nix-daemon = {
after = [ "yggdrasil.service" ]; after = [ "yggdrasil.service" ];
wants = [ "yggdrasil.service" ]; wants = [ "yggdrasil.service" ];
}; };
# unique hostname based on 6 last MAC address digits
# networking.hostName = "nixos" leaves back as default fallback
#
# Уникальный hostname на основе последних 6 цифр MAC-адреса основного интерфейса. # Уникальный hostname на основе последних 6 цифр MAC-адреса основного интерфейса.
# networking.hostName = "nixos" остаётся fallback-значением в /etc/hostname; # networking.hostName = "nixos" остаётся fallback-значением в /etc/hostname;
# сервис перекрывает его transient-именем при каждой загрузке. # сервис перекрывает его transient-именем при каждой загрузке.
@ -802,11 +973,14 @@ in
fi fi
''; '';
}; };
# Place location service
# Директория для хранения данных о физическом расположении компьютера # Директория для хранения данных о физическом расположении компьютера
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /var/lib/place 0755 student users -" "d /var/lib/place 0755 student users -"
]; ];
##### GRAPHICS & DE & DM SETTINGS ######
##### НАСТРОЙКИ ГРАФИКИ И РАБОЧЕГО СТОЛА ###### ##### НАСТРОЙКИ ГРАФИКИ И РАБОЧЕГО СТОЛА ######
hardware.graphics = { hardware.graphics = {
enable = true; enable = true;
@ -844,12 +1018,23 @@ in
nvidiaSettings = false; nvidiaSettings = false;
}; };
services.udev.packages = [ pkgs.stlink pkgs.openocd ]; services.udev.packages = [
services.udev.extraRules = if isAdata then '' pkgs.stlink
pkgs.openocd
];
services.udev.extraRules =
if isAdata then
''
ACTION=="add|change",KERNEL=="nvme[0-9]", ATTR{queue/scheduler}="none" ACTION=="add|change",KERNEL=="nvme[0-9]", ATTR{queue/scheduler}="none"
'' else ""; ''
boot.kernelParams = lib.optionals isNvidia [ "nvidia-drm.modeset=1" ] else
++ lib.optionals isAdata [ "nvme_core.default_ps_max_latency_us=0" "nvme_core.io_timeout=4294967295" ]; "";
boot.kernelParams =
lib.optionals isNvidia [ "nvidia-drm.modeset=1" ]
++ lib.optionals isAdata [
"nvme_core.default_ps_max_latency_us=0"
"nvme_core.io_timeout=4294967295"
];
boot.blacklistedKernelModules = lib.optionals isNvidia [ "nouveau" ]; boot.blacklistedKernelModules = lib.optionals isNvidia [ "nouveau" ];
boot.extraModprobeConfig = boot.extraModprobeConfig =
if isNvidia then if isNvidia then
@ -866,17 +1051,16 @@ in
services.getty.autologinUser = "student"; services.getty.autologinUser = "student";
services.xserver.displayManager.lightdm.enable = true; services.xserver.displayManager.lightdm.enable = true;
services.xserver.displayManager.startx.enable = true; services.xserver.displayManager.startx.enable = true;
services.displayManager.defaultSession = "MIREA-WindowsLike+Metacity"; services.displayManager.defaultSession = "${university.shortName}-WindowsLike+Metacity";
services.xserver.displayManager.session = [ services.xserver.displayManager.session = [
{ {
manage = "desktop"; manage = "desktop";
name = "MIREA-WindowsLike"; name = "${university.shortName}-WindowsLike";
# подробности настроек рабочего стола см. на github.com/gregorybednov/mireadesktop
start = '' start = ''
${inputs.mireadesktop.packages.x86_64-linux.tint2} & ${desktop.tint2} &
${inputs.mireadesktop.packages.x86_64-linux.pcmanfm} & ${desktop.pcmanfm} &
${inputs.mireadesktop.packages.x86_64-linux.sxhkd} & ${desktop.sxhkd} &
#${inputs.mireadesktop.packages.x86_64-linux.xcape} & #${desktop.xcape} &
waitPID=$! waitPID=$!
''; '';
} }
@ -890,7 +1074,17 @@ in
} }
]; ];
##### NETWORKING SETTINGS #####
##### СЕТЕВЫЕ НАСТРОЙКИ ####### ##### СЕТЕВЫЕ НАСТРОЙКИ #######
# Yggdrasil-маршрутизация позволяет целевым ПК автоматически получать статический IPv6 даже в сетях DHCP,
# что также запускается на установщике для максимальной гибкости.
# Благодаря Yggdrasil может быть доступно удаленнное управление и локальный кэш сборок
# Yggdrasil routing above network allows any target PC to get automatically static IPv6 even on DHCP,
# so installer is recommended to use Yggdrasil too for maximum scalability
# With Yggdrasil routing it's easy to connect remotely, and you can use
# nix build cache nodes with DHCP-addresses (e.g. other PCs)
services.yggdrasil = { services.yggdrasil = {
enable = true; enable = true;
persistentKeys = true; persistentKeys = true;
@ -899,16 +1093,31 @@ in
}; };
}; };
# each computer has internet connection
# каждый компьютер имеет выход в интернет # каждый компьютер имеет выход в интернет
# our buildnode caught a bug on launching with networkmanager,
# so I had to disable it
#
# наша build-нода не работала с networkmanager, отключалась от сети,
# так что пришлось ее отключить
networking.networkmanager.enable = !config.services.harmonia.enable; networking.networkmanager.enable = !config.services.harmonia.enable;
networking.hostName = "nixos"; networking.hostName = "nixos";
networking.firewall.allowedTCPPorts = [ 22 ] ++ lib.optionals config.services.harmonia.enable [ 80 ]; networking.firewall.allowedTCPPorts = [
22
]
++ lib.optionals config.services.harmonia.enable [ 80 ];
# each computer knows where is ${serverAddress} (at ${serverIP}) - useful for self-signed HTTPS
# каждый компьютер знает, что kafpi.local - это адрес нашего сервера # and where is nixos.builds.node (at ${buildNodeYggIP}) - userful for nix caching via harmonia server
networking.hosts."${serverIP}" = [ "kafpi.local" ]; #
# каждый компьютер знает, что ${serverAddress} - это адрес нашего сервера
# полезно для self-signed HTTPS
networking.hosts."${serverIP}" = [ serverAddress ];
networking.hosts."${buildNodeYggIP}" = [ "nixos.builds.node" ]; networking.hosts."${buildNodeYggIP}" = [ "nixos.builds.node" ];
#### LOCALIZATION ####
# (if you're foreign you probably would like to change it)
#### ЛОКАЛИЗАЦИЯ ##### #### ЛОКАЛИЗАЦИЯ #####
time.timeZone = "Europe/Moscow"; time.timeZone = "Europe/Moscow";
@ -918,6 +1127,12 @@ in
useXkbConfig = true; useXkbConfig = true;
}; };
# installed:
# - Microsoft corefonts
# - GOST Type A (for learning CADs and manufacturing documents)
# - basic freetype fonts
# - JetBrains Mono
#
# установлены шрифты Microsoft (corefonts), # установлены шрифты Microsoft (corefonts),
# установлен ГОСТ Тип А (задел на будущее), # установлен ГОСТ Тип А (задел на будущее),
# установлены базовые свободные шрифты, # установлены базовые свободные шрифты,
@ -929,6 +1144,7 @@ in
liberation_ttf liberation_ttf
]; ];
####### OTHER SETTINGS #######
####### ПРОЧИЕ НАСТРОЙКИ ####### ####### ПРОЧИЕ НАСТРОЙКИ #######
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
vim vim
@ -942,7 +1158,11 @@ in
# При запуске от root через SSH автоматически подключается к X-сессии student на :0 # При запуске от root через SSH автоматически подключается к X-сессии student на :0
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "place"; name = "place";
runtimeInputs = [ yad coreutils util-linux ]; runtimeInputs = [
yad
coreutils
util-linux
];
text = '' text = ''
ROOM_ARG="''${1:-}" ROOM_ARG="''${1:-}"
PLACE_FILE="/var/lib/place/location" PLACE_FILE="/var/lib/place/location"
@ -988,12 +1208,14 @@ in
}) })
]; ];
# remote-control inside our local networking
# удаленный доступ в пределах нашей сети # удаленный доступ в пределах нашей сети
services.openssh = { services.openssh = {
enable = true; enable = true;
settings.PermitRootLogin = "yes"; settings.PermitRootLogin = "yes"; # TODO
}; };
users.users.root.openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyBYo/E/FkFZVABzMixLS2TWaipfN5T24y8f+E6Px1t+IG8PLnQ38dLJiCR8k971DOycLuJUfKWsC06BK3XLWTO0+PmpfGKNT4NI6dwP2REl/umaignP/QQSs2w9Ff49WqPjIYTSmATTsCNZSVB0VtM0eJ+Y9Ff4CXb1frtt4GYztk6XB3jc3TxV72qzB0g6DqrHkf6pT5YAq2UeuFGZYSZCqBvVXCGcvKHkO1KBubuo95itVA5XbzK3INQTZpQowbtK4ULhUYlaGBcX5tYq1bdiTCDlTcLt6MfxYfFHSFiHbJOzdGPd+mXM7urOQhq49uQOf07dHt9qAzQHajItQb+X3FOgyFt4n6Y9Q37gn/6KC3PH1zClldq9DtgttuG/Xk15q+uvCldji9YIgb80aRHBIp6DY8PlYodmGGesBLiBMGQ7hgKupfkqszjfMkxnMYIkZodUCQVgaqsxsEQ7lD84JJMgBY8HkNLxKhy+6dP6kTc4vTtrpjezq/Ph95PFE= bednov@kafpi-108-1-mainserver2" ];
users.users.root.openssh.authorizedKeys.keys = sshKeys; # TODO root
services.gnome.gnome-keyring.enable = true; services.gnome.gnome-keyring.enable = true;
programs = { programs = {
@ -1014,9 +1236,13 @@ in
enable = true; enable = true;
enableSSHSupport = true; enableSSHSupport = true;
}; };
udevil.enable = true; # тоже нужно для флешек
# required for flash stick support
# требуется для поддержки флеш-накопителей
udevil.enable = true;
}; };
# DO NOT CHANGE THIS IF YOU'RE UPDATING OLD COMPUTERS
# НЕ МЕНЯТЬ, иначе придётся все компы переустанавливать, а не обновлять # НЕ МЕНЯТЬ, иначе придётся все компы переустанавливать, а не обновлять
system.stateVersion = "24.05"; system.stateVersion = "24.05";
} }

View file

@ -1,5 +1,7 @@
{ {
description = "MIREA NixOS USB Installer"; description =
let university = import ../mirea-specific/university.nix;
in "${university.shortName} NixOS USB Installer";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";

View file

@ -1,11 +1,63 @@
{ pkgs, lib, config, ... }: {
pkgs,
lib,
config,
...
}:
let let
# static server IP address, it must be always online and serve as Yggdrasil peer
# (see config.services.ygggdrasil.settings.peers for details)
# WARN: the peer should NOT connect Yggdrasil worldwide network
# if your PC fleet shouldn't be globally accessible around the world
#
# статический IP адрес сервера, который должен быть всегда онлайн и служить пиром Yggdrasil
# (см. подробности config.services.ygggdrasil.settings.peers)
# ПРЕДУПРЕЖДЕНИЕ: этот пир не должен быть подключен к мировой сети Yggdrasil,
# если конечно вы не хотите чтобы весь компьютерный парк был доступен из любой точки мира
serverIP = "10.0.174.12"; serverIP = "10.0.174.12";
# -------
# Yggdrasil address cache build node. It should use the same NixOS config as others
# It's NOT required to be the same server as ${serverIP} but it also should be always online
# It CAN be a NixOS VM installed on the same server ${serverIP} autostarted
#
# Yggdrasil-адрес кэширующего сервера. На нем должна быть установлена NixOS с той
# же конфигурацией, что и у остальных машин. Не обязательно, чтобы эта машина была той же,
# что сервер ${serverIP}, но она также должна быть онлайн.
# Это может быть виртуальная NixOS-машина, установленная на сервере ${serverIP} в режим автозапуска
buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903"; buildNodeYggIP = "200:ccc6:1361:5c84:aba0:1244:35f5:c903";
# -------
# here is your configuration repo URL. fork it and change it on your own if you want
#
# здесь требуется указать ваш URL-адрес репозитория с конфигурацией. fork-аете, и меняете на свой
configRepoUrl = "https://forgejo.gregorbednov.ru/gregorbednov/configuration.nix.git"; configRepoUrl = "https://forgejo.gregorbednov.ru/gregorbednov/configuration.nix.git";
# -------
# here is some university specifics, apps and resources
# e.g. for MIREA it's wallpaper, university logo, utils to show uuniversity schedule week number and so on
#
# LEGALS: I am NOT a creator on wallpaper.svg,
# I do NOT own wallpaper.svg, this doesn't represent any of my ideas or views,
# that's just a logo (a coat of arms to be precise) of a university,
# and it is in the public domain.
#
# здесь могут быть специфические вузовские данные и ресурсы,
# например, обои, логотип университета, утилита для показа номера недели по расписанию, и так далее
#
# ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:
# Я не являюсь владельцем файла wallpaper.svg, его добавление не репрезентует моих идей или взглядов,
# это просто логотип (точнее герб) университета, и он является общественным достоянием.
university = import ../mirea-specific/university.nix;
in in
{ {
isoImage.isoName = lib.mkForce "mirea-nixos-installer.iso"; isoImage.isoName = lib.mkForce university.isoName;
isoImage.squashfsCompression = "zstd -Xcompression-level 6"; isoImage.squashfsCompression = "zstd -Xcompression-level 6";
services.getty.autologinUser = lib.mkForce "root"; services.getty.autologinUser = lib.mkForce "root";
@ -19,15 +71,22 @@ in
git git
pv pv
curl curl
(writeShellScriptBin "mirea-install" ( (writeShellScriptBin university.installerBin (
builtins.replaceStrings builtins.replaceStrings
[ "@CONFIG_REPO_URL@" ] [ "@CONFIG_REPO_URL@" "@DISTRO_TITLE@" ]
[ configRepoUrl ] [ configRepoUrl university.shortName ]
(builtins.readFile ./mirea-install.sh) (builtins.readFile ./mirea-install.sh)
)) ))
]; ];
# Yggdrasil запускается на установщике — благодаря ему доступен локальный кэш сборок # Yggdrasil-маршрутизация позволяет целевым ПК автоматически получать статический IPv6 даже в сетях DHCP,
# что также запускается на установщике для максимальной гибкости.
# Благодаря Yggdrasil может быть доступно удаленнное управление и локальный кэш сборок
# Yggdrasil routing above network allows any target PC to get automatically static IPv6 even on DHCP,
# so installer is recommended to use Yggdrasil too for maximum scalability
# With Yggdrasil routing it's easy to connect remotely, and you can use
# nix build cache nodes with DHCP-addresses (e.g. other PCs)
services.yggdrasil = { services.yggdrasil = {
enable = true; enable = true;
persistentKeys = false; persistentKeys = false;
@ -49,7 +108,10 @@ in
]; ];
trusted-substituters = [ "http://nixos.builds.node" ]; trusted-substituters = [ "http://nixos.builds.node" ];
connect-timeout = 5; connect-timeout = 5;
experimental-features = [ "nix-command" "flakes" ]; experimental-features = [
"nix-command"
"flakes"
];
}; };
systemd.services.nix-daemon = { systemd.services.nix-daemon = {
@ -64,10 +126,13 @@ in
environment.etc."issue".text = '' environment.etc."issue".text = ''
┌─────────────────────────────────────────┐ ┌─────────────────────────────────────────┐
│ Установщик NixOS MIREA │ │ Установщик NixOS ${university.shortName}
│ Запустите: mirea-install │ │ Запустите: ${university.installerBin}
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ NixOS Installer ${university.shortName}
│ Run: ${university.installerBin}
└─────────────────────────────────────────┘ └─────────────────────────────────────────┘
''; '';
system.stateVersion = "24.11"; system.stateVersion = "24.11";

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# MIREA NixOS Installer # @DISTRO_TITLE@ NixOS Installer
# Устанавливает NixOS рядом с Windows или на чистый диск. # Устанавливает NixOS рядом с Windows или на чистый диск.
# NixOS root: 50 GiB, EFI (при чистой установке): 512 MiB. # NixOS root: 50 GiB, EFI (при чистой установке): 512 MiB.
# Идемпотентен: если установка прервалась, просто запустите повторно. # Идемпотентен: если установка прервалась, просто запустите повторно.
@ -331,9 +331,9 @@ else
info "noatime добавлен к ext4 разделам" info "noatime добавлен к ext4 разделам"
fi fi
step "Загрузка конфигурации MIREA" step "Загрузка конфигурации @DISTRO_TITLE@"
if [[ -f "$MNT/etc/nixos/flake.nix" ]]; then if [[ -f "$MNT/etc/nixos/flake.nix" ]]; then
skip "конфигурация MIREA уже загружена" skip "конфигурация @DISTRO_TITLE@ уже загружена"
else else
tmpconf=$(mktemp -d) tmpconf=$(mktemp -d)
git clone --depth=1 "$CONFIG_REPO_URL" "$tmpconf/config" \ git clone --depth=1 "$CONFIG_REPO_URL" "$tmpconf/config" \
@ -342,7 +342,7 @@ else
cp "$tmpconf/config/flake.lock" "$MNT/etc/nixos/" cp "$tmpconf/config/flake.lock" "$MNT/etc/nixos/"
cp "$tmpconf/config/configuration.nix" "$MNT/etc/nixos/" cp "$tmpconf/config/configuration.nix" "$MNT/etc/nixos/"
rm -rf "$tmpconf" rm -rf "$tmpconf"
info "Конфигурация MIREA установлена" info "Конфигурация @DISTRO_TITLE@ установлена"
fi fi
# ── Установка ───────────────────────────────────────────────────────────────── # ── Установка ─────────────────────────────────────────────────────────────────

View file

@ -0,0 +1,19 @@
# Утилита расчёта номера учебной недели.
# Даты отсечки семестров (9 февраля / 1 сентября) специфичны для МИРЭА,
# поэтому пакет живёт здесь, а не в общем mireadesktop.
{ pkgs }:
pkgs.stdenv.mkDerivation rec {
pname = "mireaweek";
version = "0.1.0";
src = ./weekday.kt;
dontInstall = true;
dontUnpack = true;
nativeBuildInputs = [ pkgs.kotlin ];
buildPhase = ''
mkdir -p $out/{bin,lib}
kotlinc $src -include-runtime -d mireaweek.jar
mv mireaweek.jar $out/lib
printf "${pkgs.jre}/bin/java -jar $out/lib/mireaweek.jar" > $out/bin/mireaweek
chmod +x $out/bin/mireaweek
'';
}

View file

@ -0,0 +1,15 @@
# Виджет панели tint2, показывающий номер учебной недели МИРЭА.
# Подставляется в mireadesktop через параметр extraTint2Widgets.
{ mireaweek }:
''
#-------------------------------------
execp = new
execp_name = mireaweek
execp_command = ${mireaweek}/bin/mireaweek
execp_interval = 0
execp_font = mono 10
execp_font_color = #dddddd 100
execp_centered = 1
execp_has_icon = 0
execp_padding = 5 5
''

View file

@ -0,0 +1,27 @@
{
# University names
# May be written any language
#
# Название университета
# Может быть на любом языке
name = "МИРЭА — Российский технологический университет";
# short name should be in english
# короткое название должно быть на английском
shortName = "MIREA";
# NixOS installer branding
# Брендирование установщика NixOS
isoName = "mirea-nixos-installer.iso";
installerBin = "mirea-install";
# LEGALS: I am NOT a creator on wallpaper.svg,
# I do NOT own wallpaper.svg, this doesn't represent any of my ideas or views,
# that's just a logo (a coat of arms to be precise) of a university,
# and it is in the public domain.
#
# ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:
# Я не являюсь владельцем файла wallpaper.svg, его добавление не репрезентует моих идей или взглядов,
# это просто логотип (точнее герб) университета, и он является общественным достоянием.
wallpaper = ./wallpaper.svg;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 689 KiB

52
mirea-specific/weekday.kt Normal file
View file

@ -0,0 +1,52 @@
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.Month
enum class Period {
Autumn,
Winter,
Spring
}
fun determinePeriod(today: LocalDate): Period {
val februaryCutoff = LocalDate.of(today.year, Month.FEBRUARY, 9)
val septemberCutoff = LocalDate.of(today.year, Month.SEPTEMBER, 1)
return when {
today.isBefore(februaryCutoff) -> Period.Winter
today.isAfter(septemberCutoff.minusDays(1)) -> Period.Autumn
else -> Period.Spring
}
}
fun calculateWeek(period: Period, date: LocalDate): String {
return when {
period == Period.Winter -> "Хороших праздников, удачной сессии!"
date.dayOfWeek == DayOfWeek.SUNDAY -> "Сегодня воскресенье, лучше иди домой"
else -> {
val currentWeek = date.getWeekOfYear()
val periodLimit = when (period) {
Period.Spring -> LocalDate.of(date.year, Month.FEBRUARY, 9)
Period.Autumn -> LocalDate.of(date.year, Month.SEPTEMBER, 1)
else -> throw IllegalStateException("Unexpected period")
}
val limitWeek = periodLimit.getWeekOfYear()
val isLimitSunday = periodLimit.dayOfWeek == DayOfWeek.SUNDAY
val weekOffset = if (isLimitSunday) 1 else 0
val weekNumber = 1 + currentWeek - limitWeek - weekOffset
"$weekNumber неделя"
}
}
}
fun LocalDate.getWeekOfYear(): Int {
return this.get(java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR)
}
fun main() {
val today = LocalDate.now()
val period = determinePeriod(today)
val weekInfo = calculateWeek(period, today)
println(weekInfo)
}