mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-18 16:28:55 +00:00
Announcer Trait (#9)
This commit is contained in:
parent
a17e9c6d1d
commit
7d49edb1fe
3 changed files with 92 additions and 1 deletions
84
youmubot/src/commands/announcer.rs
Normal file
84
youmubot/src/commands/announcer.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
use crate::db::{AnnouncerChannels, DBWriteGuard};
|
||||||
|
use serenity::{
|
||||||
|
framework::standard::{CommandError as Error, CommandResult},
|
||||||
|
http::{CacheHttp, Http},
|
||||||
|
model::id::{ChannelId, GuildId, UserId},
|
||||||
|
prelude::ShareMap,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
|
thread::{spawn, JoinHandle},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait Announcer {
|
||||||
|
fn announcer_key() -> &'static str;
|
||||||
|
fn send_messages(
|
||||||
|
c: &Http,
|
||||||
|
d: &mut ShareMap,
|
||||||
|
channels: impl Fn(UserId) -> Vec<ChannelId> + Sync,
|
||||||
|
) -> CommandResult;
|
||||||
|
|
||||||
|
fn set_channel(d: &mut ShareMap, guild: GuildId, channel: ChannelId) -> CommandResult {
|
||||||
|
let mut data: DBWriteGuard<_> = d
|
||||||
|
.get_mut::<AnnouncerChannels>()
|
||||||
|
.expect("DB initialized")
|
||||||
|
.into();
|
||||||
|
let mut data = data.borrow_mut()?;
|
||||||
|
data.entry(Self::announcer_key().to_owned())
|
||||||
|
.or_default()
|
||||||
|
.insert(guild, channel);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_guilds(d: &mut ShareMap) -> Result<Vec<(GuildId, ChannelId)>, Error> {
|
||||||
|
let data = d
|
||||||
|
.get::<AnnouncerChannels>()
|
||||||
|
.expect("DB initialized")
|
||||||
|
.read(|v| {
|
||||||
|
v.get(Self::announcer_key())
|
||||||
|
.map(|m| m.iter().map(|(a, b)| (*a, *b)).collect())
|
||||||
|
.unwrap_or_else(|| vec![])
|
||||||
|
})?;
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn announce(c: &Http, d: &mut ShareMap) -> CommandResult {
|
||||||
|
let guilds: Vec<_> = Self::get_guilds(d)?;
|
||||||
|
let member_sets = {
|
||||||
|
let mut v = Vec::with_capacity(guilds.len());
|
||||||
|
for (guild, channel) in guilds.into_iter() {
|
||||||
|
let mut s = HashSet::new();
|
||||||
|
for user in guild
|
||||||
|
.members_iter(c.as_ref())
|
||||||
|
.take_while(|u| u.is_ok())
|
||||||
|
.filter_map(|u| u.ok())
|
||||||
|
{
|
||||||
|
s.insert(user.user_id());
|
||||||
|
}
|
||||||
|
v.push((s, channel))
|
||||||
|
}
|
||||||
|
v
|
||||||
|
};
|
||||||
|
Self::send_messages(c.as_ref(), d, |user_id| {
|
||||||
|
let mut v = Vec::new();
|
||||||
|
for (members, channel) in member_sets.iter() {
|
||||||
|
if members.contains(&user_id) {
|
||||||
|
v.push(*channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scan(client: &serenity::Client, cooldown: std::time::Duration) -> JoinHandle<()> {
|
||||||
|
let c = client.cache_and_http.clone();
|
||||||
|
let data = client.data.clone();
|
||||||
|
spawn(move || loop {
|
||||||
|
if let Err(e) = Self::announce(c.http(), &mut *data.write()) {
|
||||||
|
dbg!(e);
|
||||||
|
}
|
||||||
|
std::thread::sleep(cooldown);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ use serenity::{
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
mod announcer;
|
||||||
mod args;
|
mod args;
|
||||||
|
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
|
@ -17,6 +18,8 @@ pub use admin::ADMIN_GROUP;
|
||||||
pub use community::COMMUNITY_GROUP;
|
pub use community::COMMUNITY_GROUP;
|
||||||
pub use fun::FUN_GROUP;
|
pub use fun::FUN_GROUP;
|
||||||
|
|
||||||
|
pub use announcer::Announcer;
|
||||||
|
|
||||||
// A help command
|
// A help command
|
||||||
#[help]
|
#[help]
|
||||||
pub fn help(
|
pub fn help(
|
||||||
|
|
|
@ -5,7 +5,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
client::Client,
|
client::Client,
|
||||||
framework::standard::CommandError as Error,
|
framework::standard::CommandError as Error,
|
||||||
model::id::{GuildId, RoleId, UserId},
|
model::id::{ChannelId, GuildId, RoleId, UserId},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -32,6 +32,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A map from announcer keys to guild IDs and to channels.
|
||||||
|
pub type AnnouncerChannels = DB<HashMap<String, GuildMap<ChannelId>>>;
|
||||||
|
|
||||||
/// A list of SoftBans for all servers.
|
/// A list of SoftBans for all servers.
|
||||||
pub type SoftBans = DB<GuildMap<ServerSoftBans>>;
|
pub type SoftBans = DB<GuildMap<ServerSoftBans>>;
|
||||||
|
|
||||||
|
@ -43,6 +46,7 @@ pub fn setup_db(client: &mut Client) -> Result<(), Error> {
|
||||||
});
|
});
|
||||||
let mut data = client.data.write();
|
let mut data = client.data.write();
|
||||||
SoftBans::insert_into(&mut *data, &path.join("soft_bans.ron"))?;
|
SoftBans::insert_into(&mut *data, &path.join("soft_bans.ron"))?;
|
||||||
|
AnnouncerChannels::insert_into(&mut *data, &path.join("announcers.yaml"))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue