cache files
This commit is contained in:
parent
182b17c47f
commit
eb55d13c01
8 changed files with 66 additions and 43 deletions
|
@ -31,8 +31,7 @@ fn build_index(config: Config) -> String {
|
||||||
let mut posts = get_posts(&format!("{blog_dir}/{POST_DIR}"));
|
let mut posts = get_posts(&format!("{blog_dir}/{POST_DIR}"));
|
||||||
|
|
||||||
// Get about
|
// Get about
|
||||||
let about: Option<File> =
|
let about: Option<File> = read_file(format!("{blog_dir}/about.md"), TypeFileMetadata::Generic);
|
||||||
read_file(&format!("{blog_dir}/about.md"), &TypeFileMetadata::Generic);
|
|
||||||
|
|
||||||
// Sort from newest to oldest
|
// Sort from newest to oldest
|
||||||
posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day));
|
posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day));
|
||||||
|
|
|
@ -85,26 +85,44 @@ fn build_page(config: Config) -> String {
|
||||||
|
|
||||||
// Get about
|
// Get about
|
||||||
let about = read_file(
|
let about = read_file(
|
||||||
&format!("{contacts_dir}/about.md"),
|
format!("{contacts_dir}/about.md"),
|
||||||
&TypeFileMetadata::Generic,
|
TypeFileMetadata::Generic,
|
||||||
);
|
);
|
||||||
|
|
||||||
let socials_dir = "socials";
|
let socials_dir = "socials";
|
||||||
let mut socials = glob(&format!("{contacts_dir}/{socials_dir}/*{ext}"))
|
let mut socials = glob(&format!("{contacts_dir}/{socials_dir}/*{ext}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy(), &TypeFileMetadata::Contact).unwrap())
|
.map(|e| {
|
||||||
|
read_file(
|
||||||
|
e.unwrap().to_string_lossy().to_string(),
|
||||||
|
TypeFileMetadata::Contact,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
let forges_dir = "forges";
|
let forges_dir = "forges";
|
||||||
let mut forges = glob(&format!("{contacts_dir}/{forges_dir}/*{ext}"))
|
let mut forges = glob(&format!("{contacts_dir}/{forges_dir}/*{ext}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy(), &TypeFileMetadata::Contact).unwrap())
|
.map(|e| {
|
||||||
|
read_file(
|
||||||
|
e.unwrap().to_string_lossy().to_string(),
|
||||||
|
TypeFileMetadata::Contact,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
let others_dir = "others";
|
let others_dir = "others";
|
||||||
let mut others = glob(&format!("{contacts_dir}/{others_dir}/*{ext}"))
|
let mut others = glob(&format!("{contacts_dir}/{others_dir}/*{ext}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy(), &TypeFileMetadata::Contact).unwrap())
|
.map(|e| {
|
||||||
|
read_file(
|
||||||
|
e.unwrap().to_string_lossy().to_string(),
|
||||||
|
TypeFileMetadata::Contact,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
// Remove paragraphs in custom statements
|
// Remove paragraphs in custom statements
|
||||||
|
|
|
@ -53,10 +53,7 @@ fn get_content(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_file(
|
read_file(format!("{cours_dir}/{filename}"), TypeFileMetadata::Generic)
|
||||||
&format!("{cours_dir}/{filename}"),
|
|
||||||
&TypeFileMetadata::Generic,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_page(info: &web::Query<PathRequest>, config: Config) -> String {
|
fn build_page(info: &web::Query<PathRequest>, config: Config) -> String {
|
||||||
|
|
|
@ -36,8 +36,8 @@ struct StyleAvatar {
|
||||||
#[once(time = 60)]
|
#[once(time = 60)]
|
||||||
fn build_page(config: Config) -> String {
|
fn build_page(config: Config) -> String {
|
||||||
let mut file = read_file(
|
let mut file = read_file(
|
||||||
&format!("{}/index.md", config.locations.data_dir),
|
format!("{}/index.md", config.locations.data_dir),
|
||||||
&TypeFileMetadata::Index,
|
TypeFileMetadata::Index,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Default values
|
// Default values
|
||||||
|
@ -67,7 +67,7 @@ fn build_page(config: Config) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
file = read_file("README.md", &TypeFileMetadata::Generic);
|
file = read_file("README.md".to_string(), TypeFileMetadata::Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
|
|
|
@ -5,11 +5,11 @@ use ramhorns::Content;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
|
template::{InfosPage, NavBar},
|
||||||
utils::{
|
utils::{
|
||||||
markdown::{File, TypeFileMetadata},
|
markdown::{File, TypeFileMetadata},
|
||||||
misc::{make_kw, read_file, Html},
|
misc::{make_kw, read_file, Html},
|
||||||
},
|
},
|
||||||
template::{InfosPage, NavBar},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("/portfolio")]
|
#[get("/portfolio")]
|
||||||
|
@ -36,14 +36,20 @@ fn build_page(config: Config) -> String {
|
||||||
|
|
||||||
// Get about
|
// Get about
|
||||||
let about = read_file(
|
let about = read_file(
|
||||||
&format!("{projects_dir}/about.md"),
|
format!("{projects_dir}/about.md"),
|
||||||
&TypeFileMetadata::Generic,
|
TypeFileMetadata::Generic,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get apps
|
// Get apps
|
||||||
let apps = glob(&format!("{apps_dir}/*{ext}"))
|
let apps = glob(&format!("{apps_dir}/*{ext}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy(), &TypeFileMetadata::Portfolio).unwrap())
|
.map(|e| {
|
||||||
|
read_file(
|
||||||
|
e.unwrap().to_string_lossy().to_string(),
|
||||||
|
TypeFileMetadata::Portfolio,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
let appdata = if apps.is_empty() {
|
let appdata = if apps.is_empty() {
|
||||||
|
@ -55,7 +61,13 @@ fn build_page(config: Config) -> String {
|
||||||
// Get archived apps
|
// Get archived apps
|
||||||
let archived_apps = glob(&format!("{apps_dir}/archive/*{ext}"))
|
let archived_apps = glob(&format!("{apps_dir}/archive/*{ext}"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy(), &TypeFileMetadata::Portfolio).unwrap())
|
.map(|e| {
|
||||||
|
read_file(
|
||||||
|
e.unwrap().to_string_lossy().to_string(),
|
||||||
|
TypeFileMetadata::Portfolio,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
let archived_appdata = if archived_apps.is_empty() {
|
let archived_appdata = if archived_apps.is_empty() {
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<'a> Deserialize<'a> for Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata for contact entry
|
/// Metadata for contact entry
|
||||||
#[derive(Content, Debug, Default, Deserialize)]
|
#[derive(Content, Debug, Default, Deserialize, Clone)]
|
||||||
pub struct FileMetadataContact {
|
pub struct FileMetadataContact {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub custom: Option<bool>,
|
pub custom: Option<bool>,
|
||||||
|
@ -56,7 +56,7 @@ pub struct FileMetadataContact {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata for index page
|
/// Metadata for index page
|
||||||
#[derive(Content, Debug, Default, Deserialize)]
|
#[derive(Content, Debug, Default, Deserialize, Clone)]
|
||||||
pub struct FileMetadataIndex {
|
pub struct FileMetadataIndex {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub pronouns: Option<String>,
|
pub pronouns: Option<String>,
|
||||||
|
@ -66,7 +66,7 @@ pub struct FileMetadataIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata for portfolio cards
|
/// Metadata for portfolio cards
|
||||||
#[derive(Content, Debug, Default, Deserialize)]
|
#[derive(Content, Debug, Default, Deserialize, Clone)]
|
||||||
pub struct FileMetadataPortfolio {
|
pub struct FileMetadataPortfolio {
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
pub link: Option<String>,
|
pub link: Option<String>,
|
||||||
|
@ -75,6 +75,7 @@ pub struct FileMetadataPortfolio {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of available metadata types
|
/// List of available metadata types
|
||||||
|
#[derive(Hash, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum TypeFileMetadata {
|
pub enum TypeFileMetadata {
|
||||||
Blog,
|
Blog,
|
||||||
Contact,
|
Contact,
|
||||||
|
@ -85,7 +86,7 @@ pub enum TypeFileMetadata {
|
||||||
|
|
||||||
/// Structure who holds all the metadata the file have
|
/// Structure who holds all the metadata the file have
|
||||||
/// Usually all fields are None except one
|
/// Usually all fields are None except one
|
||||||
#[derive(Content, Debug, Default, Deserialize)]
|
#[derive(Content, Debug, Default, Deserialize, Clone)]
|
||||||
pub struct FileMetadata {
|
pub struct FileMetadata {
|
||||||
pub hardbreaks: bool,
|
pub hardbreaks: bool,
|
||||||
pub blog: Option<FileMetadataBlog>,
|
pub blog: Option<FileMetadataBlog>,
|
||||||
|
@ -96,7 +97,7 @@ pub struct FileMetadata {
|
||||||
|
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
/// Global metadata
|
/// Global metadata
|
||||||
#[derive(Content, Debug)]
|
#[derive(Content, Debug, Clone)]
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
pub info: FileMetadata,
|
pub info: FileMetadata,
|
||||||
pub math: bool,
|
pub math: bool,
|
||||||
|
@ -115,7 +116,7 @@ impl Metadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// File description
|
/// File description
|
||||||
#[derive(Content, Debug)]
|
#[derive(Content, Debug, Clone)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
pub metadata: Metadata,
|
pub metadata: Metadata,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
|
@ -247,12 +248,8 @@ fn fix_images_and_integration(path: &str, html: &str) -> (String, Metadata) {
|
||||||
if mime == "text/markdown" {
|
if mime == "text/markdown" {
|
||||||
let mut options = get_options();
|
let mut options = get_options();
|
||||||
options.extension.footnotes = false;
|
options.extension.footnotes = false;
|
||||||
let data = read_md(
|
let data =
|
||||||
&img_path,
|
read_md(&img_path, &file, TypeFileMetadata::Generic, Some(options));
|
||||||
&file,
|
|
||||||
&TypeFileMetadata::Generic,
|
|
||||||
Some(options),
|
|
||||||
);
|
|
||||||
el.replace(&data.content, ContentType::Html);
|
el.replace(&data.content, ContentType::Html);
|
||||||
|
|
||||||
// Store the metadata for later merging
|
// Store the metadata for later merging
|
||||||
|
@ -283,7 +280,7 @@ fn fix_images_and_integration(path: &str, html: &str) -> (String, Metadata) {
|
||||||
pub fn read_md(
|
pub fn read_md(
|
||||||
path: &str,
|
path: &str,
|
||||||
raw_text: &str,
|
raw_text: &str,
|
||||||
metadata_type: &TypeFileMetadata,
|
metadata_type: TypeFileMetadata,
|
||||||
options: Option<Options>,
|
options: Option<Options>,
|
||||||
) -> File {
|
) -> File {
|
||||||
let arena = Arena::new();
|
let arena = Arena::new();
|
||||||
|
@ -333,7 +330,7 @@ fn deserialize_metadata<T: Default + serde::de::DeserializeOwned>(text: &str) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch metadata from AST
|
/// Fetch metadata from AST
|
||||||
pub fn get_metadata<'a>(root: &'a AstNode<'a>, mtype: &TypeFileMetadata) -> FileMetadata {
|
pub fn get_metadata<'a>(root: &'a AstNode<'a>, mtype: TypeFileMetadata) -> FileMetadata {
|
||||||
root.children()
|
root.children()
|
||||||
.map(|node| {
|
.map(|node| {
|
||||||
let generic = FileMetadata {
|
let generic = FileMetadata {
|
||||||
|
|
|
@ -53,13 +53,14 @@ impl Responder for Html {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a file
|
/// Read a file
|
||||||
pub fn read_file(filename: &str, expected_file: &TypeFileMetadata) -> Option<File> {
|
#[cached]
|
||||||
Path::new(filename)
|
pub fn read_file(filename: String, expected_file: TypeFileMetadata) -> Option<File> {
|
||||||
|
Path::new(&filename.clone())
|
||||||
.extension()
|
.extension()
|
||||||
.and_then(|ext| match ext.to_str().unwrap() {
|
.and_then(|ext| match ext.to_str().unwrap() {
|
||||||
"pdf" => fs::read(filename).map_or(None, |bytes| Some(read_pdf(bytes))),
|
"pdf" => fs::read(filename).map_or(None, |bytes| Some(read_pdf(bytes))),
|
||||||
_ => fs::read_to_string(filename).map_or(None, |text| {
|
_ => fs::read_to_string(&filename).map_or(None, |text| {
|
||||||
Some(read_md(filename, &text, expected_file, None))
|
Some(read_md(&filename, &text, expected_file, None))
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,8 @@ impl Post {
|
||||||
let ext = ".md";
|
let ext = ".md";
|
||||||
|
|
||||||
if let Some(file) = read_file(
|
if let Some(file) = read_file(
|
||||||
&format!("{blog_dir}/{}{ext}", self.url),
|
format!("{blog_dir}/{}{ext}", self.url),
|
||||||
&TypeFileMetadata::Blog,
|
TypeFileMetadata::Blog,
|
||||||
) {
|
) {
|
||||||
self.content = Some(file.content);
|
self.content = Some(file.content);
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,7 @@ pub fn get_posts(location: &str) -> Vec<Post> {
|
||||||
|
|
||||||
let options = get_options();
|
let options = get_options();
|
||||||
let root = parse_document(&arena, &text, &options);
|
let root = parse_document(&arena, &text, &options);
|
||||||
let mut metadata =
|
let mut metadata = get_metadata(root, TypeFileMetadata::Blog).blog.unwrap();
|
||||||
get_metadata(root, &TypeFileMetadata::Blog).blog.unwrap();
|
|
||||||
|
|
||||||
// Always have a title
|
// Always have a title
|
||||||
metadata.title = metadata
|
metadata.title = metadata
|
||||||
|
@ -143,8 +142,8 @@ pub fn get_post(
|
||||||
let ext = ".md";
|
let ext = ".md";
|
||||||
|
|
||||||
*post = read_file(
|
*post = read_file(
|
||||||
&format!("{blog_dir}/{filename}{ext}"),
|
format!("{blog_dir}/{filename}{ext}"),
|
||||||
&TypeFileMetadata::Blog,
|
TypeFileMetadata::Blog,
|
||||||
);
|
);
|
||||||
|
|
||||||
let default = (
|
let default = (
|
||||||
|
|
Loading…
Reference in a new issue