on Lua
This commit is contained in:
parent
ebb4543f8d
commit
b6e803cfee
11 changed files with 162 additions and 30 deletions
|
@ -343,7 +343,7 @@ impl Generator {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn generate(paths: &Paths<'_>) -> anyhow::Result<Treehouse> {
|
||||
pub fn generate(paths: &Paths<'_>) -> anyhow::Result<(Config, Treehouse)> {
|
||||
let start = Instant::now();
|
||||
|
||||
info!("loading config");
|
||||
|
@ -386,13 +386,13 @@ pub fn generate(paths: &Paths<'_>) -> anyhow::Result<Treehouse> {
|
|||
info!("generation done in {duration:?}");
|
||||
|
||||
if !treehouse.has_errors() {
|
||||
Ok(treehouse)
|
||||
Ok((config, treehouse))
|
||||
} else {
|
||||
bail!("generation errors occurred; diagnostics were emitted with detailed descriptions");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn regenerate_or_report_error(paths: &Paths<'_>) -> anyhow::Result<Treehouse> {
|
||||
pub fn regenerate_or_report_error(paths: &Paths<'_>) -> anyhow::Result<(Config, Treehouse)> {
|
||||
info!("regenerating site content");
|
||||
|
||||
let result = generate(paths);
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#[cfg(debug_assertions)]
|
||||
mod live_reload;
|
||||
|
||||
use std::{borrow::Cow, net::Ipv4Addr, path::PathBuf, sync::Arc};
|
||||
use std::{net::Ipv4Addr, path::PathBuf, sync::Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
use axum::{
|
||||
extract::{Path, RawQuery, State},
|
||||
http::{header::CONTENT_TYPE, HeaderValue, StatusCode},
|
||||
http::{
|
||||
header::{CONTENT_TYPE, LOCATION},
|
||||
HeaderValue, StatusCode,
|
||||
},
|
||||
response::{Html, IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
|
@ -15,7 +18,10 @@ use log::{error, info};
|
|||
use pulldown_cmark::escape::escape_html;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use crate::state::{Source, Treehouse};
|
||||
use crate::{
|
||||
config::Config,
|
||||
state::{Source, Treehouse},
|
||||
};
|
||||
|
||||
use super::Paths;
|
||||
|
||||
|
@ -29,12 +35,18 @@ struct SystemPages {
|
|||
}
|
||||
|
||||
struct Server {
|
||||
config: Config,
|
||||
treehouse: Treehouse,
|
||||
target_dir: PathBuf,
|
||||
system_pages: SystemPages,
|
||||
}
|
||||
|
||||
pub async fn serve(treehouse: Treehouse, paths: &Paths<'_>, port: u16) -> anyhow::Result<()> {
|
||||
pub async fn serve(
|
||||
config: Config,
|
||||
treehouse: Treehouse,
|
||||
paths: &Paths<'_>,
|
||||
port: u16,
|
||||
) -> anyhow::Result<()> {
|
||||
let app = Router::new()
|
||||
.route("/", get(index))
|
||||
.route("/*page", get(page))
|
||||
|
@ -44,6 +56,7 @@ pub async fn serve(treehouse: Treehouse, paths: &Paths<'_>, port: u16) -> anyhow
|
|||
.route("/static/*file", get(static_file))
|
||||
.fallback(get(four_oh_four))
|
||||
.with_state(Arc::new(Server {
|
||||
config,
|
||||
treehouse,
|
||||
target_dir: paths.target_dir.to_owned(),
|
||||
system_pages: SystemPages {
|
||||
|
@ -114,13 +127,17 @@ async fn static_file(Path(path): Path<String>, State(state): State<Arc<Server>>)
|
|||
}
|
||||
|
||||
async fn page(Path(path): Path<String>, State(state): State<Arc<Server>>) -> Response {
|
||||
let path = if !path.ends_with(".html") {
|
||||
Cow::Owned(path + ".html")
|
||||
} else {
|
||||
Cow::Borrowed(&path)
|
||||
};
|
||||
let bare_path = path.strip_suffix(".html").unwrap_or(&path);
|
||||
if let Some(redirected_path) = state.config.redirects.page.get(bare_path) {
|
||||
return (
|
||||
StatusCode::MOVED_PERMANENTLY,
|
||||
[(LOCATION, format!("{}/{redirected_path}", state.config.site))],
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
|
||||
if let Ok(file) = tokio::fs::read(state.target_dir.join(&*path)).await {
|
||||
let html_path = format!("{bare_path}.html");
|
||||
if let Ok(file) = tokio::fs::read(state.target_dir.join(&*html_path)).await {
|
||||
([(CONTENT_TYPE, "text/html")], file).into_response()
|
||||
} else {
|
||||
four_oh_four(State(state)).await
|
||||
|
|
|
@ -17,6 +17,26 @@ pub struct Config {
|
|||
/// Links exported to Markdown for use with reference syntax `[text][def:key]`.
|
||||
pub defs: HashMap<String, String>,
|
||||
|
||||
/// Redirects for moving pages around. These are used solely by the treehouse server.
|
||||
///
|
||||
/// Note that redirects are only resolved _non-recursively_ by the server. For a configuration
|
||||
/// like:
|
||||
///
|
||||
/// ```toml
|
||||
/// page.redirects.foo = "bar"
|
||||
/// page.redirects.bar = "baz"
|
||||
/// ```
|
||||
///
|
||||
/// the user will be redirected from `foo` to `bar`, then from `bar` to `baz`. This isn't
|
||||
/// optimal for UX and causes unnecessary latency. Therefore you should always make redirects
|
||||
/// point to the newest version of the page.
|
||||
///
|
||||
/// ```toml
|
||||
/// page.redirects.foo = "baz"
|
||||
/// page.redirects.bar = "baz"
|
||||
/// ```
|
||||
pub redirects: Redirects,
|
||||
|
||||
/// Overrides for emoji filenames. Useful for setting up aliases.
|
||||
///
|
||||
/// On top of this, emojis are autodiscovered by walking the `static/emoji` directory.
|
||||
|
@ -30,6 +50,13 @@ pub struct Config {
|
|||
pub pics: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct Redirects {
|
||||
/// Page redirects. When a user navigates to a page, if they navigate to `url`, they will
|
||||
/// be redirected to `page[url]`.
|
||||
pub page: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load(path: &Path) -> anyhow::Result<Self> {
|
||||
let string = std::fs::read_to_string(path).context("cannot read config file")?;
|
||||
|
|
|
@ -42,8 +42,8 @@ async fn fallible_main() -> anyhow::Result<()> {
|
|||
generate: _,
|
||||
serve: serve_args,
|
||||
} => {
|
||||
let treehouse = regenerate_or_report_error(&paths)?;
|
||||
serve(treehouse, &paths, serve_args.port).await?;
|
||||
let (config, treehouse) = regenerate_or_report_error(&paths)?;
|
||||
serve(config, treehouse, &paths, serve_args.port).await?;
|
||||
}
|
||||
|
||||
Command::Fix(fix_args) => fix_file_cli(fix_args)?,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue