..
This commit is contained in:
parent
6340f5a20f
commit
eb5c851d97
@ -59,7 +59,6 @@ assets = [
|
||||
["reminder-dashboard/dist/index.html", "lib/reminder-rs/static/index.html", "644"],
|
||||
["conf/default.env", "etc/reminder-rs/config.env", "600"],
|
||||
["conf/Rocket.toml", "etc/reminder-rs/Rocket.toml", "600"],
|
||||
["bin/reminder-rs-clean-old", "usr/bin/reminder-rs-clean-old", "755"],
|
||||
# ["nginx/reminder-rs", "etc/nginx/sites-available/reminder-rs", "755"]
|
||||
]
|
||||
conf-files = [
|
||||
|
363
src/main.rs
363
src/main.rs
@ -29,7 +29,6 @@ use std::{
|
||||
};
|
||||
|
||||
use chrono_tz::Tz;
|
||||
use clap::Subcommand;
|
||||
use log::warn;
|
||||
use poise::serenity_prelude::{
|
||||
model::{
|
||||
@ -121,174 +120,224 @@ async fn _main(tx: Sender<()>) -> Result<(), Box<dyn StdError + Send + Sync>> {
|
||||
let _ = dotenv::dotenv();
|
||||
}
|
||||
|
||||
let discord_token = env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
|
||||
|
||||
let options = poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
help::command(),
|
||||
info::command(),
|
||||
clock::command(),
|
||||
donate::command(),
|
||||
clock_context_menu(),
|
||||
dashboard::command(),
|
||||
timezone::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![allowed_dm::set::set(), allowed_dm::unset::unset()],
|
||||
..allowed_dm::allowed_dm()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![poise::Command {
|
||||
subcommands: vec![
|
||||
settings::ephemeral_confirmations::set::set(),
|
||||
settings::ephemeral_confirmations::unset::unset(),
|
||||
],
|
||||
..settings::ephemeral_confirmations::ephemeral_confirmations()
|
||||
}],
|
||||
..settings::settings()
|
||||
},
|
||||
webhook::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
command_macro::delete_macro::delete_macro(),
|
||||
command_macro::finish_macro::finish_macro(),
|
||||
command_macro::list_macro::list_macro(),
|
||||
command_macro::record_macro::record_macro(),
|
||||
command_macro::run_macro::run_macro(),
|
||||
],
|
||||
..command_macro::command_macro()
|
||||
},
|
||||
pause::command(),
|
||||
offset::command(),
|
||||
nudge::command(),
|
||||
look::command(),
|
||||
delete::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
timer::list::list(),
|
||||
timer::start::start(),
|
||||
timer::delete::delete(),
|
||||
],
|
||||
..timer::timer()
|
||||
},
|
||||
multiline::command(),
|
||||
remind::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
poise::Command {
|
||||
subcommands: vec![todo::guild::add::add(), todo::guild::view::view()],
|
||||
..todo::guild::guild()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![todo::channel::add::add(), todo::channel::view::view()],
|
||||
..todo::channel::channel()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![todo::user::add::add(), todo::user::view::view()],
|
||||
..todo::user::user()
|
||||
},
|
||||
],
|
||||
..todo::todo()
|
||||
},
|
||||
],
|
||||
allowed_mentions: None,
|
||||
command_check: Some(|ctx| Box::pin(all_checks(ctx))),
|
||||
event_handler: |ctx, event, _framework, data| Box::pin(listener(ctx, event, data)),
|
||||
on_error: |error| {
|
||||
Box::pin(async move {
|
||||
match error {
|
||||
poise::FrameworkError::CommandCheckFailed { .. } => {
|
||||
// suppress error
|
||||
}
|
||||
error => {
|
||||
if let Err(e) = poise::builtins::on_error(error).await {
|
||||
log::error!("Error while handling error: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Start metrics
|
||||
init_metrics();
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
let cmd_word = args.last().map(|w| w.as_str());
|
||||
|
||||
let database =
|
||||
Pool::connect(&env::var("DATABASE_URL").expect("No database URL provided")).await.unwrap();
|
||||
|
||||
sqlx::migrate!().run(&database).await?;
|
||||
match cmd_word {
|
||||
Some("clean") => {
|
||||
let sent_clean_age = env::var("SENT_CLEAN_AGE")?;
|
||||
if sent_clean_age.is_empty() {
|
||||
panic!("No SENT_CLEAN_AGE")
|
||||
}
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM reminders
|
||||
WHERE `utc_time` < NOW() - INTERVAL ? DAY
|
||||
AND status != 'pending'
|
||||
ORDER BY `utc_time`
|
||||
LIMIT 1000
|
||||
",
|
||||
sent_clean_age
|
||||
)
|
||||
.execute(&database)
|
||||
.await?;
|
||||
|
||||
let popular_timezones = sqlx::query!(
|
||||
"
|
||||
SELECT IFNULL(timezone, 'UTC') AS timezone
|
||||
FROM users
|
||||
WHERE timezone IS NOT NULL
|
||||
GROUP BY timezone
|
||||
ORDER BY COUNT(timezone) DESC
|
||||
LIMIT 21
|
||||
"
|
||||
)
|
||||
.fetch_all(&database)
|
||||
.await
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|t| t.timezone.parse::<Tz>().unwrap())
|
||||
.collect::<Vec<Tz>>();
|
||||
let total_clean_age = env::var("TOTAL_CLEAN_AGE");
|
||||
if let Ok(total_clean_age) = total_clean_age {
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM reminders
|
||||
WHERE `utc_time` < NOW() - INTERVAL ? DAY
|
||||
ORDER BY `utc_time`
|
||||
LIMIT 1000
|
||||
",
|
||||
total_clean_age
|
||||
)
|
||||
.execute(&database)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let framework = poise::Framework::builder()
|
||||
.setup(move |ctx, _bot, framework| {
|
||||
Box::pin(async move {
|
||||
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
let discord_token =
|
||||
env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
|
||||
|
||||
let kill_tx = tx.clone();
|
||||
let kill_recv = tx.subscribe();
|
||||
|
||||
let ctx1 = ctx.clone();
|
||||
let ctx2 = ctx.clone();
|
||||
|
||||
let pool1 = database.clone();
|
||||
let pool2 = database.clone();
|
||||
|
||||
let run_settings = env::var("DONTRUN").unwrap_or_else(|_| "".to_string());
|
||||
|
||||
if !run_settings.contains("postman") {
|
||||
tokio::spawn(async move {
|
||||
match postman::initialize(kill_recv, ctx1, &pool1).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
panic!("postman exiting: {}", e);
|
||||
let options = poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
help::command(),
|
||||
info::command(),
|
||||
clock::command(),
|
||||
donate::command(),
|
||||
clock_context_menu(),
|
||||
dashboard::command(),
|
||||
timezone::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![allowed_dm::set::set(), allowed_dm::unset::unset()],
|
||||
..allowed_dm::allowed_dm()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![poise::Command {
|
||||
subcommands: vec![
|
||||
settings::ephemeral_confirmations::set::set(),
|
||||
settings::ephemeral_confirmations::unset::unset(),
|
||||
],
|
||||
..settings::ephemeral_confirmations::ephemeral_confirmations()
|
||||
}],
|
||||
..settings::settings()
|
||||
},
|
||||
webhook::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
command_macro::delete_macro::delete_macro(),
|
||||
command_macro::finish_macro::finish_macro(),
|
||||
command_macro::list_macro::list_macro(),
|
||||
command_macro::record_macro::record_macro(),
|
||||
command_macro::run_macro::run_macro(),
|
||||
],
|
||||
..command_macro::command_macro()
|
||||
},
|
||||
pause::command(),
|
||||
offset::command(),
|
||||
nudge::command(),
|
||||
look::command(),
|
||||
delete::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
timer::list::list(),
|
||||
timer::start::start(),
|
||||
timer::delete::delete(),
|
||||
],
|
||||
..timer::timer()
|
||||
},
|
||||
multiline::command(),
|
||||
remind::command(),
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
todo::guild::add::add(),
|
||||
todo::guild::view::view(),
|
||||
],
|
||||
..todo::guild::guild()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![
|
||||
todo::channel::add::add(),
|
||||
todo::channel::view::view(),
|
||||
],
|
||||
..todo::channel::channel()
|
||||
},
|
||||
poise::Command {
|
||||
subcommands: vec![todo::user::add::add(), todo::user::view::view()],
|
||||
..todo::user::user()
|
||||
},
|
||||
],
|
||||
..todo::todo()
|
||||
},
|
||||
],
|
||||
allowed_mentions: None,
|
||||
command_check: Some(|ctx| Box::pin(all_checks(ctx))),
|
||||
event_handler: |ctx, event, _framework, data| Box::pin(listener(ctx, event, data)),
|
||||
on_error: |error| {
|
||||
Box::pin(async move {
|
||||
match error {
|
||||
poise::FrameworkError::CommandCheckFailed { .. } => {
|
||||
// suppress error
|
||||
}
|
||||
};
|
||||
});
|
||||
} else {
|
||||
warn!("Not running postman");
|
||||
}
|
||||
error => {
|
||||
if let Err(e) = poise::builtins::on_error(error).await {
|
||||
log::error!("Error while handling error: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if !run_settings.contains("web") {
|
||||
tokio::spawn(async move {
|
||||
web::initialize(kill_tx, ctx2, pool2).await.unwrap();
|
||||
});
|
||||
} else {
|
||||
warn!("Not running web");
|
||||
}
|
||||
// Start metrics
|
||||
init_metrics();
|
||||
|
||||
Ok(Data {
|
||||
database,
|
||||
popular_timezones,
|
||||
recording_macros: Default::default(),
|
||||
_broadcast: tx,
|
||||
sqlx::migrate!().run(&database).await?;
|
||||
|
||||
let popular_timezones = sqlx::query!(
|
||||
"
|
||||
SELECT IFNULL(timezone, 'UTC') AS timezone
|
||||
FROM users
|
||||
WHERE timezone IS NOT NULL
|
||||
GROUP BY timezone
|
||||
ORDER BY COUNT(timezone) DESC
|
||||
LIMIT 21
|
||||
"
|
||||
)
|
||||
.fetch_all(&database)
|
||||
.await
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|t| t.timezone.parse::<Tz>().unwrap())
|
||||
.collect::<Vec<Tz>>();
|
||||
|
||||
let framework = poise::Framework::builder()
|
||||
.setup(move |ctx, _bot, framework| {
|
||||
Box::pin(async move {
|
||||
poise::builtins::register_globally(ctx, &framework.options().commands)
|
||||
.await?;
|
||||
|
||||
let kill_tx = tx.clone();
|
||||
let kill_recv = tx.subscribe();
|
||||
|
||||
let ctx1 = ctx.clone();
|
||||
let ctx2 = ctx.clone();
|
||||
|
||||
let pool1 = database.clone();
|
||||
let pool2 = database.clone();
|
||||
|
||||
let run_settings = env::var("DONTRUN").unwrap_or_else(|_| "".to_string());
|
||||
|
||||
if !run_settings.contains("postman") {
|
||||
tokio::spawn(async move {
|
||||
match postman::initialize(kill_recv, ctx1, &pool1).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
panic!("postman exiting: {}", e);
|
||||
}
|
||||
};
|
||||
});
|
||||
} else {
|
||||
warn!("Not running postman");
|
||||
}
|
||||
|
||||
if !run_settings.contains("web") {
|
||||
tokio::spawn(async move {
|
||||
web::initialize(kill_tx, ctx2, pool2).await.unwrap();
|
||||
});
|
||||
} else {
|
||||
warn!("Not running web");
|
||||
}
|
||||
|
||||
Ok(Data {
|
||||
database,
|
||||
popular_timezones,
|
||||
recording_macros: Default::default(),
|
||||
_broadcast: tx,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.options(options)
|
||||
.build();
|
||||
.options(options)
|
||||
.build();
|
||||
|
||||
let mut client = ClientBuilder::new(&discord_token, GatewayIntents::GUILDS)
|
||||
.framework(framework)
|
||||
.activity(ActivityData::watching("for /remind"))
|
||||
.await?;
|
||||
let mut client = ClientBuilder::new(&discord_token, GatewayIntents::GUILDS)
|
||||
.framework(framework)
|
||||
.activity(ActivityData::watching("for /remind"))
|
||||
.await?;
|
||||
|
||||
client.start_autosharded().await?;
|
||||
client.start_autosharded().await?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
systemd/reminder-rs-clean-old.service
Normal file
11
systemd/reminder-rs-clean-old.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Clean old data from Reminder Bot
|
||||
|
||||
[Service]
|
||||
User=reminder
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/reminder-rs clean
|
||||
WorkingDirectory=/etc/reminder-rs
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
9
systemd/reminder-rs-clean-old.timer
Normal file
9
systemd/reminder-rs-clean-old.timer
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Clean reminder data twice daily
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 0/8
|
||||
Unit=reminder-rs-clean-old.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
Loading…
Reference in New Issue
Block a user