* move routes logic into own directory * api: add some date in human readable format
144 lines
3.9 KiB
Rust
144 lines
3.9 KiB
Rust
use actix_web::{get, routes, web, HttpRequest, Responder};
|
|
use cached::proc_macro::cached;
|
|
use ramhorns::Content;
|
|
|
|
use crate::{
|
|
config::Config,
|
|
logic::contact::{find_links, read, remove_paragraphs},
|
|
template::{InfosPage, NavBar},
|
|
utils::{
|
|
markdown::{File, FilePath},
|
|
metadata::MType,
|
|
misc::{lang, make_kw, read_file_fallback, Html, Lang},
|
|
},
|
|
};
|
|
|
|
const CONTACT_DIR: &str = "contacts";
|
|
|
|
pub fn pages(cfg: &mut web::ServiceConfig) {
|
|
// Here define the services used
|
|
let routes = |route_path| {
|
|
web::scope(route_path)
|
|
.service(page)
|
|
.service(service_redirection)
|
|
};
|
|
|
|
// Here define the routes aliases
|
|
cfg.service(routes("/contact")).service(routes("/c"));
|
|
}
|
|
|
|
#[get("")]
|
|
async fn page(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
|
Html(build_page(config.get_ref().to_owned(), lang(req.headers())))
|
|
}
|
|
|
|
#[routes]
|
|
#[get("/{service}")]
|
|
#[get("/{service}/{scope}")]
|
|
async fn service_redirection(config: web::Data<Config>, req: HttpRequest) -> impl Responder {
|
|
let info = req.match_info();
|
|
let link = find_links(format!("{}/{}", config.locations.data_dir, CONTACT_DIR))
|
|
.iter()
|
|
// Find requested service
|
|
.filter(|&x| x.service == *info.query("service"))
|
|
// Search for a potential scope
|
|
.filter(|&x| match (info.get("scope"), x.scope.clone()) {
|
|
// The right scope is accepted
|
|
(Some(str_value), Some(string_value)) if str_value == string_value.as_str() => true,
|
|
// No scope provided is accepted
|
|
(None, None) => true,
|
|
// Else we reject
|
|
_ => false,
|
|
})
|
|
// Returns the link
|
|
.map(|data| data.url.clone())
|
|
.collect::<Vec<String>>();
|
|
|
|
// This shouldn't be more than one link here
|
|
match link.len() {
|
|
// Redirect to the desired service
|
|
1 => actix_web::web::Redirect::to(link[0].clone()),
|
|
// By default, returns to the contact page
|
|
_ => actix_web::web::Redirect::to("/contact"),
|
|
}
|
|
}
|
|
|
|
#[derive(Content, Debug)]
|
|
struct NetworksTemplate {
|
|
navbar: NavBar,
|
|
about: Option<File>,
|
|
|
|
socials_exists: bool,
|
|
socials: Vec<File>,
|
|
|
|
forges_exists: bool,
|
|
forges: Vec<File>,
|
|
|
|
others_exists: bool,
|
|
others: Vec<File>,
|
|
}
|
|
|
|
#[cached(time = 60)]
|
|
fn build_page(config: Config, lang: Lang) -> String {
|
|
let contacts_dir = format!("{}/{}", config.locations.data_dir, CONTACT_DIR);
|
|
let ext = ".md";
|
|
|
|
// Get about
|
|
let (about, html_lang) = read_file_fallback(
|
|
FilePath {
|
|
base: contacts_dir.clone(),
|
|
path: "about.md".to_owned(),
|
|
},
|
|
MType::Generic,
|
|
&lang,
|
|
);
|
|
|
|
let mut socials = read(&FilePath {
|
|
base: contacts_dir.clone(),
|
|
path: format!("socials/*{ext}"),
|
|
});
|
|
let mut forges = read(&FilePath {
|
|
base: contacts_dir.clone(),
|
|
path: format!("forges/*{ext}"),
|
|
});
|
|
let mut others = read(&FilePath {
|
|
base: contacts_dir,
|
|
path: format!("others/*{ext}"),
|
|
});
|
|
|
|
// Remove paragraphs in custom statements
|
|
[&mut socials, &mut forges, &mut others]
|
|
.iter_mut()
|
|
.for_each(|it| remove_paragraphs(it));
|
|
|
|
config.tmpl.render(
|
|
"contact/index.html",
|
|
NetworksTemplate {
|
|
navbar: NavBar {
|
|
contact: true,
|
|
..NavBar::default()
|
|
},
|
|
about,
|
|
|
|
socials_exists: !socials.is_empty(),
|
|
socials,
|
|
|
|
forges_exists: !forges.is_empty(),
|
|
forges,
|
|
|
|
others_exists: !others.is_empty(),
|
|
others,
|
|
},
|
|
InfosPage {
|
|
title: Some("Contacts".into()),
|
|
desc: Some(format!("Réseaux d'{}", config.fc.name.unwrap_or_default())),
|
|
kw: Some(make_kw(&[
|
|
"réseaux sociaux",
|
|
"email",
|
|
"contact",
|
|
"linktree",
|
|
])),
|
|
},
|
|
Some(html_lang),
|
|
)
|
|
}
|