guzzles data
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Cargo.toml | 18 | ||||
| -rw-r--r-- | src/main.rs | 97 | ||||
| -rw-r--r-- | x.plot | 39 |
4 files changed, 159 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b39f798 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +1.dat +token +data.png +data.svg +Cargo.lock
\ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0b97bae --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "data-guzzler" +version = "0.1.0" +edition = "2021" + +[dependencies] +serenity = { version = "0.12", features = [ + "builder", + "client", + "utils", + "rustls_backend", + "gateway", + "cache", +], default-features = false } +poise = { git = "https://github.com/serenity-rs/poise" } +anyhow = "1.0.80" +tokio = { version = "1.36.0", features = ["rt-multi-thread"] } +emoji = { git = "https://github.com/apricot-conservation-project/emoji", version = "0.1.0" } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c92aa9b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,97 @@ +use anyhow::Result; +use emoji::named::*; +use poise::serenity_prelude::*; +use serenity::futures::StreamExt; +use std::fs::read_to_string; +use std::io::Write; +type Context<'a> = poise::Context<'a, (), anyhow::Error>; +#[poise::command(slash_command)] +pub async fn users(c: Context<'_>) -> Result<()> { + c.defer().await?; + let g = { + let Some(g) = c.guild() else { + _ = c.reply(format!("{CANCEL} need guild")); + return Ok(()); + }; + g.id + }; + let mut s = std::pin::pin!(g.members_iter(c)); + let mut data: Vec<u16> = vec![0; 365 * 12]; + let mut min = 365 * 12; + let mut max = 0; + while let Some(x) = s.next().await { + let x = x?.joined_at.unwrap(); + let d = (x.timestamp() as usize - 1420070400) / (60 * 60 * 24); + min = min.min(d); + max = max.max(d); + data[d] += 1; + } + let mut f = std::fs::File::create("1.dat").unwrap(); + let mut sum = 0; + for (i, &d) in data[min..max].iter().enumerate() { + sum += d; + let t = + Timestamp::from_unix_timestamp(((i + min) as i64 * (60 * 60 * 24) as i64) + 1420070400) + .unwrap(); + writeln!( + &mut f, + r"{},{sum}", + if t.format("%d").to_string() == "01" { + t.format("%m/%d/%y").to_string() + } else { + "".to_string() + } + ) + .unwrap(); + } + assert!(std::process::Command::new("gnuplot") + .arg("x.plot") + .spawn() + .unwrap() + .wait() + .unwrap() + .success()); + assert!(std::process::Command::new("inkscape") + .arg("--export-filename=data.png") + .arg("data.svg") + .spawn() + .unwrap() + .wait() + .unwrap() + .success()); + poise::send_reply( + c, + poise::CreateReply::default().attachment(CreateAttachment::path("data.png").await.unwrap()), + ) + .await?; + Ok(()) +} + +#[tokio::main] +async fn main() { + let tok = + std::env::var("TOKEN").unwrap_or_else(|_| read_to_string("token").expect("wher token")); + let f = poise::Framework::builder() + .options(poise::FrameworkOptions { + commands: vec![users()], + ..Default::default() + }) + .setup(|ctx, _ready, f| { + Box::pin(async move { + poise::builtins::register_globally(ctx, &f.options().commands).await?; + println!("registered"); + Ok(()) + }) + }) + .build(); + ClientBuilder::new( + tok, + GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT, + ) + .framework(f) + .await + .unwrap() + .start() + .await + .unwrap(); +} @@ -0,0 +1,39 @@ +set terminal svg enhanced background rgb "#0D1117" size 1280 720 + +set linetype 1 lw 2 lc rgb '#73D0FF' pointtype 6 +set linetype 2 lw 2 lc rgb '#FFD173' pointtype 6 +set linetype 3 lw 2 lc rgb '#D5FF80' pointtype 6 +set linetype 4 lw 2 lc rgb '#F27983' pointtype 6 +set linetype 5 lw 2 lc rgb '#DFBFFF' pointtype 6 +set linetype 6 lw 2 lc rgb '#BFBDB6' pointtype 6 +set linetype 7 lw 2 lc rgb '#FF6666' pointtype 6 +set title textcolor rgb '#E6EDF3' font "Verdana,18" +set ylabel textcolor rgb '#E6EDF3' font "Verdana,18" +set xlabel textcolor rgb '#E6EDF3' font "Verdana,18" +set style fill solid border rgb "#1A1F29" +set border lw 3 lc rgb '#E6EDF3' +set key textcolor rgb '#E6EDF3' font "Verdana,14" +set xtics nomirror +set border lw 1 + +set output "data.svg" +set title "users" +# set logscale y +set ytics 50 +set mytics 2 +set style data histogram +set style histogram cluster gap 1 +set ylabel "user count" +set xlabel "days" +set auto x +set yrange [0:*] +set style line 12 lc rgb '#1F2430' lt 1 lw 2 dt 22 +unset xtics +set xtics format "" +set xtics scale 0 +set xtics rotate by 45 right +set grid ytics ls 12 +set datafile separator "," +set key top left + +plot '1.dat' u 2:xtic(1) smooth acsplines title "user count"
\ No newline at end of file |