guzzles data
-rw-r--r--.gitignore5
-rw-r--r--Cargo.toml18
-rw-r--r--src/main.rs97
-rw-r--r--x.plot39
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();
+}
diff --git a/x.plot b/x.plot
new file mode 100644
index 0000000..bd548e0
--- /dev/null
+++ b/x.plot
@@ -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