mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-18 16:28:55 +00:00
Implement a better Announcer trait
This commit is contained in:
parent
e5ea38b442
commit
765da554c4
1 changed files with 42 additions and 13 deletions
|
@ -1,8 +1,9 @@
|
||||||
|
use crate::db::{AnnouncerChannels, DBWriteGuard};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
builder::CreateMessage,
|
|
||||||
framework::standard::{CommandError as Error, CommandResult},
|
framework::standard::{CommandError as Error, CommandResult},
|
||||||
http::{CacheHttp, Http},
|
http::{CacheHttp, Http},
|
||||||
model::id::{ChannelId, GuildId, UserId},
|
model::id::{ChannelId, GuildId, UserId},
|
||||||
|
prelude::ShareMap,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
|
@ -10,13 +11,39 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Announcer {
|
pub trait Announcer {
|
||||||
type MessageSender: for<'a, 'r> Fn(&'r mut CreateMessage<'a>) -> &'r mut CreateMessage<'a>;
|
fn announcer_key() -> &'static str;
|
||||||
|
fn send_messages(
|
||||||
|
c: &Http,
|
||||||
|
d: &mut ShareMap,
|
||||||
|
channels: impl Fn(UserId) -> Vec<ChannelId>,
|
||||||
|
) -> CommandResult;
|
||||||
|
|
||||||
fn get_guilds(c: impl AsRef<Http>) -> Result<Vec<(GuildId, ChannelId)>, Error>;
|
fn set_channel(d: &mut ShareMap, guild: GuildId, channel: ChannelId) -> CommandResult {
|
||||||
fn fetch_messages(c: impl AsRef<Http>) -> Result<Vec<(UserId, Self::MessageSender)>, Error>;
|
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 announce(c: impl AsRef<Http>) -> CommandResult {
|
fn get_guilds(d: &mut ShareMap) -> Result<Vec<(GuildId, ChannelId)>, Error> {
|
||||||
let guilds: Vec<_> = Self::get_guilds(c.as_ref())?;
|
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 member_sets = {
|
||||||
let mut v = Vec::with_capacity(guilds.len());
|
let mut v = Vec::with_capacity(guilds.len());
|
||||||
for (guild, channel) in guilds.into_iter() {
|
for (guild, channel) in guilds.into_iter() {
|
||||||
|
@ -28,21 +55,23 @@ pub trait Announcer {
|
||||||
}
|
}
|
||||||
v
|
v
|
||||||
};
|
};
|
||||||
for (user_id, f) in Self::fetch_messages(c.as_ref())?.into_iter() {
|
Self::send_messages(c.as_ref(), d, |user_id| {
|
||||||
|
let mut v = Vec::new();
|
||||||
for (members, channel) in member_sets.iter() {
|
for (members, channel) in member_sets.iter() {
|
||||||
if members.contains(&user_id) {
|
if members.contains(&user_id) {
|
||||||
if let Err(e) = channel.send_message(c.as_ref(), &f) {
|
v.push(*channel);
|
||||||
dbg!((user_id, channel, e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
v
|
||||||
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan(c: impl CacheHttp + 'static + Send, cooldown: std::time::Duration) -> JoinHandle<()> {
|
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 {
|
spawn(move || loop {
|
||||||
if let Err(e) = Self::announce(c.http()) {
|
if let Err(e) = Self::announce(c.http(), &mut *data.write()) {
|
||||||
dbg!(e);
|
dbg!(e);
|
||||||
}
|
}
|
||||||
std::thread::sleep(cooldown);
|
std::thread::sleep(cooldown);
|
||||||
|
|
Loading…
Add table
Reference in a new issue