Improved `start_session` performance and added checklist
parent
4bddb8371c
commit
c644874fef
106
src/bot.rs
106
src/bot.rs
|
@ -2,11 +2,11 @@ use crate::config::BotConfig;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::model::session::{Session, SessionConfig};
|
use crate::model::session::{Session, SessionConfig};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use log::{debug, info};
|
use log::{debug, error, info};
|
||||||
use poise::futures_util::{Stream, StreamExt};
|
use poise::futures_util::{Stream, StreamExt};
|
||||||
use poise::serenity_prelude::{
|
use poise::serenity_prelude::{
|
||||||
futures, AutocompleteChoice, CreateAttachment, EditScheduledEvent, MessageBuilder,
|
futures, AutocompleteChoice, CreateAttachment, CreateEmbed, EditScheduledEvent, GatewayIntents,
|
||||||
ScheduledEventId, ScheduledEventStatus,
|
MessageBuilder, ScheduledEventId, ScheduledEventStatus,
|
||||||
};
|
};
|
||||||
use poise::CreateReply;
|
use poise::CreateReply;
|
||||||
use raas_types::raas::bot::roll::{roll_response, Roll, RollCmd};
|
use raas_types::raas::bot::roll::{roll_response, Roll, RollCmd};
|
||||||
|
@ -113,7 +113,7 @@ async fn create_session(
|
||||||
let path = ctx.data().config.session_config_path.clone();
|
let path = ctx.data().config.session_config_path.clone();
|
||||||
let mut session_config = ctx.data().session_config.lock().await;
|
let mut session_config = ctx.data().session_config.lock().await;
|
||||||
|
|
||||||
session_config.create_session(event.id).await;
|
session_config.create_session(event.id, &event.name);
|
||||||
|
|
||||||
session_config.save_config(path).await.unwrap();
|
session_config.save_config(path).await.unwrap();
|
||||||
|
|
||||||
|
@ -131,30 +131,75 @@ async fn start_session(
|
||||||
#[autocomplete = "autocomplete_session"]
|
#[autocomplete = "autocomplete_session"]
|
||||||
session: ScheduledEventId,
|
session: ScheduledEventId,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let sessions = &mut ctx.data().session_config.lock().await;
|
let event = {
|
||||||
|
let sessions = &mut ctx.data().session_config.lock().await;
|
||||||
|
|
||||||
let session = sessions
|
let session = sessions
|
||||||
.sessions
|
.sessions
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.event == session)
|
.find(|s| s.event == session)
|
||||||
.unwrap();
|
.cloned()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let event = match ctx
|
||||||
|
.guild_id()
|
||||||
|
.unwrap()
|
||||||
|
.scheduled_event(ctx.http(), session.event, false)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(e) => e,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Event '{}', no longer available", session.event);
|
||||||
|
|
||||||
|
sessions.remove_session(session.event);
|
||||||
|
|
||||||
|
sessions
|
||||||
|
.save_config(ctx.data().config.session_config_path.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sessions.active_session = Some(event.id);
|
||||||
|
|
||||||
|
sessions
|
||||||
|
.save_config(ctx.data().config.session_config_path.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
event
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.reply(format!("Started session '{}'", event.name))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
ctx.send(
|
||||||
|
CreateReply::default().reply(true).embed(
|
||||||
|
CreateEmbed::new()
|
||||||
|
.title(format!("{} started", event.name))
|
||||||
|
.field(
|
||||||
|
"Checklist",
|
||||||
|
ctx.data().config.checklist.format_as_markdown(),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Note: This needs to be done last to get around timeouts caused by editing the event during event processing
|
||||||
let event = ctx
|
let event = ctx
|
||||||
.guild_id()
|
.guild_id()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.edit_scheduled_event(
|
.edit_scheduled_event(
|
||||||
ctx.http(),
|
ctx.http(),
|
||||||
session.event,
|
event.id,
|
||||||
EditScheduledEvent::new().status(ScheduledEventStatus::Active),
|
EditScheduledEvent::new().status(ScheduledEventStatus::Active),
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
ctx.reply(format!("Started session '{}'", event.name))
|
info!("Started event '{}'", event.name);
|
||||||
.await?;
|
|
||||||
|
|
||||||
sessions.active_session = Some(event.id);
|
|
||||||
|
|
||||||
sessions.save_config(ctx.data().config.session_config_path.clone()).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -182,36 +227,29 @@ async fn stop_session(ctx: BotContext<'_>) -> Result<(), Error> {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sessions.remove_session(session);
|
||||||
} else {
|
} else {
|
||||||
ctx.reply("No sessions in progress!").await?;
|
ctx.reply("No sessions in progress!").await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
sessions.active_session = None;
|
sessions.active_session = None;
|
||||||
|
|
||||||
|
sessions
|
||||||
|
.save_config(ctx.data().config.session_config_path.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn autocomplete_session<'a>(
|
async fn autocomplete_session<'a>(
|
||||||
ctx: BotContext<'a>,
|
ctx: BotContext<'a>,
|
||||||
partial: &'a str,
|
partial: &'a str,
|
||||||
) -> impl Stream<Item = poise::serenity_prelude::AutocompleteChoice> + 'a {
|
) -> impl Stream<Item = AutocompleteChoice> + 'a {
|
||||||
let sessions: Vec<Session> = { ctx.data().session_config.lock().await.sessions.clone() };
|
let sessions: Vec<Session> = { ctx.data().session_config.lock().await.sessions.clone() };
|
||||||
|
|
||||||
futures::stream::iter(sessions).filter_map(move |s| async move {
|
futures::stream::iter(sessions).filter_map(move |s| async move {
|
||||||
let event = ctx
|
if s.name.matches(partial).count() > 0 {
|
||||||
.guild_id()
|
Some(AutocompleteChoice::new(s.name, s.event.to_string()))
|
||||||
.unwrap()
|
|
||||||
.scheduled_event(ctx.http(), s.event, false)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Ok(event) = event {
|
|
||||||
if event.status == ScheduledEventStatus::Scheduled
|
|
||||||
&& event.name.matches(partial).count() > 0
|
|
||||||
{
|
|
||||||
Some(AutocompleteChoice::new(event.name, event.id.to_string()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -221,7 +259,7 @@ async fn autocomplete_session<'a>(
|
||||||
pub async fn start_bot(config: BotConfig) {
|
pub async fn start_bot(config: BotConfig) {
|
||||||
info!("Starting bot!");
|
info!("Starting bot!");
|
||||||
|
|
||||||
let intents = poise::serenity_prelude::GatewayIntents::non_privileged();
|
let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::GUILD_SCHEDULED_EVENTS;
|
||||||
|
|
||||||
let token = config.bot_token.clone();
|
let token = config.bot_token.clone();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
|
use poise::serenity_prelude::MessageBuilder;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
@ -8,11 +9,29 @@ pub struct Args {
|
||||||
pub config_path: PathBuf,
|
pub config_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SessionCheckList {
|
||||||
|
steps: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionCheckList {
|
||||||
|
pub fn format_as_markdown(&self) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
for step in &self.steps {
|
||||||
|
msg.push_line(format!("* {}", step));
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct BotConfig {
|
pub struct BotConfig {
|
||||||
pub bot_token: String,
|
pub bot_token: String,
|
||||||
pub raas_url: String,
|
pub raas_url: String,
|
||||||
pub session_config_path: PathBuf,
|
pub session_config_path: PathBuf,
|
||||||
|
pub checklist: SessionCheckList,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BotConfig {
|
impl BotConfig {
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
|
pub name: String,
|
||||||
pub event: ScheduledEventId,
|
pub event: ScheduledEventId,
|
||||||
pub scenes: Vec<Scene>,
|
pub scenes: Vec<Scene>,
|
||||||
}
|
}
|
||||||
|
@ -45,10 +46,15 @@ impl SessionConfig {
|
||||||
tokio::fs::write(path, toml::to_string(self).unwrap()).await
|
tokio::fs::write(path, toml::to_string(self).unwrap()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_session(&mut self, event: ScheduledEventId) {
|
pub fn create_session(&mut self, event: ScheduledEventId, name: &str) {
|
||||||
self.sessions.push(Session {
|
self.sessions.push(Session {
|
||||||
|
name: name.to_string(),
|
||||||
event,
|
event,
|
||||||
scenes: vec![],
|
scenes: vec![],
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_session(&mut self, event: ScheduledEventId) {
|
||||||
|
self.sessions.retain(|s| s.event != event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue