mylloon.fr/src/routes/cours.rs
2024-11-09 17:29:59 +01:00

106 lines
2.7 KiB
Rust

use actix_web::{get, web, Responder};
use cached::proc_macro::cached;
use ramhorns::Content;
use regex::Regex;
use serde::Deserialize;
use crate::{
config::Config,
template::{InfosPage, NavBar},
utils::{
markdown::{File, TypeFileMetadata},
misc::{make_kw, read_file, Html},
routes::cours::{excluded, get_filetree},
},
};
#[derive(Debug, Deserialize)]
pub struct PathRequest {
q: Option<String>,
}
#[get("/cours")]
pub async fn page(info: web::Query<PathRequest>, config: web::Data<Config>) -> impl Responder {
Html(build_page(&info, config.get_ref().to_owned()))
}
#[derive(Content, Debug)]
struct CoursTemplate {
navbar: NavBar,
filetree: String,
content: Option<File>,
}
#[cached]
fn compile_patterns(exclusion_list: Vec<String>) -> Vec<Regex> {
exclusion_list
.iter()
.map(|pattern| Regex::new(pattern).unwrap())
.collect()
}
/// Get a page content
fn get_content(
cours_dir: &str,
path: &web::Query<PathRequest>,
exclusion_list: &[String],
exclusion_patterns: &[Regex],
) -> Option<File> {
let filename = path.q.as_ref().map_or("index.md", |q| q);
// Exclusion checks
if excluded(filename, exclusion_list, exclusion_patterns) {
return None;
}
read_file(
&format!("{cours_dir}/{filename}"),
&TypeFileMetadata::Generic,
)
}
fn build_page(info: &web::Query<PathRequest>, config: Config) -> String {
let cours_dir = "data/cours";
let (ep, el): (_, Vec<String>) = config
.fc
.exclude_courses
.unwrap()
.into_iter()
.partition(|item| item.starts_with('/'));
let exclusion_list = {
let mut base = vec!["../".to_owned()];
base.extend(el);
base
};
let exclusion_patterns: Vec<Regex> =
compile_patterns(ep.iter().map(|r| r[1..r.len() - 1].to_owned()).collect());
let filetree = get_filetree(cours_dir, &exclusion_list, &exclusion_patterns);
config.tmpl.render(
"cours.html",
CoursTemplate {
navbar: NavBar {
cours: true,
..NavBar::default()
},
filetree: serde_json::to_string(&filetree).unwrap(),
content: get_content(cours_dir, info, &exclusion_list, &exclusion_patterns),
},
InfosPage {
title: Some("Cours".into()),
desc: Some("Cours à l'univ".into()),
kw: Some(make_kw(&[
"cours",
"études",
"université",
"licence",
"master",
"notes",
"digital garden",
])),
},
)
}