mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-23 01:08:33 +02:00
feat: visitors and load analytics middleware
This commit is contained in:
@@ -17,6 +17,7 @@ use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
|||||||
use zettle_db::{
|
use zettle_db::{
|
||||||
ingress::jobqueue::JobQueue,
|
ingress::jobqueue::JobQueue,
|
||||||
server::{
|
server::{
|
||||||
|
middleware_analytics::analytics_middleware,
|
||||||
middleware_api_auth::api_auth,
|
middleware_api_auth::api_auth,
|
||||||
routes::{
|
routes::{
|
||||||
api::{
|
api::{
|
||||||
@@ -122,6 +123,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
session_store,
|
session_store,
|
||||||
auth_config,
|
auth_config,
|
||||||
app_state.surreal_db_client.client.clone(),
|
app_state.surreal_db_client.client.clone(),
|
||||||
|
&app_state,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.with_state(app_state);
|
.with_state(app_state);
|
||||||
@@ -148,11 +150,11 @@ fn api_routes_v1(app_state: &AppState) -> Router<AppState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Router for HTML endpoints
|
/// Router for HTML endpoints
|
||||||
///
|
|
||||||
fn html_routes(
|
fn html_routes(
|
||||||
session_store: SessionStore<SessionSurrealPool<Any>>,
|
session_store: SessionStore<SessionSurrealPool<Any>>,
|
||||||
auth_config: AuthConfig<String>,
|
auth_config: AuthConfig<String>,
|
||||||
db_client: Surreal<Any>,
|
db_client: Surreal<Any>,
|
||||||
|
app_state: &AppState,
|
||||||
) -> Router<AppState> {
|
) -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(index_handler))
|
.route("/", get(index_handler))
|
||||||
@@ -178,6 +180,7 @@ fn html_routes(
|
|||||||
.route("/documentation", get(show_documentation_index))
|
.route("/documentation", get(show_documentation_index))
|
||||||
.route("/documentation/privacy-policy", get(show_privacy_policy))
|
.route("/documentation/privacy-policy", get(show_privacy_policy))
|
||||||
.nest_service("/assets", ServeDir::new("assets/"))
|
.nest_service("/assets", ServeDir::new("assets/"))
|
||||||
|
.layer(from_fn_with_state(app_state.clone(), analytics_middleware))
|
||||||
.layer(
|
.layer(
|
||||||
AuthSessionLayer::<User, String, SessionSurrealPool<Any>, Surreal<Any>>::new(Some(
|
AuthSessionLayer::<User, String, SessionSurrealPool<Any>, Surreal<Any>>::new(Some(
|
||||||
db_client,
|
db_client,
|
||||||
|
|||||||
33
src/server/middleware_analytics.rs
Normal file
33
src/server/middleware_analytics.rs
Normal file
@@ -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<AppState>,
|
||||||
|
session: axum_session::Session<SessionSurrealPool<Any>>,
|
||||||
|
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::<bool>("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
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ use crate::utils::mailer::Mailer;
|
|||||||
use minijinja_autoreload::AutoReloader;
|
use minijinja_autoreload::AutoReloader;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub mod middleware_analytics;
|
||||||
pub mod middleware_api_auth;
|
pub mod middleware_api_auth;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::State,
|
extract::State,
|
||||||
http::{StatusCode, Uri},
|
|
||||||
response::{IntoResponse, Redirect},
|
response::{IntoResponse, Redirect},
|
||||||
};
|
};
|
||||||
use axum_htmx::HxRedirect;
|
|
||||||
use axum_session_auth::AuthSession;
|
use axum_session_auth::AuthSession;
|
||||||
use axum_session_surreal::SessionSurrealPool;
|
use axum_session_surreal::SessionSurrealPool;
|
||||||
use surrealdb::{engine::any::Any, Surreal};
|
use surrealdb::{engine::any::Any, Surreal};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{AppError, HtmlError},
|
error::HtmlError,
|
||||||
page_data,
|
page_data,
|
||||||
server::{routes::html::render_template, AppState},
|
server::{routes::html::render_template, AppState},
|
||||||
storage::types::{analytics::Analytics, system_settings::SystemSettings, user::User},
|
storage::types::{analytics::Analytics, system_settings::SystemSettings, user::User},
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ use axum::{
|
|||||||
use axum_htmx::{HxBoosted, HxRedirect};
|
use axum_htmx::{HxBoosted, HxRedirect};
|
||||||
use axum_session_auth::AuthSession;
|
use axum_session_auth::AuthSession;
|
||||||
use axum_session_surreal::SessionSurrealPool;
|
use axum_session_surreal::SessionSurrealPool;
|
||||||
use chrono::RoundingError;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use surrealdb::{engine::any::Any, Surreal};
|
use surrealdb::{engine::any::Any, Surreal};
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
use crate::{error::HtmlError, server::AppState, storage::types::user::User};
|
use crate::{error::HtmlError, server::AppState, storage::types::user::User};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::storage::types::{file_info::deserialize_flexible_id, user::User, StoredObject};
|
use crate::storage::types::{file_info::deserialize_flexible_id, user::User, StoredObject};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
use crate::{error::AppError, storage::db::SurrealDbClient};
|
use crate::{error::AppError, storage::db::SurrealDbClient};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user