Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
Commit eb3cb869 authored by peterrabbit's avatar peterrabbit
Browse files

wip static files manager

parent 9dd20cac
No related branches found
No related tags found
No related merge requests found
......@@ -375,6 +375,8 @@ name = "cms_rust"
version = "0.1.0"
dependencies = [
"actix-web",
"dirs",
"fs_extra",
"regex",
"rustls",
"rustls-pemfile",
......@@ -467,6 +469,26 @@ dependencies = [
"subtle",
]
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "encoding_rs"
version = "0.8.31"
......@@ -508,6 +530,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fs_extra"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
[[package]]
name = "futures-core"
version = "0.3.21"
......@@ -930,6 +958,17 @@ dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall",
"thiserror",
]
[[package]]
name = "regex"
version = "1.6.0"
......@@ -1142,6 +1181,26 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.3.12"
......
......@@ -12,3 +12,5 @@ rustls-pemfile = "1.0.1"
serde = { version = "1.0.143", features = ["derive"] }
serde_json = "1.0.83"
regex = "1.6"
fs_extra = "1.2"
dirs = "4.0"
console.log("Hello from default js")
\ No newline at end of file
body {
font-family: monospace;
}
\ No newline at end of file
mod static_files;
mod website;
use actix_web::{get, App, HttpResponse, HttpServer, Responder};
use static_files::StaticFilesManager;
use std::path::PathBuf;
use website::WebSite;
......@@ -37,6 +39,9 @@ async fn admin_login() -> impl Responder {
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let website = load_website_template();
let site_name = "rust_cms".to_string(); // Get from arg
let mut static_files_manager = StaticFilesManager::new(&site_name).unwrap();
static_files_manager.build_index().unwrap();
// GET HOST AND CERTS DIR FROM CLI ARGUMENT
// Get port from arg, or get context from arg and define default port, or set default port to standard
......@@ -47,17 +52,15 @@ async fn main() -> std::io::Result<()> {
// create the static dir in standard location if doesn't exist (like /var/{sitename}/static)
// create the static files index (like Arc<Mutex<StaticFilesIndex>>)
// create a Rest service at root with extensive path argument: like #[get(/{pth:.*})]
// Then parse the website document and return the corresponding template, or 404 template
let host = "localhost";
let certs_dir = std::path::PathBuf::from("/etc/letsencrypt/live").join(host);
let certs_dir = PathBuf::from("/etc/letsencrypt/live").join(host);
let cert_file =
&mut std::io::BufReader::new(std::fs::File::open(certs_dir.join("fullchain.pem")).unwrap());
let key_file =
&mut std::io::BufReader::new(std::fs::File::open(certs_dir.join("privkey.pem")).unwrap());
let cert = rustls::Certificate(rustls_pemfile::certs(cert_file).unwrap().remove(0).to_vec());
let key = rustls::PrivateKey(
rustls_pemfile::pkcs8_private_keys(key_file)
.unwrap()
......@@ -71,11 +74,15 @@ async fn main() -> std::io::Result<()> {
.with_single_cert(vec![cert], key)
.expect("bad certificate/key");
let static_files_manager =
actix_web::web::Data::new(std::sync::Mutex::new(static_files_manager));
HttpServer::new(move || {
App::new()
.wrap(actix_web::middleware::Logger::default())
.wrap(actix_web::middleware::Compress::default())
.app_data(actix_web::web::Data::new(website.clone()))
.app_data(actix_web::web::Data::clone(&static_files_manager))
.service(admin_dashboard)
.service(admin_login)
.service(page)
......
use std::path::PathBuf;
#[derive(Clone)]
pub struct StaticFilesManager {
index: Vec<String>,
}
impl StaticFilesManager {
fn create_dir_if_missing(app_dir: &PathBuf) -> Result<(), String> {
let static_path = app_dir.join("static");
if !static_path.exists() {
match std::fs::create_dir_all(static_path) {
Ok(_) => return Self::copy_default(&app_dir),
Err(err) => return Err(format!("{}", err)),
}
}
Ok(())
}
fn copy_default(app_dir: &PathBuf) -> Result<(), String> {
let local_default = std::env::current_dir().unwrap().join("default_static");
let standard_default = app_dir.join("static").join("default");
if let Err(err) = std::fs::create_dir_all(&standard_default) {
return Err(format!("{}", err));
}
let mut copy_default_options = fs_extra::dir::CopyOptions::new();
copy_default_options.content_only = true;
if let Err(err) =
fs_extra::dir::copy(local_default, standard_default, &copy_default_options)
{
return Err(format!("{}", err));
};
Ok(())
}
pub fn new(website_name: &String) -> Result<Self, String> {
if let Err(err) = Self::create_dir_if_missing(&dirs::home_dir().unwrap().join(website_name))
{
return Err(err);
}
Ok(StaticFilesManager { index: Vec::new() })
}
pub fn build_index(&mut self) -> Result<(), String> {
self.index.push("TODO".to_string());
Ok(())
}
}
......@@ -18,26 +18,28 @@ pub struct PageData {
pub struct HtmlDoc(String);
impl HtmlDoc {
pub fn from_page_data(page_data: &PageData) -> Self {
let html_doc = std::fs::read_to_string(
fn load_template() -> String {
std::fs::read_to_string(
std::env::current_dir()
.unwrap()
.join("templates")
.join("html_doc.html"),
)
.expect("Missing html_doc template");
.expect("Missing html_doc template")
}
pub fn from_page_data(page_data: &PageData) -> Self {
let re = Regex::new(r#"\{[a-z]+\}"#).unwrap();
let html_doc = re
.replace_all(&html_doc, |captures: &Captures| {
let html = re
.replace_all(&HtmlDoc::load_template(), |captures: &Captures| {
let placeholder = captures.iter().next().unwrap().unwrap().as_str();
let placeholder = placeholder[1..placeholder.len() - 1].to_owned();
page_data.field_from_str_key(placeholder)
})
.to_string();
HtmlDoc(html_doc)
HtmlDoc(html)
}
pub fn to_string(&self) -> String {
......@@ -146,11 +148,11 @@ mod test_website {
\"sub_pages\": [
{
\"page_data\": {
\"title\": \"Another page\",
\"title\": \"Nested page\",
\"lang\": \"en\",
\"slug\": \"otherpage\",
\"description\": \"Another testing page\",
\"html_body\": \"<h1>Another page</h1>\"
\"slug\": \"nested\",
\"description\": \"Nested testing page\",
\"html_body\": \"<h1>Nested page</h1>\"
}
}
]
......@@ -167,9 +169,14 @@ mod test_website {
let root_page = root_page.unwrap();
assert_eq!(root_page.page_data.html_body, "<h1>Test Website</h1>");
let sub_page = website.get_page_by_url(&PathBuf::from("/subpage"));
let sub_page = website.get_page_by_url(&PathBuf::from("subpage"));
assert!(sub_page.is_some());
let sub_page = sub_page.unwrap();
assert_eq!(sub_page.page_data.html_body, "<h1>A sub page</h1>");
let nested_page = website.get_page_by_url(&PathBuf::from("subpage/nested"));
assert!(nested_page.is_some());
let nested_page = nested_page.unwrap();
assert_eq!(nested_page.page_data.html_body, "<h1>Nested page</h1>");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment