about summary refs log tree commit diff
path: root/splorm/src/handler
diff options
context:
space:
mode:
Diffstat (limited to 'splorm/src/handler')
-rw-r--r--splorm/src/handler/api.rs43
-rw-r--r--splorm/src/handler/mod.rs11
-rw-r--r--splorm/src/handler/templated.rs19
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()