repos
/ analytics-rust master

analytics-rust

mirror archived upstream

Single-binary self-hosted website analytics on Rust axum: collector API, dashboards, world map, and PDF reports.

analyticsaxumdockerrustself-hostedsqliteviteweb-analytics

1.9 KB · 57 lines · Rust Raw History
 1use axum::{
 2    extract::State,
 3    http::{header, HeaderMap, StatusCode},
 4    response::{IntoResponse, Response},
 5    routing::get,
 6    Router,
 7};
 8
 9use crate::AppState;
10
11pub fn router() -> Router<AppState> {
12    Router::new()
13        .route("/favicon.ico", get(favicon))
14        .route("/robots.txt", get(robots))
15        .route("/sitemap.xml", get(sitemap))
16}
17
18pub async fn favicon() -> Response {
19    let mut h = HeaderMap::new();
20    h.insert(header::CONTENT_TYPE, "image/svg+xml".parse().unwrap());
21    let svg = r##"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
22  <rect x="6"  y="38" width="10" height="22" rx="1.5" fill="#6b9e78"/>
23  <rect x="20" y="28" width="10" height="32" rx="1.5" fill="#6b9e78"/>
24  <rect x="34" y="18" width="10" height="42" rx="1.5" fill="#6b9e78"/>
25  <rect x="48" y="8"  width="10" height="52" rx="1.5" fill="#6b9e78"/>
26  <rect x="48" y="8"  width="10" height="6"  rx="1.5" fill="#c9a84c"/>
27</svg>"##;
28    (StatusCode::OK, h, svg).into_response()
29}
30
31pub async fn robots() -> Response {
32    let mut h = HeaderMap::new();
33    h.insert(header::CONTENT_TYPE, "text/plain".parse().unwrap());
34    (StatusCode::OK, h, "User-agent: *\nAllow: /\n").into_response()
35}
36
37pub async fn sitemap(State(state): State<AppState>) -> Response {
38    let mut h = HeaderMap::new();
39    h.insert(header::CONTENT_TYPE, "application/xml".parse().unwrap());
40    let base = if state.config.base_url.is_empty() {
41        "/".to_string()
42    } else {
43        format!("{}/", state.config.base_url.trim_end_matches('/'))
44    };
45    let now = chrono::Utc::now().format("%Y-%m-%d");
46    let body = format!(
47        r##"<?xml version="1.0" encoding="UTF-8"?>
48<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
49  <url><loc>{base}</loc><lastmod>{now}</lastmod></url>
50  <url><loc>{base}documentation</loc><lastmod>{now}</lastmod></url>
51  <url><loc>{base}changelog</loc><lastmod>{now}</lastmod></url>
52</urlset>
53"##
54    );
55    (StatusCode::OK, h, body).into_response()
56}