* move date to utils dir * rename get_* to build_* * increase index ttl from 60 to 120 * split index blog build in half
This commit is contained in:
parent
3dc18e6f75
commit
2c0fe8d6e5
11 changed files with 80 additions and 71 deletions
29
src/misc/date.rs
Normal file
29
src/misc/date.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use chrono::{Datelike, NaiveDate};
|
||||||
|
use ramhorns::Content;
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
|
#[derive(Content, Default)]
|
||||||
|
pub struct Date {
|
||||||
|
pub day: u32,
|
||||||
|
pub month: u32,
|
||||||
|
pub year: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Date {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
match <&str>::deserialize(deserializer) {
|
||||||
|
Ok(s) => match NaiveDate::parse_from_str(s, "%d-%m-%Y") {
|
||||||
|
Ok(date) => Ok(Self {
|
||||||
|
day: date.day(),
|
||||||
|
month: date.month(),
|
||||||
|
year: date.year(),
|
||||||
|
}),
|
||||||
|
Err(e) => Err(serde::de::Error::custom(e)),
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
|
pub mod date;
|
||||||
pub mod github;
|
pub mod github;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use ramhorns::Content;
|
||||||
#[get("/.well-known/security.txt")]
|
#[get("/.well-known/security.txt")]
|
||||||
#[get("/security.txt")]
|
#[get("/security.txt")]
|
||||||
pub async fn security(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
pub async fn security(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_security(
|
HttpResponse::Ok().body(build_securitytxt(
|
||||||
config.get_ref().clone(),
|
config.get_ref().clone(),
|
||||||
req.connection_info().to_owned(),
|
req.connection_info().to_owned(),
|
||||||
))
|
))
|
||||||
|
@ -21,7 +21,7 @@ struct SecurityTemplate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
fn get_security(config: Config, info: ConnectionInfo) -> String {
|
fn build_securitytxt(config: Config, info: ConnectionInfo) -> String {
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
"security.txt",
|
"security.txt",
|
||||||
SecurityTemplate {
|
SecurityTemplate {
|
||||||
|
@ -45,11 +45,11 @@ pub async fn humans() -> impl Responder {
|
||||||
|
|
||||||
#[get("/robots.txt")]
|
#[get("/robots.txt")]
|
||||||
pub async fn robots() -> impl Responder {
|
pub async fn robots() -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_robots())
|
HttpResponse::Ok().body(build_robotstxt())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
fn get_robots() -> String {
|
fn build_robotstxt() -> String {
|
||||||
// TODO, see https://www.robotstxt.org/orig.html
|
// TODO, see https://www.robotstxt.org/orig.html
|
||||||
"User-agent: * Allow: /".to_string()
|
"User-agent: * Allow: /".to_string()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,13 @@ use ramhorns::Content;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
template::{get_md_asm, get_md_metadata, read_md_file, Date, File, FileMetadata, Infos},
|
misc::date::Date,
|
||||||
|
template::{get_md_asm, get_md_metadata, read_md_file, File, FileMetadata, Infos},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("/blog")]
|
#[get("/blog")]
|
||||||
pub async fn index(config: web::Data<Config>) -> impl Responder {
|
pub async fn index(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_index(config.get_ref().clone()))
|
HttpResponse::Ok().body(build_index(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
|
@ -18,6 +19,27 @@ struct BlogIndexTemplate {
|
||||||
posts: Option<Vec<Post>>,
|
posts: Option<Vec<Post>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[once(time = 120)]
|
||||||
|
pub fn build_index(config: Config) -> String {
|
||||||
|
let mut posts = get_posts("data/blog");
|
||||||
|
|
||||||
|
// Sort from newest to oldest
|
||||||
|
posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day));
|
||||||
|
posts.reverse();
|
||||||
|
|
||||||
|
config.tmpl.render(
|
||||||
|
"blog/index.html",
|
||||||
|
BlogIndexTemplate {
|
||||||
|
posts: if posts.is_empty() { None } else { Some(posts) },
|
||||||
|
},
|
||||||
|
Infos {
|
||||||
|
page_title: Some("Blog".to_string()),
|
||||||
|
page_desc: Some("Liste des posts d'Anri".to_string()),
|
||||||
|
page_kw: Some(["blog", "blogging"].join(", ")),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
struct Post {
|
struct Post {
|
||||||
title: String,
|
title: String,
|
||||||
|
@ -25,17 +47,14 @@ struct Post {
|
||||||
url: String,
|
url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[once(time = 60)]
|
fn get_posts(location: &str) -> Vec<Post> {
|
||||||
pub fn get_index(config: Config) -> String {
|
|
||||||
let location = "data/blog";
|
|
||||||
|
|
||||||
let entries = std::fs::read_dir(location)
|
let entries = std::fs::read_dir(location)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(|f| f.path().extension().unwrap() == "md")
|
.filter(|f| f.path().extension().unwrap() == "md")
|
||||||
.collect::<Vec<std::fs::DirEntry>>();
|
.collect::<Vec<std::fs::DirEntry>>();
|
||||||
|
|
||||||
let mut posts = entries
|
entries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let _filename = f.file_name();
|
let _filename = f.file_name();
|
||||||
|
@ -80,23 +99,7 @@ pub fn get_index(config: Config) -> String {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<Post>>();
|
.collect::<Vec<Post>>()
|
||||||
|
|
||||||
// Sort from newest to oldest
|
|
||||||
posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day));
|
|
||||||
posts.reverse();
|
|
||||||
|
|
||||||
config.tmpl.render(
|
|
||||||
"blog/index.html",
|
|
||||||
BlogIndexTemplate {
|
|
||||||
posts: if posts.is_empty() { None } else { Some(posts) },
|
|
||||||
},
|
|
||||||
Infos {
|
|
||||||
page_title: Some("Blog".to_string()),
|
|
||||||
page_desc: Some("Liste des posts d'Anri".to_string()),
|
|
||||||
page_kw: Some(["blog", "blogging"].join(", ")),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
|
@ -106,19 +109,19 @@ struct BlogPostTemplate {
|
||||||
|
|
||||||
#[get("/blog/{id}")]
|
#[get("/blog/{id}")]
|
||||||
pub async fn page(path: web::Path<(String,)>, config: web::Data<Config>) -> impl Responder {
|
pub async fn page(path: web::Path<(String,)>, config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_post(path.into_inner().0, config.get_ref().clone()))
|
HttpResponse::Ok().body(build_post(path.into_inner().0, config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_post(file: String, config: Config) -> String {
|
pub fn build_post(file: String, config: Config) -> String {
|
||||||
let mut post = None;
|
let mut post = None;
|
||||||
let infos = _get_post(&mut post, file);
|
let infos = get_post(&mut post, file);
|
||||||
|
|
||||||
config
|
config
|
||||||
.tmpl
|
.tmpl
|
||||||
.render("blog/post.html", BlogPostTemplate { post }, infos)
|
.render("blog/post.html", BlogPostTemplate { post }, infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _get_post(post: &mut Option<File>, filename: String) -> Infos {
|
fn get_post(post: &mut Option<File>, filename: String) -> Infos {
|
||||||
let blog_dir = "data/blog";
|
let blog_dir = "data/blog";
|
||||||
let ext = ".md";
|
let ext = ".md";
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ramhorns::Content;
|
||||||
|
|
||||||
#[get("/contrib")]
|
#[get("/contrib")]
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_page(config.get_ref().clone()).await)
|
HttpResponse::Ok().body(build_page(config.get_ref().clone()).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
|
@ -40,7 +40,7 @@ struct Pull {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[once(time = 120)]
|
#[once(time = 120)]
|
||||||
pub async fn get_page(config: Config) -> String {
|
pub async fn build_page(config: Config) -> String {
|
||||||
// Fetch latest data from github
|
// Fetch latest data from github
|
||||||
let data = match fetch_pr().await {
|
let data = match fetch_pr().await {
|
||||||
Ok(projects) => {
|
Ok(projects) => {
|
||||||
|
|
|
@ -6,14 +6,14 @@ use crate::{config::Config, template::Infos};
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_page(config.get_ref().clone()))
|
HttpResponse::Ok().body(build_page(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
struct IndexTemplate {}
|
struct IndexTemplate {}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
pub fn get_page(config: Config) -> String {
|
pub fn build_page(config: Config) -> String {
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
"index.html",
|
"index.html",
|
||||||
IndexTemplate {},
|
IndexTemplate {},
|
||||||
|
|
|
@ -6,14 +6,14 @@ use crate::{config::Config, template::Infos};
|
||||||
|
|
||||||
#[get("/networks")]
|
#[get("/networks")]
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_page(config.get_ref().clone()))
|
HttpResponse::Ok().body(build_page(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
struct NetworksTemplate {}
|
struct NetworksTemplate {}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
pub fn get_page(config: Config) -> String {
|
pub fn build_page(config: Config) -> String {
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
"networks.html",
|
"networks.html",
|
||||||
NetworksTemplate {},
|
NetworksTemplate {},
|
||||||
|
|
|
@ -5,14 +5,14 @@ use ramhorns::Content;
|
||||||
use crate::{config::Config, template::Infos};
|
use crate::{config::Config, template::Infos};
|
||||||
|
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::NotFound().body(get_page(config.get_ref().clone()))
|
HttpResponse::NotFound().body(build_page(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
struct Error404Template {}
|
struct Error404Template {}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
pub fn get_page(config: Config) -> String {
|
pub fn build_page(config: Config) -> String {
|
||||||
config
|
config
|
||||||
.tmpl
|
.tmpl
|
||||||
.render("404.html", Error404Template {}, Infos::default())
|
.render("404.html", Error404Template {}, Infos::default())
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
|
|
||||||
#[get("/portfolio")]
|
#[get("/portfolio")]
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_page(config.get_ref().clone()))
|
HttpResponse::Ok().body(build_page(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
|
@ -25,7 +25,7 @@ struct PortfolioTemplate<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
pub fn get_page(config: Config) -> String {
|
pub fn build_page(config: Config) -> String {
|
||||||
let projects_dir = "data/projects";
|
let projects_dir = "data/projects";
|
||||||
let ext = ".md";
|
let ext = ".md";
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ use crate::{config::Config, template::Infos};
|
||||||
|
|
||||||
#[get("/web3")]
|
#[get("/web3")]
|
||||||
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
pub async fn page(config: web::Data<Config>) -> impl Responder {
|
||||||
HttpResponse::Ok().body(get_page(config.get_ref().clone()))
|
HttpResponse::Ok().body(build_page(config.get_ref().clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Content)]
|
#[derive(Content)]
|
||||||
struct Web3Template {}
|
struct Web3Template {}
|
||||||
|
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
pub fn get_page(config: Config) -> String {
|
pub fn build_page(config: Config) -> String {
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
"web3.html",
|
"web3.html",
|
||||||
Web3Template {},
|
Web3Template {},
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use chrono::{Datelike, NaiveDate};
|
|
||||||
use markdown::mdast::Node;
|
use markdown::mdast::Node;
|
||||||
use ramhorns::{Content, Ramhorns};
|
use ramhorns::{Content, Ramhorns};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::Deserialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
use crate::misc::date::Date;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Template {
|
pub struct Template {
|
||||||
pub directory: String,
|
pub directory: String,
|
||||||
|
@ -59,31 +60,6 @@ impl FrontMatter<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Content, Default)]
|
|
||||||
pub struct Date {
|
|
||||||
pub day: u32,
|
|
||||||
pub month: u32,
|
|
||||||
pub year: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Date {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
match <&str>::deserialize(deserializer) {
|
|
||||||
Ok(s) => match NaiveDate::parse_from_str(s, "%d-%m-%Y") {
|
|
||||||
Ok(date) => Ok(Self {
|
|
||||||
day: date.day(),
|
|
||||||
month: date.month(),
|
|
||||||
year: date.year(),
|
|
||||||
}),
|
|
||||||
Err(e) => Err(serde::de::Error::custom(e)),
|
|
||||||
},
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Content)]
|
#[derive(Default, Deserialize, Content)]
|
||||||
pub struct FileMetadata {
|
pub struct FileMetadata {
|
||||||
|
|
Loading…
Reference in a new issue