guzzles data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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();
}