From a9e2f67b3ff95619b79976c357af3875ffb156e9 Mon Sep 17 00:00:00 2001 From: Per Stark Date: Fri, 24 Jan 2025 10:51:45 +0100 Subject: [PATCH] feat: visitors and load analytics middleware --- src/bin/server.rs | 5 +++- src/server/middleware_analytics.rs | 33 +++++++++++++++++++++++++++ src/server/mod.rs | 1 + src/server/routes/html/admin_panel.rs | 4 +--- src/server/routes/html/signup.rs | 2 -- src/storage/types/analytics.rs | 1 - 6 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/server/middleware_analytics.rs diff --git a/src/bin/server.rs b/src/bin/server.rs index 162ce6d..cab19b6 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -17,6 +17,7 @@ use tracing_subscriber::{fmt, prelude::*, EnvFilter}; use zettle_db::{ ingress::jobqueue::JobQueue, server::{ + middleware_analytics::analytics_middleware, middleware_api_auth::api_auth, routes::{ api::{ @@ -122,6 +123,7 @@ async fn main() -> Result<(), Box> { session_store, auth_config, app_state.surreal_db_client.client.clone(), + &app_state, ), ) .with_state(app_state); @@ -148,11 +150,11 @@ fn api_routes_v1(app_state: &AppState) -> Router { } /// Router for HTML endpoints -/// fn html_routes( session_store: SessionStore>, auth_config: AuthConfig, db_client: Surreal, + app_state: &AppState, ) -> Router { Router::new() .route("/", get(index_handler)) @@ -178,6 +180,7 @@ fn html_routes( .route("/documentation", get(show_documentation_index)) .route("/documentation/privacy-policy", get(show_privacy_policy)) .nest_service("/assets", ServeDir::new("assets/")) + .layer(from_fn_with_state(app_state.clone(), analytics_middleware)) .layer( AuthSessionLayer::, Surreal>::new(Some( db_client, diff --git a/src/server/middleware_analytics.rs b/src/server/middleware_analytics.rs new file mode 100644 index 0000000..fda992d --- /dev/null +++ b/src/server/middleware_analytics.rs @@ -0,0 +1,33 @@ +use axum::{ + extract::{Request, State}, + middleware::Next, + response::Response, +}; +use axum_session_surreal::SessionSurrealPool; +use surrealdb::engine::any::Any; + +use crate::storage::types::analytics::Analytics; + +use super::AppState; + +pub async fn analytics_middleware( + State(state): State, + session: axum_session::Session>, + request: Request, + next: Next, +) -> Response { + // Get the path from the request + let path = request.uri().path(); + + // Only count if it's a main page request (not assets or other resources) + if !path.starts_with("/assets") && !path.starts_with("/_next") && !path.contains('.') { + if !session.get::("counted_visitor").unwrap_or(false) { + let _ = Analytics::increment_visitors(&state.surreal_db_client).await; + session.set("counted_visitor", true); + } + + let _ = Analytics::increment_page_loads(&state.surreal_db_client).await; + } + + next.run(request).await +} diff --git a/src/server/mod.rs b/src/server/mod.rs index ebe109b..3b6b92f 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -4,6 +4,7 @@ use crate::utils::mailer::Mailer; use minijinja_autoreload::AutoReloader; use std::sync::Arc; +pub mod middleware_analytics; pub mod middleware_api_auth; pub mod routes; diff --git a/src/server/routes/html/admin_panel.rs b/src/server/routes/html/admin_panel.rs index b4a91e4..a9c3c10 100644 --- a/src/server/routes/html/admin_panel.rs +++ b/src/server/routes/html/admin_panel.rs @@ -1,15 +1,13 @@ use axum::{ extract::State, - http::{StatusCode, Uri}, response::{IntoResponse, Redirect}, }; -use axum_htmx::HxRedirect; use axum_session_auth::AuthSession; use axum_session_surreal::SessionSurrealPool; use surrealdb::{engine::any::Any, Surreal}; use crate::{ - error::{AppError, HtmlError}, + error::HtmlError, page_data, server::{routes::html::render_template, AppState}, storage::types::{analytics::Analytics, system_settings::SystemSettings, user::User}, diff --git a/src/server/routes/html/signup.rs b/src/server/routes/html/signup.rs index 4066200..3aad748 100644 --- a/src/server/routes/html/signup.rs +++ b/src/server/routes/html/signup.rs @@ -7,10 +7,8 @@ use axum::{ use axum_htmx::{HxBoosted, HxRedirect}; use axum_session_auth::AuthSession; use axum_session_surreal::SessionSurrealPool; -use chrono::RoundingError; use serde::{Deserialize, Serialize}; use surrealdb::{engine::any::Any, Surreal}; -use tracing::info; use crate::{error::HtmlError, server::AppState, storage::types::user::User}; diff --git a/src/storage/types/analytics.rs b/src/storage/types/analytics.rs index 5ee97e4..43dee3a 100644 --- a/src/storage/types/analytics.rs +++ b/src/storage/types/analytics.rs @@ -1,6 +1,5 @@ use crate::storage::types::{file_info::deserialize_flexible_id, user::User, StoredObject}; use serde::{Deserialize, Serialize}; -use tracing::info; use crate::{error::AppError, storage::db::SurrealDbClient};