aboutsummaryrefslogtreecommitdiffstats
path: root/src/command/client/stats.rs
diff options
context:
space:
mode:
authorConrad Ludgate <conrad.ludgate@truelayer.com>2022-04-21 10:12:56 +0100
committerGitHub <noreply@github.com>2022-04-21 09:12:56 +0000
commitd57f549855caf8ab90b5ea0ae7cc9445f3abedfc (patch)
tree0818ff405a3b697a0ca981d215ceb4dbb30cd15a /src/command/client/stats.rs
parentFix SQL cache query (#318) (diff)
downloadatuin-d57f549855caf8ab90b5ea0ae7cc9445f3abedfc.zip
refactor commands for better separation (#313)
* refactor commands for better separation * fmt
Diffstat (limited to 'src/command/client/stats.rs')
-rw-r--r--src/command/client/stats.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/command/client/stats.rs b/src/command/client/stats.rs
new file mode 100644
index 00000000..6d342c19
--- /dev/null
+++ b/src/command/client/stats.rs
@@ -0,0 +1,101 @@
+use std::collections::HashMap;
+
+use chrono::prelude::*;
+use chrono::Duration;
+use chrono_english::parse_date_string;
+
+use clap::Parser;
+use cli_table::{format::Justify, print_stdout, Cell, Style, Table};
+use eyre::{bail, Result};
+
+use atuin_client::database::Database;
+use atuin_client::history::History;
+use atuin_client::settings::Settings;
+
+#[derive(Parser)]
+#[clap(infer_subcommands = true)]
+pub enum Cmd {
+ /// Compute statistics for all of time
+ All,
+
+ /// Compute statistics for a single day
+ Day { words: Vec<String> },
+}
+
+fn compute_stats(history: &[History]) -> Result<()> {
+ let mut commands = HashMap::<String, i64>::new();
+
+ for i in history {
+ *commands.entry(i.command.clone()).or_default() += 1;
+ }
+
+ let most_common_command = commands.iter().max_by(|a, b| a.1.cmp(b.1));
+
+ if most_common_command.is_none() {
+ bail!("No commands found");
+ }
+
+ let table = vec![
+ vec![
+ "Most used command".cell(),
+ most_common_command
+ .unwrap()
+ .0
+ .cell()
+ .justify(Justify::Right),
+ ],
+ vec![
+ "Commands ran".cell(),
+ history.len().to_string().cell().justify(Justify::Right),
+ ],
+ vec![
+ "Unique commands ran".cell(),
+ commands.len().to_string().cell().justify(Justify::Right),
+ ],
+ ]
+ .table()
+ .title(vec![
+ "Statistic".cell().bold(true),
+ "Value".cell().bold(true),
+ ])
+ .bold(true);
+
+ print_stdout(table)?;
+
+ Ok(())
+}
+
+impl Cmd {
+ pub async fn run(
+ &self,
+ db: &mut (impl Database + Send + Sync),
+ settings: &Settings,
+ ) -> Result<()> {
+ match self {
+ Self::Day { words } => {
+ let words = if words.is_empty() {
+ String::from("yesterday")
+ } else {
+ words.join(" ")
+ };
+
+ let start = parse_date_string(&words, Local::now(), settings.dialect.into())?;
+ let end = start + Duration::days(1);
+
+ let history = db.range(start.into(), end.into()).await?;
+
+ compute_stats(&history)?;
+
+ Ok(())
+ }
+
+ Self::All => {
+ let history = db.list(None, false).await?;
+
+ compute_stats(&history)?;
+
+ Ok(())
+ }
+ }
+ }
+}