diff options
| author | gennyble <gen@nyble.dev> | 2026-09-24 01:52:48 -0500 |
|---|---|---|
| committer | gennyble <gen@nyble.dev> | 2026-09-24 01:52:48 -0500 |
| commit | f2a9bc39cb9aa8a9d9e186bfd71dfd2405fe1ab6 (patch) | |
| tree | 9a5fdc35930ce7d0a039fe5eae154555cf0231fb /splorm/src/handler | |
| parent | 32cbf8332bdaafae8c0934ff2ab45048bc8f2361 (diff) | |
splorm, meow
Diffstat (limited to 'splorm/src/handler')
| -rw-r--r-- | splorm/src/handler/api.rs | 43 | ||||
| -rw-r--r-- | splorm/src/handler/mod.rs | 11 | ||||
| -rw-r--r-- | splorm/src/handler/templated.rs | 19 |
3 files changed, 67 insertions, 6 deletions
diff --git a/splorm/src/handler/api.rs b/splorm/src/handler/api.rs new file mode 100644 index 0000000..f360b87 --- /dev/null +++ b/splorm/src/handler/api.rs @@ -0,0 +1,43 @@ +use axum::{ + Router, + body::Body, + extract::{Path, State}, + response::Response, + routing::get, +}; +use sessionhash::RequestContext; + +use crate::{RuntimeError, fs, state::SplormState}; + +pub fn routes() -> Router<SplormState> { + Router::new().route("/stats/now/{name}", get(stats)) +} + +async fn stats( + Path(name): Path<String>, + State(state): State<SplormState>, + ctx: RequestContext, +) -> Result<Response, RuntimeError> { + tracing::trace!("{ctx} GET /api/stats/{name}"); + + let graphs = { + let mut connector = state.gatherer_thread().await; + connector.regular_graphs().await + }; + + let file_path = match name.as_str() { + "current_hostmeminfo.gif" => graphs.meminfo, + "current_hostnetinfo.gif" => graphs.meminfo, + "current_hostcpuinfo.gif" => graphs.cpuinfo, + _ => return Err(RuntimeError::generic_404()), + }; + + tracing::trace!("graph {name} system_path={file_path}"); + let file = fs::unsafe_read_file(file_path).await?; + + Response::builder() + .header("content-type", "image/gif") + .status(200) + .body(Body::from(file)) + .map_err(|_| RuntimeError::Unknown) +} diff --git a/splorm/src/handler/mod.rs b/splorm/src/handler/mod.rs index 95c7e00..edf86f9 100644 --- a/splorm/src/handler/mod.rs +++ b/splorm/src/handler/mod.rs @@ -3,16 +3,17 @@ use std::sync::Arc; use axum::{ Extension, RequestExt, body::Body, - extract::{Path, Request}, + extract::{Path, Request, State}, middleware::Next, response::Response, }; use sessionhash::RequestContext; +pub mod api; mod staticfile; mod templated; -use crate::{RuntimeError, config::Settings, fs::RequestPath}; +use crate::{RuntimeError, config::Settings, fs::RequestPath, state::SplormState}; /// Log runtime errors using a middleware layer. Very much based on the [axum /// error_handling example][axum_errorhandling] @@ -32,16 +33,18 @@ pub async fn log_errors(mut request: Request, next: Next) -> Response { /// GET / pub async fn index( + State(state): State<SplormState>, Extension(settings): Extension<Settings>, ctx: RequestContext, ) -> Result<Response, RuntimeError> { tracing::info!("{ctx} GET /"); let rqp = RequestPath::verify_safe(settings.root(), "home.html")?; - templated::send_file(rqp, &settings).await + templated::send_file(rqp, state, &settings).await } /// GET /{*path} pub async fn static_path( + State(state): State<SplormState>, Extension(settings): Extension<Settings>, Path(path): Path<String>, ctx: RequestContext, @@ -55,7 +58,7 @@ pub async fn static_path( if rqp.guess_mime().as_ref() == "text/html" { tracing::info!("{ctx} GET /{path}"); - templated::send_file(rqp, &settings).await + templated::send_file(rqp, state, &settings).await } else { staticfile::send_or_stream_file(rqp).await } diff --git a/splorm/src/handler/templated.rs b/splorm/src/handler/templated.rs index 4a5fa62..dee93ba 100644 --- a/splorm/src/handler/templated.rs +++ b/splorm/src/handler/templated.rs @@ -8,15 +8,25 @@ use crate::{ RuntimeError, config::Settings, fs::{self, RequestPath, SafePathBuf}, + state::SplormState, templated::TemplateVariables, }; -pub async fn send_file(path: RequestPath, settings: &Settings) -> Result<Response, RuntimeError> { +pub async fn send_file( + path: RequestPath, + state: SplormState, + settings: &Settings, +) -> Result<Response, RuntimeError> { let safe = path.system_path().to_owned(); let string = fs::read_file_to_string(path.system_path()).await?; let template = Templated::from_str(&string) .map_err(|_| RuntimeError::not_a_template(path.system_path().to_path_buf()))?; let tvars = TemplateVariables::build(safe.as_path(), &template.frontmatter); + tracing::trace!( + "page {} has features {:?}", + path.web_path(), + tvars.features() + ); let pt_path = match tvars.template() { Some(name) => { @@ -40,7 +50,12 @@ pub async fn send_file(path: RequestPath, settings: &Settings) -> Result<Respons tvars.apply_pathnav(&mut page_template, &path); tvars.apply_opengraph(&mut page_template, &settings, &path); - let content = tvars.apply_markup(&mut page_template, template.content); + let mut content = template.content; + if !tvars.features().is_empty() { + content = tvars.apply_features(content, &state).await; + } + + let content = tvars.apply_markup(&mut page_template, content); page_template.set("main", content); Response::builder() |
