feat: implement RecordingDataManager::between and between_in_vc, start using it in /render

This commit is contained in:
2026-05-27 21:48:31 -04:00
parent 23f86ace3b
commit 0137f97788
3 changed files with 201 additions and 41 deletions

View File

@@ -1,3 +1,4 @@
use futures::TryStreamExt as _;
use snafu::{OptionExt as _, Report, ResultExt as _, Snafu};
use std::{collections::BTreeMap, sync::LazyLock};
use time::{UtcDateTime, format_description::well_known::Rfc3339};
@@ -85,7 +86,7 @@ pub static COMMAND: LazyLock<Command> = LazyLock::new(|| {
});
struct Options {
voice_channel: Id<ChannelMarker>,
voice_channel_id: Id<ChannelMarker>,
start: UtcDateTime,
end: UtcDateTime,
}
@@ -152,15 +153,15 @@ fn parse_options(interaction: &Interaction) -> Result<Options, ParseOptionsError
})
.collect();
let voice_channel = options
let voice_channel_id = options
.remove(OPTION_VOICE_CHANNEL)
.context(NoVoiceChannelSnafu)?;
let start = options.remove(OPTION_START).context(NoStartSnafu)?;
let end = options.remove(OPTION_END).context(NoEndSnafu)?;
let &CommandOptionValue::Channel(voice_channel) = voice_channel else {
let &CommandOptionValue::Channel(voice_channel_id) = voice_channel_id else {
return Err(ParseOptionsError::VoiceChannelInvalidType {
actual: voice_channel.clone(),
actual: voice_channel_id.clone(),
});
};
let &CommandOptionValue::String(ref start) = start else {
@@ -178,7 +179,7 @@ fn parse_options(interaction: &Interaction) -> Result<Options, ParseOptionsError
let end = UtcDateTime::parse(end, &DATE_FORMAT).context(EndInvalidDateSnafu)?;
Ok(Options {
voice_channel,
voice_channel_id,
start,
end,
})
@@ -186,6 +187,36 @@ fn parse_options(interaction: &Interaction) -> Result<Options, ParseOptionsError
#[tracing::instrument]
pub async fn handle(state: State, interaction: Interaction) {
let Some(guild_id) = interaction.guild_id else {
state
.discord_client
.interaction(state.discord_application_id)
.create_response(
interaction.id,
&interaction.token,
&InteractionResponse {
kind: InteractionResponseType::ChannelMessageWithSource,
data: Some(
InteractionResponseDataBuilder::new()
.embeds([EmbedBuilder::new()
.title("Not in a server")
.description(
"This command can only work when used in a Discord server.",
)
.validate()
.unwrap()
.build()])
.flags(MessageFlags::EPHEMERAL)
.build(),
),
},
)
.await
.expect("TODO");
return;
};
let bot_owner_user_id = state.discord_bot_owner_user_id;
let is_bot_owner = interaction
@@ -224,7 +255,7 @@ pub async fn handle(state: State, interaction: Interaction) {
}
let Options {
voice_channel,
voice_channel_id,
start,
end,
} = match parse_options(&interaction) {
@@ -253,9 +284,22 @@ pub async fn handle(state: State, interaction: Interaction) {
}
};
tracing::info!(?voice_channel, ?start, ?end);
let duration = end - start;
tracing::info!(?voice_channel_id, ?start, ?end, ?duration);
let mut recordings =
state
.recording_data_manager
.between_in_vc(start, end, guild_id, voice_channel_id);
while let Some(recording) = recordings.try_next().await.expect("TODO") {
tracing::debug!(?recording);
let recording_data = state
.recording_data_manager
.read(&recording)
.await
.expect("TODO");
tracing::debug!(?recording, ?recording_data);
}
todo!();
}