filetree preparation
Some checks are pending
ci/woodpecker/push/publish Pipeline is pending

This commit is contained in:
Mylloon 2023-11-01 03:36:03 +01:00
parent fc44816a04
commit d025981f0e
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
6 changed files with 88 additions and 25 deletions

1
Cargo.lock generated
View file

@ -930,6 +930,7 @@ dependencies = [
"reqwest",
"rss",
"serde",
"serde_json",
"serde_yaml",
"toml",
]

View file

@ -17,6 +17,7 @@ ramhorns = "0.14"
toml = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
serde_json = "1.0"
minify-html = "0.11"
minify-js = "0.5"
glob = "0.3"

View file

@ -6,7 +6,11 @@ use ramhorns::Content;
use serde::{Deserialize, Deserializer};
use std::fs;
#[derive(Default, Deserialize, Content, Debug)]
/// Regular markdown files, no metadata
#[derive(Content, Debug, Default, Deserialize)]
pub struct FileNoMetadata {}
#[derive(Content, Debug, Default, Deserialize)]
pub struct FileMetadataBlog {
pub title: Option<String>,
pub date: Option<Date>,
@ -16,7 +20,7 @@ pub struct FileMetadataBlog {
pub toc: Option<bool>,
}
#[derive(Default, Deserialize, Content, Debug)]
#[derive(Content, Debug, Default, Deserialize)]
pub struct FileMetadataContact {
pub title: String,
pub custom: Option<bool>,
@ -26,7 +30,7 @@ pub struct FileMetadataContact {
pub description: Option<String>,
}
#[derive(Default, Deserialize, Content, Debug)]
#[derive(Content, Debug, Default, Deserialize)]
pub struct FileMetadataPortfolio {
pub title: Option<String>,
pub link: Option<String>,
@ -34,9 +38,6 @@ pub struct FileMetadataPortfolio {
pub language: Option<String>,
}
#[derive(Default, Deserialize, Content, Debug)]
pub struct FileMetadataCours {}
pub enum TypeFileMetadata {
Blog,
Contact,
@ -44,12 +45,12 @@ pub enum TypeFileMetadata {
Cours,
}
#[derive(Default, Deserialize, Content, Debug)]
#[derive(Content, Debug, Default, Deserialize)]
pub struct FileMetadata {
pub blog: Option<FileMetadataBlog>,
pub contact: Option<FileMetadataContact>,
pub portfolio: Option<FileMetadataPortfolio>,
pub cours: Option<FileMetadataCours>,
pub cours: Option<FileNoMetadata>,
}
#[derive(Content, Debug, Clone)]
@ -254,7 +255,7 @@ pub fn get_metadata<'a>(root: &'a AstNode<'a>, mtype: TypeFileMetadata) -> FileM
..FileMetadata::default()
},
TypeFileMetadata::Cours => FileMetadata {
cours: Some(FileMetadataCours::default()),
cours: Some(FileNoMetadata::default()),
..FileMetadata::default()
},
},

View file

@ -1,43 +1,91 @@
use std::path::Path;
use actix_web::{get, web, Responder};
use glob::glob;
use ramhorns::Content;
use serde::{Deserialize, Serialize};
use crate::{
config::Config,
misc::{
markdown::{read_file, TypeFileMetadata},
markdown::{read_file, File, TypeFileMetadata},
utils::{make_kw, Html},
},
template::{Infos, NavBar},
};
#[derive(Debug, Deserialize)]
pub struct PathRequest {
q: Option<String>,
}
#[get("/cours")]
async fn page(config: web::Data<Config>) -> impl Responder {
Html(build_page(config.get_ref().to_owned()))
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: Truc, */
filetree: String,
content: Option<File>,
}
/// Get the filetree
fn get_filetree() {
let cours_dir = "data/cours";
glob(&format!("{cours_dir}/*")).unwrap();
#[derive(Serialize)]
struct FileNode {
name: String,
is_dir: bool,
children: Vec<FileNode>,
}
/// Get a page
fn get_page(filename: &str) {
let cours_dir = "data/cours";
/// Build the filetree
fn get_filetree(dir_path: &str, exclusion_list: &[&str]) -> FileNode {
let entries = std::fs::read_dir(dir_path).unwrap();
let post = read_file(&format!("{cours_dir}/{filename}"), TypeFileMetadata::Cours);
let mut children = Vec::new();
for entry in entries.filter_map(Result::ok) {
let entry_path = entry.path();
let entry_name = entry_path.file_name().and_then(|n| n.to_str()).unwrap();
if !exclusion_list.contains(&entry_name) {
let filename = entry_name.to_string();
if entry_path.is_file() {
children.push(FileNode {
name: filename,
is_dir: false,
children: vec![],
});
} else {
children.push(get_filetree(entry_path.to_str().unwrap(), exclusion_list));
}
}
}
FileNode {
name: Path::new(dir_path)
.file_name()
.unwrap()
.to_string_lossy()
.to_string(),
is_dir: true,
children,
}
}
/// Get a page content
fn get_content(cours_dir: &str, path: &web::Query<PathRequest>) -> Option<File> {
let filename = match &path.q {
Some(q) => q,
None => "index.md",
};
read_file(&format!("{cours_dir}/{filename}"), TypeFileMetadata::Cours)
}
// #[once(time = 60)]
// TODO: Uncomment before release
fn build_page(config: Config) -> String {
fn build_page(info: web::Query<PathRequest>, config: Config) -> String {
let cours_dir = "data/cours";
let filetree = get_filetree(cours_dir, &[]);
config.tmpl.render(
"cours.html",
CoursTemplate {
@ -45,6 +93,8 @@ fn build_page(config: Config) -> String {
cours: true,
..NavBar::default()
},
filetree: serde_json::to_string(&filetree).unwrap(),
content: get_content(cours_dir, &info),
},
Infos {
page_title: Some("Cours".into()),

4
static/js/cours.js Normal file
View file

@ -0,0 +1,4 @@
window.addEventListener("load", () => {
/* Ici on va récuperer le JSON envoyer par le serveur et le transformer
* en un jolie filetree */
});

View file

@ -9,9 +9,15 @@
<main>
{{#data}}
<p>Coucou</p>
<aside>
<div id="data" data-json="{{filetree}} "></div>
</aside>
{{/data}}
{{^content}}
<p>Fichier introuvable</p>
{{/content}} {{#content}}
<article>{{&content}}</article>
{{/content}} {{/data}}
</main>
</body>
</html>