All checks were successful
PR Check / lint-and-format (pull_request) Successful in 12m34s
123 lines
3.2 KiB
Rust
123 lines
3.2 KiB
Rust
use actix_web::{get, web, HttpRequest, Responder};
|
|
use cached::proc_macro::cached;
|
|
use glob::glob;
|
|
use ramhorns::Content;
|
|
|
|
use crate::{
|
|
config::Config,
|
|
logic::portfolio::{get_langs, Language},
|
|
template::{InfosPage, NavBar},
|
|
utils::{
|
|
markdown::{File, FilePath},
|
|
metadata::MType,
|
|
misc::{lang, make_kw, read_file, read_file_fallback, Html, Lang},
|
|
},
|
|
};
|
|
|
|
#[get("/portfolio")]
|
|
pub async fn page(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
|
Html(build_page(config.get_ref().to_owned(), lang(req.headers())))
|
|
}
|
|
|
|
#[derive(Content, Debug)]
|
|
struct PortfolioTemplate<'a> {
|
|
navbar: NavBar,
|
|
about: Option<File>,
|
|
langs: Vec<Language>,
|
|
location_apps: Option<&'a str>,
|
|
apps: Option<Vec<File>>,
|
|
archived_apps: Option<Vec<File>>,
|
|
archived_apps_exists: bool,
|
|
err_msg: &'a str,
|
|
}
|
|
|
|
#[cached(time = 60)]
|
|
fn build_page(config: Config, lang: Lang) -> String {
|
|
let projects_dir = format!("{}/projects", config.locations.data_dir);
|
|
let apps_dir = FilePath {
|
|
base: format!("{projects_dir}/apps"),
|
|
path: String::new(),
|
|
};
|
|
let ext = ".md";
|
|
|
|
// Get about
|
|
let (about, html_lang) = read_file_fallback(
|
|
FilePath {
|
|
base: projects_dir,
|
|
path: "about.md".to_owned(),
|
|
},
|
|
MType::Generic,
|
|
&lang,
|
|
);
|
|
|
|
// Get apps
|
|
let apps = glob(&format!("{apps_dir}/*{ext}"))
|
|
.unwrap()
|
|
.map(|e| {
|
|
read_file(
|
|
apps_dir.from(&e.unwrap().to_string_lossy()),
|
|
MType::Portfolio,
|
|
None,
|
|
)
|
|
.unwrap()
|
|
})
|
|
.collect::<Vec<File>>();
|
|
|
|
let appdata = if apps.is_empty() {
|
|
(None, Some(apps_dir.to_string()))
|
|
} else {
|
|
(Some(apps), None)
|
|
};
|
|
|
|
// Get archived apps
|
|
let archived_apps = glob(&format!("{apps_dir}/archive/*{ext}"))
|
|
.unwrap()
|
|
.map(|e| {
|
|
read_file(
|
|
apps_dir.from(&e.unwrap().to_string_lossy()),
|
|
MType::Portfolio,
|
|
None,
|
|
)
|
|
.unwrap()
|
|
})
|
|
.collect::<Vec<File>>();
|
|
|
|
let archived_appdata = if archived_apps.is_empty() {
|
|
(None, false)
|
|
} else {
|
|
(Some(archived_apps), true)
|
|
};
|
|
|
|
config.tmpl.render(
|
|
"portfolio/index.html",
|
|
PortfolioTemplate {
|
|
navbar: NavBar {
|
|
portfolio: true,
|
|
..NavBar::default()
|
|
},
|
|
about,
|
|
langs: get_langs(),
|
|
location_apps: appdata.1.as_deref(),
|
|
apps: appdata.0,
|
|
archived_apps: archived_appdata.0,
|
|
archived_apps_exists: archived_appdata.1,
|
|
err_msg: "is empty",
|
|
},
|
|
InfosPage {
|
|
title: Some("Portfolio".into()),
|
|
desc: Some(format!(
|
|
"Portfolio d'{}",
|
|
config.fc.name.unwrap_or_default()
|
|
)),
|
|
kw: Some(make_kw(&[
|
|
"développeur",
|
|
"portfolio",
|
|
"projets",
|
|
"programmation",
|
|
"applications",
|
|
"code",
|
|
])),
|
|
},
|
|
Some(html_lang),
|
|
)
|
|
}
|