moving this chron job over to rust for muh resources and shieet
This commit is contained in:
parent
d4d6f19c5f
commit
f1a0771855
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,3 +14,5 @@ docs/resources
|
|||||||
docs/public/
|
docs/public/
|
||||||
|
|
||||||
keys/
|
keys/
|
||||||
|
|
||||||
|
chan-like/target/
|
||||||
|
1496
chan-like/Cargo.lock
generated
Normal file
1496
chan-like/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
chan-like/Cargo.toml
Normal file
15
chan-like/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "chan-chron"
|
||||||
|
version = "1.0.0"
|
||||||
|
authors = ["shockrah"]
|
||||||
|
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
tokio = { version = "1", features=["full"] }
|
||||||
|
mysql_async = "0.27.0"
|
||||||
|
|
||||||
|
clap = "2.33.3"
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
chrono = "0.4.19"
|
@ -1,8 +0,0 @@
|
|||||||
home = /usr
|
|
||||||
implementation = CPython
|
|
||||||
version_info = 3.8.5.final.0
|
|
||||||
virtualenv = 20.0.20
|
|
||||||
include-system-site-packages = false
|
|
||||||
base-prefix = /usr
|
|
||||||
base-exec-prefix = /usr
|
|
||||||
base-executable = /usr/bin/python3
|
|
154
chan-like/src/main.rs
Normal file
154
chan-like/src/main.rs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
use tokio;
|
||||||
|
|
||||||
|
use mysql_async::{Pool, params};
|
||||||
|
use mysql_async::prelude::*;
|
||||||
|
|
||||||
|
use chrono::{Utc, Duration};
|
||||||
|
|
||||||
|
use std::env::var;
|
||||||
|
use clap::{App, Arg};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const MAX_DAYS_HELP: &'static str = "Purge messages older than <D> days old
|
||||||
|
If the value is 0 (default) then messages are not deleted by their age
|
||||||
|
";
|
||||||
|
|
||||||
|
const MSG_LIMIT_HELP: &'static str = "Sets the max number of messages per channel.
|
||||||
|
NOTE: Deletes based on time so oldest messages are removed first until the max number of messages has been reached.
|
||||||
|
|
||||||
|
Example: #channel-a contains 1500 messages. Limit is set to 1000. Oldest 500 messages are removed
|
||||||
|
";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async fn remove_old(pool: &Pool, age_limit: i64) -> Result<(), mysql_async::Error> {
|
||||||
|
// really stupid guard but whatever
|
||||||
|
if age_limit == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Straight removal of messages by age
|
||||||
|
let now = Utc::now();
|
||||||
|
let oldest = (now - Duration::days(age_limit)).timestamp();
|
||||||
|
|
||||||
|
let query = "DELETE FROM messages WHERE time < :age";
|
||||||
|
let p = params!{ "age" => oldest };
|
||||||
|
|
||||||
|
let mut conn = pool.get_conn().await?;
|
||||||
|
conn.exec_drop(query, p).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn remove_maxed(pool: &Pool, max_msg: u64) -> Result<(), mysql_async::Error> {
|
||||||
|
// grab each channel id
|
||||||
|
// remove max by group
|
||||||
|
// ?
|
||||||
|
let mut conn = pool.get_conn().await?;
|
||||||
|
let channel_ids: Vec<u64> = conn.exec_map(
|
||||||
|
"SELECT id FROM channels", (),
|
||||||
|
| row | { row }
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// reverse the order and apply the limit to get the N newest items
|
||||||
|
for cid in channel_ids {
|
||||||
|
let query = "DELETE msg FROM messages msg join
|
||||||
|
(SELECT id FROM messages imsg WHERE imsg.channel_id = :cid
|
||||||
|
ORDER BY id DESC LIMIT 999 OFFSET :lim
|
||||||
|
) imsg on imsg.id = msg.id;";
|
||||||
|
|
||||||
|
let param = params!{"cid" => cid, "lim" => max_msg};
|
||||||
|
|
||||||
|
if let Err(e) = conn.exec_drop(query , param).await {
|
||||||
|
eprintln!("Couldn't remove messages from channel: {}", cid);
|
||||||
|
eprintln!("Mysql error: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), String>{
|
||||||
|
let args = App::new("chan-chron")
|
||||||
|
.version("1.0")
|
||||||
|
.author("shockrah - with <3")
|
||||||
|
.about("Removes \"old\" messages periodically")
|
||||||
|
.arg(Arg::with_name("max_days")
|
||||||
|
.short("d")
|
||||||
|
.long("max-days")
|
||||||
|
.value_name("D")
|
||||||
|
.takes_value(true)
|
||||||
|
.long_help(MAX_DAYS_HELP)
|
||||||
|
.default_value("0"))
|
||||||
|
.arg(Arg::with_name("config_file")
|
||||||
|
.short("f")
|
||||||
|
.long("file")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true))
|
||||||
|
.arg(Arg::with_name("msg_limit")
|
||||||
|
.short("l")
|
||||||
|
.long("msg-limit")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true)
|
||||||
|
.help(MSG_LIMIT_HELP))
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
//if let Some(db_url) = args.value_of("db-url") {
|
||||||
|
let db_url = if let Some(config) = args.value_of("config_file") {
|
||||||
|
match dotenv::from_filename(config) {
|
||||||
|
// Not bothering with fucked up configs thats an admin problem not mine
|
||||||
|
Ok(_) => var("DATABASE_URL").unwrap(),
|
||||||
|
_ => panic!("Config not found!")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("No config file provided!");
|
||||||
|
};
|
||||||
|
|
||||||
|
// could fail but again, thats a problem with configs sucking
|
||||||
|
let pool = Pool::from_url(db_url).unwrap();
|
||||||
|
|
||||||
|
let mut exec = 0;
|
||||||
|
if let Some(max_days) = args.value_of("max_days") {
|
||||||
|
let max: i64 = match max_days.parse() {
|
||||||
|
Ok(val) => val,
|
||||||
|
_ => panic!("Couldn't parse max_days value")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Panicing in hopes that we avoid running later on
|
||||||
|
if let Err(e) = remove_old(&pool, max).await {
|
||||||
|
panic!("{}", e);
|
||||||
|
} else {
|
||||||
|
exec = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if let Some(limit) = args.value_of("msg_limit") {
|
||||||
|
let limit: u64 = match limit.parse() {
|
||||||
|
Ok(val) => val,
|
||||||
|
_ => panic!("couldn't parse msg_limit value")
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = remove_maxed(&pool, limit).await {
|
||||||
|
panic!("{}", e);
|
||||||
|
} else {
|
||||||
|
exec |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if exec == 0 {
|
||||||
|
println!("Nothing todo");
|
||||||
|
} else {
|
||||||
|
match exec {
|
||||||
|
1 => println!("Age Based Purge succeed"),
|
||||||
|
2 => println!("Max message based purge succeed"),
|
||||||
|
3 => println!("All succeed"),
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user