aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--Cargo.toml4
-rw-r--r--src/bot.rs8
-rw-r--r--src/commands/playback.rs58
-rw-r--r--src/commands/today/mod.rs21
5 files changed, 87 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0373af6..ec37269 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1076,6 +1076,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
name = "hyper"
version = "0.14.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3017,6 +3023,7 @@ dependencies = [
"envconfig_derive",
"fnv",
"grate",
+ "humantime",
"itertools",
"lazy_static",
"poise",
@@ -3037,6 +3044,7 @@ dependencies = [
"tokio",
"tokio-postgres",
"url",
+ "uuid",
"windows 0.58.0",
]
@@ -3567,9 +3575,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
-version = "1.8.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
+checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
dependencies = [
"getrandom",
]
diff --git a/Cargo.toml b/Cargo.toml
index 5ee41b1..ebc4348 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,6 +57,10 @@ timeago = "0.4"
fnv = "1.0"
dashmap = "6.0"
+humantime = "2.1"
+
+uuid = "1.10"
+
clap = { version = "4.5", features = ["derive"] }
envconfig = "0.10"
diff --git a/src/bot.rs b/src/bot.rs
index d9047e6..4ad22c6 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -69,6 +69,12 @@ impl TypeMapKey for VolumeKey {
type Value = DashMap<GuildId, f64>;
}
+pub struct PlaybackKey;
+
+impl TypeMapKey for PlaybackKey {
+ type Value = Arc<DashMap<uuid::Uuid, songbird::input::AuxMetadata>>;
+}
+
#[cfg(debug_assertions)]
const BOTNAME: &str = "thulani (dev)";
@@ -127,6 +133,7 @@ struct SongbirdHandler(Arc<Mutex<Call>>);
impl songbird::events::EventHandler for SongbirdHandler {
async fn act(&self, _ctx: &EventContext<'_>) -> Option<Event> {
let mut call = self.0.lock().await;
+
if call.queue().is_empty() {
let _ = call.leave().await;
}
@@ -416,6 +423,7 @@ pub async fn run() -> anyhow::Result<()> {
.register_songbird_from_config(sb_config)
.type_map_insert::<HttpKey>(reqwest::Client::new())
.type_map_insert::<VolumeKey>(DashMap::new())
+ .type_map_insert::<PlaybackKey>(Arc::new(DashMap::new()))
.framework(framework().await)
.await?;
diff --git a/src/commands/playback.rs b/src/commands/playback.rs
index 4d6d0be..e7bf830 100644
--- a/src/commands/playback.rs
+++ b/src/commands/playback.rs
@@ -1,4 +1,7 @@
-use std::sync::Arc;
+use std::{
+ fmt::Debug,
+ sync::Arc,
+};
use grate::tracing;
use serenity::prelude::*;
@@ -10,7 +13,10 @@ use songbird::{
use tap::Conv;
use crate::{
- bot::HttpKey,
+ bot::{
+ HttpKey,
+ PlaybackKey,
+ },
util,
PoiseContext,
PoiseData,
@@ -21,9 +27,7 @@ pub fn commands() -> impl IntoIterator<Item = poise::Command<PoiseData, anyhow::
}
pub async fn songbird(ctx: PoiseContext<'_>) -> anyhow::Result<(Arc<Songbird>, Arc<Mutex<Call>>)> {
- let Some(gid) = ctx.guild_id() else {
- return Err(anyhow::anyhow!("no guild id").into());
- };
+ let gid = util::guild_id(ctx)?;
let sb = songbird::get(ctx.serenity_context()).await.expect("acquiring songbird handle");
let call = sb.get_or_insert(gid);
@@ -196,19 +200,51 @@ pub async fn die(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
/// List queued audio.
#[poise::command(prefix_command, guild_only, category = "playback", aliases("queue"))]
pub async fn list(ctx: PoiseContext<'_>) -> anyhow::Result<()> {
- let (_sb, call) = songbird(ctx).await?;
+ let current_queue = {
+ let (_sb, call) = songbird(ctx).await?;
- let call = call.lock().await;
- let queue = call.queue();
+ let call = call.lock().await;
+ let queue = call.queue();
- if queue.current_queue().is_empty() {
+ queue.current_queue()
+ };
+
+ let playback_data = {
+ let data = ctx.serenity_context().data.read().await;
+ data.get::<PlaybackKey>().cloned().unwrap()
+ };
+
+ if current_queue.is_empty() {
util::reply(ctx, "nothing queued").await?;
}
- for track in queue.current_queue().into_iter() {
+ fn fmt_option<T>(name: &str, opt: Option<T>) -> String
+ where
+ T: std::fmt::Display,
+ {
+ if let Some(opt) = opt {
+ format!("{opt}")
+ } else {
+ format!("<no {name}>")
+ }
+ }
+
+ for track in current_queue.into_iter() {
let info = track.get_info().await?;
- let fmt = format!("track playing for {:?}", info.play_time);
+ let meta = playback_data.get(&track.uuid()).map(|x| x.clone());
+ let meta = meta.as_ref();
+
+ let fmt = format!(
+ "{}: {:?} / {}",
+ fmt_option("title", meta.and_then(|x| x.title.as_ref())),
+ humantime::format_duration(info.position),
+ fmt_option(
+ "duration",
+ meta.and_then(|x| x.duration.as_ref().map(|&dur| humantime::format_duration(dur)))
+ )
+ );
+
util::reply(ctx, fmt).await?;
}
diff --git a/src/commands/today/mod.rs b/src/commands/today/mod.rs
index f8f38c7..2c47e83 100644
--- a/src/commands/today/mod.rs
+++ b/src/commands/today/mod.rs
@@ -5,11 +5,17 @@ use rand::{
seq::SliceRandom,
thread_rng,
};
-use songbird::input::YoutubeDl;
+use songbird::input::{
+ Compose,
+ YoutubeDl,
+};
use tap::Conv;
use crate::{
- bot::HttpKey,
+ bot::{
+ HttpKey,
+ PlaybackKey,
+ },
commands::playback::songbird,
util,
PoiseContext,
@@ -117,12 +123,21 @@ pub async fn today(ctx: PoiseContext<'_>, #[rest] _rest: Option<String>) -> anyh
data.get::<HttpKey>().unwrap().clone()
};
- let input =
+ let mut input =
YoutubeDl::new_ytdl_like("yt-dlp", client.clone(), play_args.url.conv::<String>());
+ let meta = input.aux_metadata().await?;
+
let handle = call.enqueue_input(input.into()).await;
handle.set_volume(volume as _)?;
+ let playback = {
+ let data = ctx.serenity_context().data.read().await;
+ data.get::<PlaybackKey>().unwrap().clone()
+ };
+
+ playback.insert(handle.uuid(), meta);
+
let q = call.queue();
q.pause()?;
q.modify_queue(move |q| {