Mercurial > lbo > hg > analyrics
changeset 28:25439f8c9114
Implement time window for index page
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 14 Jul 2022 22:12:10 -0700 |
parents | 792eb8ac3d93 |
children | 8ad244c1b061 |
files | Cargo.toml src/logsdb.rs src/main.rs |
diffstat | 3 files changed, 52 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/Cargo.toml Thu Jul 14 20:35:35 2022 -0700 +++ b/Cargo.toml Thu Jul 14 22:12:10 2022 -0700 @@ -10,12 +10,12 @@ either = "1.7.0" env_logger = "0.9.0" log = "0.4.17" -rocket = { version = "0.5.0-rc.2", features = ["secrets", "json",] } +rocket = { version = "0.5.0-rc.2", features = ["secrets", "json"] } sqlx = { version = "0.5", features = ["macros"] } rocket_db_pools = { version = "0.1.0-rc.2", features = [ "sqlx_macros"] } rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["handlebars"] } sha256 = "1.0.3" -time = "0.3.11" +time = { version = "0.3.11", features = ["serde", "serde-well-known"] } tokio = { version = "1.19.2", features = ["fs"] } [features]
--- a/src/logsdb.rs Thu Jul 14 20:35:35 2022 -0700 +++ b/src/logsdb.rs Thu Jul 14 22:12:10 2022 -0700 @@ -95,6 +95,7 @@ domainpattern: Option<S>, ) -> Result<(Vec<String>, Vec<u32>, Vec<u32>), Error> { let domain = domainpattern.as_ref().map(AsRef::as_ref).unwrap_or("%"); + let tz_offset = tz_offset.unwrap_or(0); let mut results = sqlx::query( r#" SELECT DATE(atime + ?, 'unixepoch') AS rqdate, COUNT(requestlog.id) AS rqcount, sesscount @@ -103,14 +104,16 @@ SELECT DATE(start + ?, 'unixepoch') AS sessdate, COUNT(*) AS sesscount FROM sessions WHERE sessions.domain LIKE ? GROUP BY sessdate) AS sc ON (rqdate = sessdate) -WHERE atime > ? AND atime < ? AND requestlog.domain LIKE ? +WHERE atime+? > ? AND atime+? < ? AND requestlog.domain LIKE ? GROUP BY rqdate ORDER BY rqdate ASC;"#, ) - .bind(tz_offset.unwrap_or(0)) - .bind(tz_offset.unwrap_or(0)) + .bind(tz_offset) + .bind(tz_offset) .bind(domain) + .bind(tz_offset) .bind(from.unix_timestamp()) + .bind(tz_offset) .bind(to.unix_timestamp()) .bind(domain) .fetch(&mut *self.0);
--- a/src/main.rs Thu Jul 14 20:35:35 2022 -0700 +++ b/src/main.rs Thu Jul 14 22:12:10 2022 -0700 @@ -1,9 +1,9 @@ mod configdb; mod db; +mod fromparam; +mod guards; mod logsdb; -mod guards; - use crate::configdb::{ConfigDB, ConfigDBSession}; use crate::guards::{HeadersGuard, LoggedInGuard, USER_ID_COOKIE_KEY}; use crate::logsdb::{LogsDB, LogsDBSession}; @@ -11,12 +11,12 @@ use anyhow::{self, Context, Error}; use either::Either; use log::{debug, error, info, warn, Level}; -use time::{Duration, OffsetDateTime}; +use time::{Date, Duration, OffsetDateTime}; use rocket::form::Form; use rocket::fs::{relative, FileServer, NamedFile}; use rocket::futures::StreamExt; -use rocket::http::{Cookie, CookieJar, HeaderMap, Status}; +use rocket::http::{Cookie, CookieJar, HeaderMap, RawStr, Status}; use rocket::request::{self, FlashMessage, FromRequest, Outcome, Request}; use rocket::response::{self, Flash, Redirect, Responder}; use rocket::serde::json::{json, Value}; @@ -30,8 +30,7 @@ use std::collections::HashMap; use std::net::IpAddr; -use std::path::{Path, PathBuf}; -use std::time::Instant; +use std::path::Path; #[derive(Responder)] enum LoginResponse { @@ -149,13 +148,30 @@ inner } -#[rocket::get("/?<domain>", rank = 1)] +fn construct_index_querystring( + domain: Option<&str>, + from: OffsetDateTime, + duration: Duration, +) -> String { + format!( + "?domain={}&from={}&duration={}", + domain.unwrap_or(""), + from.format(&time::format_description::well_known::Iso8601::DEFAULT) + .unwrap_or("".to_string()), + duration.whole_days() + ) +} + +/// Main analytics page for logged-in users. +#[rocket::get("/?<domain>&<from>&<duration>", rank = 1)] async fn route_index_loggedin( mut conn: Connection<LogsDB>, mut config_conn: Connection<ConfigDB>, lig: LoggedInGuard, flash: Option<FlashMessage<'_>>, domain: Option<&str>, + from: Option<&str>, + duration: Option<&str>, ) -> Template { let f; if let Some(ref flash) = flash { @@ -164,8 +180,29 @@ f = None; } + // Parameter treatment + let duration = duration + .map(|d| i64::from_str_radix(d, 10).unwrap_or(30)) + .map(|d| Duration::new(84600 * d, 0)) + .unwrap_or(Duration::days(30)); + let from = from + .map(|p| { + OffsetDateTime::parse(p, &time::format_description::well_known::Iso8601::PARSING) + .or( + Date::parse(p, &time::format_description::well_known::Iso8601::PARSING) + .map(|d| d.midnight().assume_utc()), + ) + .unwrap_or(OffsetDateTime::now_utc() - duration) + }) + .unwrap_or(OffsetDateTime::now_utc() - duration); + let begin = from; + let end = begin + duration; + + // Chart rendering + let mut charts = HashMap::<String, String>::new(); + // in seconds for this user. let tz_offset = match ConfigDBSession(&mut config_conn) .get_user_details(&lig.0) .await @@ -176,9 +213,6 @@ 0 } }; - // TODO: Make configurable - let begin = OffsetDateTime::now_utc() - Duration::days(30); - let end = OffsetDateTime::now_utc(); match LogsDBSession(&mut conn) .query_visits_sessions_counts(begin, end, Some(tz_offset), domain) .await