mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-20 01:08:55 +00:00
Core: asyncify choose and implement role filter
This commit is contained in:
parent
9975aa5880
commit
5f08845d88
1 changed files with 53 additions and 26 deletions
|
@ -9,6 +9,7 @@ use serenity::{
|
||||||
},
|
},
|
||||||
model::{
|
model::{
|
||||||
channel::{Channel, Message},
|
channel::{Channel, Message},
|
||||||
|
id::RoleId,
|
||||||
user::OnlineStatus,
|
user::OnlineStatus,
|
||||||
},
|
},
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
|
@ -30,39 +31,57 @@ struct Community;
|
||||||
#[command]
|
#[command]
|
||||||
#[description = r"👑 Randomly choose an active member and mention them!
|
#[description = r"👑 Randomly choose an active member and mention them!
|
||||||
Note that only online/idle users in the channel are chosen from."]
|
Note that only online/idle users in the channel are chosen from."]
|
||||||
#[usage = "[title = the chosen one]"]
|
#[usage = "[title = the chosen one] / [limited roles = everyone online]"]
|
||||||
#[example = "the strongest in Gensokyo"]
|
#[example = "the strongest in Gensokyo"]
|
||||||
#[bucket = "community"]
|
#[bucket = "community"]
|
||||||
#[max_args(1)]
|
#[max_args(2)]
|
||||||
pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
pub async fn choose(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||||
let title = if args.is_empty() {
|
let title = if args.is_empty() {
|
||||||
"the chosen one".to_owned()
|
"the chosen one".to_owned()
|
||||||
} else {
|
} else {
|
||||||
args.single::<String>()?
|
args.single::<String>()?
|
||||||
};
|
};
|
||||||
|
let role = match args.single::<RoleId>().ok() {
|
||||||
|
Some(v) => v.to_role_cached(&ctx).await,
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
let users: Result<Vec<_>, Error> = {
|
let users: Result<Vec<_>, Error> = {
|
||||||
let guild = m.guild(&ctx).unwrap();
|
let guild = m.guild(&ctx).await.unwrap();
|
||||||
let guild = guild.read();
|
|
||||||
let presences = &guild.presences;
|
let presences = &guild.presences;
|
||||||
let channel = m.channel_id.to_channel(&ctx)?;
|
let channel = m.channel_id.to_channel(&ctx).await?;
|
||||||
if let Channel::Guild(channel) = channel {
|
if let Channel::Guild(channel) = channel {
|
||||||
let channel = channel.read();
|
|
||||||
Ok(channel
|
Ok(channel
|
||||||
.members(&ctx)?
|
.members(&ctx)
|
||||||
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|v| !v.user.read().bot)
|
.filter(|v| !v.user.bot) // Filter out bots
|
||||||
.map(|v| v.user_id())
|
|
||||||
.filter(|v| {
|
.filter(|v| {
|
||||||
|
// Filter out only online people
|
||||||
presences
|
presences
|
||||||
.get(v)
|
.get(&v.user.id)
|
||||||
.map(|presence| {
|
.map(|presence| {
|
||||||
presence.status == OnlineStatus::Online
|
presence.status == OnlineStatus::Online
|
||||||
|| presence.status == OnlineStatus::Idle
|
|| presence.status == OnlineStatus::Idle
|
||||||
})
|
})
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.collect())
|
.map(|mem| future::ready(mem))
|
||||||
|
.collect::<stream::FuturesUnordered<_>>()
|
||||||
|
.filter(|member| async {
|
||||||
|
// Filter by role if provided
|
||||||
|
if let Some(role) = role {
|
||||||
|
member
|
||||||
|
.roles(&ctx)
|
||||||
|
.await
|
||||||
|
.map(|roles| roles.into_iter().any(|r| role.id == r.id))
|
||||||
|
.unwrap_or(false)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
.await)
|
||||||
} else {
|
} else {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
@ -73,7 +92,8 @@ pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
||||||
m.reply(
|
m.reply(
|
||||||
&ctx,
|
&ctx,
|
||||||
"🍰 Have this cake for yourself because no-one is here for the gods to pick.",
|
"🍰 Have this cake for yourself because no-one is here for the gods to pick.",
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,19 +103,26 @@ pub fn choose(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult {
|
||||||
&users[uniform.sample(&mut rng)]
|
&users[uniform.sample(&mut rng)]
|
||||||
};
|
};
|
||||||
|
|
||||||
m.channel_id.send_message(&ctx, |c| {
|
m.channel_id
|
||||||
c.content(
|
.send_message(&ctx, |c| {
|
||||||
MessageBuilder::new()
|
c.content(
|
||||||
.push("👑 The Gensokyo gods have gathered around and decided, out of ")
|
MessageBuilder::new()
|
||||||
.push_bold(format!("{}", users.len()))
|
.push("👑 The Gensokyo gods have gathered around and decided, out of ")
|
||||||
.push(" potential prayers, ")
|
.push_bold(format!("{}", users.len()))
|
||||||
.push(winner.mention())
|
.push(" ")
|
||||||
.push(" will be ")
|
.push(
|
||||||
.push_bold_safe(title)
|
role.map(|r| r.mention() + "s")
|
||||||
.push(". Congrats! 🎉 🎊 🥳")
|
.unwrap_or("potential prayers".to_owned()),
|
||||||
.build(),
|
)
|
||||||
)
|
.push(", ")
|
||||||
})?;
|
.push(winner.mention())
|
||||||
|
.push(" will be ")
|
||||||
|
.push_bold_safe(title)
|
||||||
|
.push(". Congrats! 🎉 🎊 🥳")
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue