hot reload memcache
This commit is contained in:
parent
0b293d0550
commit
0e20b1d53c
5 changed files with 638 additions and 35 deletions
292
Cargo.lock
generated
292
Cargo.lock
generated
|
@ -17,6 +17,18 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
|
@ -41,6 +53,18 @@ dependencies = [
|
|||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "arraydeque"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
|
||||
|
||||
[[package]]
|
||||
name = "askama"
|
||||
version = "0.12.1"
|
||||
|
@ -225,6 +249,15 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -272,13 +305,17 @@ dependencies = [
|
|||
"askama_axum",
|
||||
"axum",
|
||||
"axum-server-timing",
|
||||
"gray_matter",
|
||||
"markdown",
|
||||
"notify",
|
||||
"serde",
|
||||
"syntect",
|
||||
"tokio",
|
||||
"tower 0.5.1",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -321,6 +358,30 @@ version = "0.8.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.25"
|
||||
|
@ -424,6 +485,43 @@ version = "0.28.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "gray_matter"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31ee6a6070bad7c953b0c8be9367e9372181fed69f3e026c4eb5160d8b3c0222"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"yaml-rust2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
|
@ -527,6 +625,16 @@ dependencies = [
|
|||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.6"
|
||||
|
@ -621,6 +729,12 @@ dependencies = [
|
|||
"redox_syscall 0.5.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
|
@ -761,6 +875,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
|
@ -785,6 +905,28 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "6.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"onig_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig_sys"
|
||||
version = "69.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -858,6 +1000,25 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"indexmap",
|
||||
"quick-xml",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
|
@ -867,6 +1028,15 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
|
@ -1090,6 +1260,48 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
||||
|
||||
[[package]]
|
||||
name = "syntect"
|
||||
version = "5.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags 1.3.2",
|
||||
"flate2",
|
||||
"fnv",
|
||||
"once_cell",
|
||||
"onig",
|
||||
"plist",
|
||||
"regex-syntax 0.8.2",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.7"
|
||||
|
@ -1100,6 +1312,37 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.41.0"
|
||||
|
@ -1142,6 +1385,15 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
|
@ -1516,6 +1768,46 @@ version = "0.52.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust2"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8"
|
||||
dependencies = [
|
||||
"arraydeque",
|
||||
"encoding_rs",
|
||||
"hashlink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.0"
|
||||
|
|
|
@ -10,10 +10,14 @@ askama = { version = "0.12.1", features = ["with-axum"] }
|
|||
askama_axum = "0.4.0"
|
||||
axum = "0.7.7"
|
||||
axum-server-timing = "1.0.1"
|
||||
gray_matter = "0.2.8"
|
||||
markdown = "1.0.0-alpha.21"
|
||||
notify = "6.1.1"
|
||||
serde = { version = "1.0.213", features = ["derive"] }
|
||||
syntect = "5.2.0"
|
||||
tokio = { version = "1.41.0", features = ["full"] }
|
||||
tower = "0.5.1"
|
||||
tower-http = { version = "0.6.1", features = ["full"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
walkdir = "2.5.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- name: cbax dev deploy
|
||||
hosts:
|
||||
containers:
|
||||
'{{ lookup("env", "ANSIBLE_HOST") }}':
|
||||
ansible_user: '{{ lookup("env", "ANSIBLE_USER") }}'
|
||||
ansible_password: '{{ lookup("env", "ANSIBLE_PASSWORD") }}'
|
||||
tasks:
|
||||
|
|
17
posts/test_post.md
Normal file
17
posts/test_post.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
title: "Test markdown post"
|
||||
author: "cbax"
|
||||
description: "Only a test post"
|
||||
img_path: "/res/img/posts/testing.png"
|
||||
canonical_url: "//cbax.dev/blog/testing"
|
||||
---
|
||||
|
||||
# This is a test
|
||||
## h2
|
||||
|
||||
testing testing testing
|
||||
|
||||
> quote me!
|
||||
```bash
|
||||
cat lol | ripgrep "test"
|
||||
```
|
358
src/main.rs
358
src/main.rs
|
@ -1,6 +1,6 @@
|
|||
use std::io::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::{collections::HashMap, fs::File};
|
||||
|
||||
use askama::Template;
|
||||
use axum::extract::{Path, State};
|
||||
|
@ -10,9 +10,13 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use gray_matter::engine::YAML;
|
||||
use gray_matter::Matter;
|
||||
use notify::{RecursiveMode, Watcher};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::services::ServeDir;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::Instrument;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -77,7 +81,8 @@ struct BlogPostTemplate {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
posts: Arc<RwLock<HashMap<String, Post>>>,
|
||||
posts: HashMap<String, Post>,
|
||||
styles: HashMap<String, String>,
|
||||
}
|
||||
|
||||
struct HtmlTemplate<T>(T);
|
||||
|
@ -98,14 +103,52 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
async fn blog(State(state): State<AppState>) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles_file = File::open("static/css/styles.css").expect("Failed to open stylesheet.");
|
||||
let mut styles = String::new();
|
||||
styles_file
|
||||
.read_to_string(&mut styles)
|
||||
.expect("Failed to read stylesheet.");
|
||||
async fn blog(State(state): State<Arc<RwLock<AppState>>>) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles: String = state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("core.css")
|
||||
.unwrap()
|
||||
.clone();
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("nord.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("colors.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("components.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("font.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let mut posts: Vec<(String, Meta)> = vec![];
|
||||
for (slug, post) in state.posts.read().unwrap().clone().iter() {
|
||||
for (slug, post) in state.read().unwrap().posts.clone().iter() {
|
||||
posts.push((slug.clone(), post.meta.clone()));
|
||||
}
|
||||
let meta = Meta {
|
||||
|
@ -128,15 +171,53 @@ async fn blog(State(state): State<AppState>) -> Result<impl IntoResponse, Status
|
|||
}
|
||||
|
||||
async fn blog_post(
|
||||
State(state): State<AppState>,
|
||||
State(state): State<Arc<RwLock<AppState>>>,
|
||||
Path(post_slug): Path<String>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles_file = File::open("static/css/styles.css").expect("Failed to open stylesheet.");
|
||||
let mut styles = String::new();
|
||||
styles_file
|
||||
.read_to_string(&mut styles)
|
||||
.expect("Failed to read stylesheet.");
|
||||
if let Some(post) = state.posts.read().unwrap().clone().get(&post_slug) {
|
||||
let mut styles: String = state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("core.css")
|
||||
.unwrap()
|
||||
.clone();
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("nord.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("colors.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("components.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("font.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
if let Some(post) = state.read().unwrap().posts.clone().get(&post_slug) {
|
||||
let meta = post.meta.clone();
|
||||
let template = BlogPostTemplate {
|
||||
_parent: BaseTemplate {
|
||||
|
@ -152,22 +233,102 @@ async fn blog_post(
|
|||
return Err(StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
async fn homelab() -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles_file = File::open("static/css/styles.css").expect("Failed to open stylesheet.");
|
||||
let mut styles = String::new();
|
||||
styles_file
|
||||
.read_to_string(&mut styles)
|
||||
.expect("Failed to read stylesheet.");
|
||||
async fn homelab(
|
||||
State(state): State<Arc<RwLock<AppState>>>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles: String = state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("core.css")
|
||||
.unwrap()
|
||||
.clone();
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("nord.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("colors.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("components.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("font.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let template = HomelabTemplate { styles };
|
||||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
||||
async fn index() -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles_file = File::open("static/css/styles.css").expect("Failed to open stylesheet.");
|
||||
let mut styles = String::new();
|
||||
styles_file
|
||||
.read_to_string(&mut styles)
|
||||
.expect("Failed to read stylesheet.");
|
||||
async fn index(
|
||||
State(state): State<Arc<RwLock<AppState>>>,
|
||||
) -> Result<impl IntoResponse, StatusCode> {
|
||||
let mut styles: String = state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("core.css")
|
||||
.unwrap()
|
||||
.clone();
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("nord.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("colors.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("components.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
styles.push_str(
|
||||
state
|
||||
.read()
|
||||
.unwrap()
|
||||
.styles
|
||||
.get("font.css")
|
||||
.unwrap()
|
||||
.as_str(),
|
||||
);
|
||||
let template = IndexTemplate { styles };
|
||||
return Ok(HtmlTemplate(template));
|
||||
}
|
||||
|
@ -185,10 +346,11 @@ async fn main() {
|
|||
)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
let state = AppState {
|
||||
posts: Arc::new(RwLock::new(HashMap::new())),
|
||||
};
|
||||
state.posts.write().unwrap().insert(
|
||||
let state = Arc::new(RwLock::new(AppState {
|
||||
posts: HashMap::new(),
|
||||
styles: HashMap::new(),
|
||||
}));
|
||||
state.write().unwrap().posts.insert(
|
||||
"test_slug".into(),
|
||||
Post {
|
||||
meta: Meta {
|
||||
|
@ -202,12 +364,140 @@ async fn main() {
|
|||
body: "this is a test post!".into(),
|
||||
},
|
||||
);
|
||||
for entry in walkdir::WalkDir::new("./posts") {
|
||||
let entry = entry.unwrap();
|
||||
if entry.file_type().is_file() {
|
||||
let path = entry.into_path();
|
||||
let file: String = std::fs::read_to_string(&path).unwrap();
|
||||
let matter = Matter::<YAML>::new();
|
||||
let matter_result = matter.parse(file.as_str());
|
||||
let meta = Meta {
|
||||
title: matter_result.data.as_ref().unwrap()["title"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
author: matter_result.data.as_ref().unwrap()["author"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
description: matter_result.data.as_ref().unwrap()["description"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
img_path: matter_result.data.as_ref().unwrap()["img_path"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
canonical_url: matter_result.data.as_ref().unwrap()["canonical_url"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
state.write().unwrap().posts.insert(
|
||||
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||
Post {
|
||||
meta,
|
||||
cover_img_path: String::new(),
|
||||
body: markdown::to_html_with_options(
|
||||
matter_result.content.as_str(),
|
||||
&markdown::Options::gfm(),
|
||||
)
|
||||
.unwrap(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
for entry in walkdir::WalkDir::new("./static/css") {
|
||||
let entry = entry.unwrap();
|
||||
if entry.file_type().is_file() {
|
||||
let path = entry.into_path();
|
||||
let file: String = std::fs::read_to_string(&path).unwrap();
|
||||
state.write().unwrap().styles.insert(
|
||||
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||
file,
|
||||
);
|
||||
}
|
||||
}
|
||||
let notify_state1 = state.clone();
|
||||
let notify_state2 = state.clone();
|
||||
let mut css_watcher =
|
||||
notify::recommended_watcher(move |res: Result<notify::Event, notify::Error>| match res {
|
||||
Ok(event) => {
|
||||
println!("event triggered: {:?}", event);
|
||||
if event.kind.is_create() || event.kind.is_modify() {
|
||||
for path in event.paths.iter() {
|
||||
println!("refreshing css: {}", path.to_string_lossy());
|
||||
let file: String = std::fs::read_to_string(&path).unwrap();
|
||||
notify_state1.clone().write().unwrap().styles.insert(
|
||||
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||
file,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("watch error: {:?}", e),
|
||||
})
|
||||
.unwrap();
|
||||
let mut post_watcher =
|
||||
notify::recommended_watcher(move |res: Result<notify::Event, notify::Error>| match res {
|
||||
Ok(mut event) => {
|
||||
if event.kind.is_create() || event.kind.is_modify() {
|
||||
event.paths.dedup();
|
||||
for path in event.paths.iter().filter(|p| {
|
||||
if p.extension().is_some() {
|
||||
p.extension().unwrap() == "md"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
println!("refreshing post: {}", path.to_string_lossy().to_string());
|
||||
std::thread::sleep(std::time::Duration::from_millis(1));
|
||||
let file: String =
|
||||
std::fs::read_to_string(path.to_string_lossy().to_string()).unwrap();
|
||||
let matter = Matter::<YAML>::new();
|
||||
let matter_result = matter.parse(file.as_str());
|
||||
let meta = Meta {
|
||||
title: matter_result.data.as_ref().unwrap()["title"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
author: matter_result.data.as_ref().unwrap()["author"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
description: matter_result.data.as_ref().unwrap()["description"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
img_path: matter_result.data.as_ref().unwrap()["img_path"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
canonical_url: matter_result.data.as_ref().unwrap()["canonical_url"]
|
||||
.as_string()
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
notify_state2.clone().write().unwrap().posts.insert(
|
||||
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||
Post {
|
||||
meta,
|
||||
cover_img_path: String::new(),
|
||||
body: markdown::to_html_with_options(
|
||||
matter_result.content.as_str(),
|
||||
&markdown::Options::gfm(),
|
||||
)
|
||||
.unwrap(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("watch error: {:?}", e),
|
||||
})
|
||||
.unwrap();
|
||||
css_watcher
|
||||
.watch(std::path::Path::new("static/css"), RecursiveMode::Recursive)
|
||||
.unwrap();
|
||||
post_watcher
|
||||
.watch(std::path::Path::new("posts"), RecursiveMode::Recursive)
|
||||
.unwrap();
|
||||
let app = Router::new()
|
||||
.route("/", get(index))
|
||||
.route("/homelab", get(homelab))
|
||||
.route("/blog", get(blog))
|
||||
.route("/blog/:post_slug", get(blog_post))
|
||||
.with_state(state)
|
||||
.with_state(state.clone())
|
||||
.fallback_service(serve_dir())
|
||||
.layer(axum_server_timing::ServerTimingLayer::new("Axum"))
|
||||
.layer(ServiceBuilder::new().layer(TraceLayer::new_for_http()));
|
||||
|
|
Loading…
Reference in a new issue