1 Commits

Author SHA1 Message Date
a2ac7050d7 Add additional indexes 2023-10-21 17:58:31 +01:00
8 changed files with 57 additions and 247 deletions

116
Cargo.lock generated
View File

@ -139,55 +139,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.68"
@ -1129,12 +1080,6 @@ dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.5.0"
@ -1604,27 +1549,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prometheus"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c"
dependencies = [
"cfg-if",
"fnv",
"lazy_static",
"memchr",
"parking_lot 0.12.1",
"protobuf",
"thiserror",
]
[[package]]
name = "protobuf"
version = "2.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
[[package]]
name = "quote"
version = "1.0.29"
@ -2022,16 +1946,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.14"
@ -2217,14 +2131,12 @@ dependencies = [
name = "soundfx-rs"
version = "1.5.11"
dependencies = [
"axum",
"dashmap",
"dotenv",
"env_logger",
"lazy_static",
"log",
"poise",
"prometheus",
"regex",
"reqwest",
"serde",
@ -2425,12 +2337,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "tempfile"
version = "3.6.0"
@ -2623,28 +2529,6 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"

View File

@ -20,11 +20,6 @@ serde_json = "1.0"
dashmap = "5.3"
serde = "1.0"
dotenv = "0.15.0"
prometheus = { version = "0.13.3", optional = true }
axum = { version = "0.6.20", optional = true }
[features]
metrics = ["dep:prometheus", "dep:axum"]
[patch."https://github.com/serenity-rs/serenity"]
serenity = { version = "0.11.6" }

View File

@ -0,0 +1,6 @@
-- Add migration script here
ALTER TABLE `sounds` ADD UNIQUE INDEX `uploader_id_name` (`uploader_id`, `name`);
ALTER TABLE `sounds` ADD INDEX `name` (`name`);
ALTER TABLE `sounds` ADD INDEX `public` (`public`);
ALTER TABLE `sounds` ADD INDEX `uploader_id` (`uploader_id`);
ALTER TABLE `sounds` ADD INDEX `server_id` (`server_id`);

View File

@ -1,16 +1,12 @@
use std::time::{SystemTime, UNIX_EPOCH};
use poise::serenity_prelude::{
builder::CreateActionRow, model::application::component::ButtonStyle, GuildChannel,
ReactionType,
};
#[cfg(feature = "metrics")]
use crate::metrics::PLAY_COUNTER;
use crate::{
cmds::autocomplete_sound,
models::{guild_data::CtxGuildData, sound::SoundCtx},
utils::{join_channel, play_audio, play_from_query, queue_audio},
utils::{join_channel, play_from_query, queue_audio},
Context, Error,
};
@ -29,9 +25,6 @@ pub async fn play(
let guild = ctx.guild().unwrap();
#[cfg(feature = "metrics")]
PLAY_COUNTER.inc();
ctx.say(
play_from_query(
&ctx.serenity_context(),
@ -49,70 +42,6 @@ pub async fn play(
Ok(())
}
/// Play a random sound from this server
#[poise::command(
slash_command,
rename = "random",
default_member_permissions = "SPEAK",
guild_only = true
)]
pub async fn play_random(
ctx: Context<'_>,
#[description = "Channel to play in (default: your current voice channel)"]
#[channel_types("Voice")]
channel: Option<GuildChannel>,
) -> Result<(), Error> {
ctx.defer().await?;
let guild = ctx.guild().unwrap();
let channel_to_join = channel.map(|c| c.id).or_else(|| {
guild
.voice_states
.get(&ctx.author().id)
.and_then(|voice_state| voice_state.channel_id)
});
match channel_to_join {
Some(channel) => {
let (call_handler, _) =
join_channel(ctx.serenity_context(), guild.clone(), channel).await;
let sounds = ctx.data().guild_sounds(guild.id, None).await?;
let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
// This is far cheaper and easier than using an RNG. No reason to use a full RNG here
// anyway.
match sounds.get(ts.subsec_micros() as usize % sounds.len()) {
Some(sound) => {
let guild_data = ctx.data().guild_data(guild.id).await.unwrap();
let mut lock = call_handler.lock().await;
play_audio(
sound,
guild_data.read().await.volume,
&mut lock,
&ctx.data().database,
false,
)
.await
.unwrap();
}
None => {
ctx.say("No sounds in this server!").await?;
}
}
}
None => {
ctx.say("You are not in a voice chat!").await?;
}
}
Ok(())
}
/// Play up to 25 sounds on queue
#[poise::command(
slash_command,

View File

@ -1,8 +1,11 @@
use std::{collections::HashMap, env};
use poise::serenity_prelude::{
model::{
application::interaction::{Interaction, InteractionResponseType},
channel::Channel,
},
utils::shard_id,
ActionRowComponent, Activity, Context, CreateActionRow, CreateComponents,
};
@ -22,6 +25,46 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
poise::Event::Ready { .. } => {
ctx.set_activity(Activity::watching("for /play")).await;
}
poise::Event::GuildCreate { guild, is_new, .. } => {
if *is_new {
if let Ok(token) = env::var("DISCORDBOTS_TOKEN") {
let shard_count = ctx.cache.shard_count();
let current_shard_id = shard_id(guild.id.as_u64().to_owned(), shard_count);
let guild_count = ctx
.cache
.guilds()
.iter()
.filter(|g| {
shard_id(g.as_u64().to_owned(), shard_count) == current_shard_id
})
.count() as u64;
let mut hm = HashMap::new();
hm.insert("server_count", guild_count);
hm.insert("shard_id", current_shard_id);
hm.insert("shard_count", shard_count);
let response = data
.http
.post(
format!(
"https://top.gg/api/bots/{}/stats",
ctx.cache.current_user_id().as_u64()
)
.as_str(),
)
.header("Authorization", token)
.json(&hm)
.send()
.await;
if let Err(res) = response {
println!("DiscordBots Response: {:?}", res);
}
}
}
}
poise::Event::VoiceStateUpdate { old, new, .. } => {
if let Some(past_state) = old {
if let (Some(guild_id), None) = (past_state.guild_id, new.channel_id) {
@ -62,9 +105,10 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
let mut sound = sqlx::query_as_unchecked!(
Sound,
"
SELECT name, id, public, server_id, uploader_id
SELECT name, id, public, server_id, uploader_id
FROM sounds
WHERE id = ?",
WHERE id = ?
",
join_id
)
.fetch_one(&data.database)

View File

@ -5,8 +5,6 @@ mod cmds;
mod consts;
mod error;
mod event_handlers;
#[cfg(feature = "metrics")]
mod metrics;
mod models;
mod utils;
@ -87,7 +85,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
cmds::manage::download_file(),
cmds::manage::delete_sound(),
cmds::play::play(),
cmds::play::play_random(),
cmds::play::queue_play(),
cmds::play::loop_play(),
cmds::play::soundboard(),
@ -106,6 +103,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
],
..cmds::favorite::favorites()
},
cmds::search::show_random_sounds(),
cmds::search::search_sounds(),
cmds::stop::stop_playing(),
cmds::stop::disconnect(),
@ -144,12 +142,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
sqlx::migrate!().run(&database).await?;
#[cfg(feature = "metrics")]
{
metrics::init_metrics();
tokio::spawn(async { metrics::serve().await });
}
poise::Framework::builder()
.token(discord_token)
.setup(move |ctx, _bot, framework| {

View File

@ -1,40 +0,0 @@
use std::net::SocketAddr;
use axum::{routing::get, Router};
use lazy_static;
use log::warn;
use prometheus::{register_int_counter, IntCounter, Registry};
lazy_static! {
static ref REGISTRY: Registry = Registry::new();
pub static ref PLAY_COUNTER: IntCounter =
register_int_counter!("play", "Number of calls to /play").unwrap();
}
pub fn init_metrics() {
REGISTRY.register(Box::new(PLAY_COUNTER.clone())).unwrap();
}
pub async fn serve() {
let app = Router::new().route("/", get(metrics));
let addr = SocketAddr::from(([127, 0, 0, 1], 31755));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn metrics() -> String {
let encoder = prometheus::TextEncoder::new();
let res_custom = encoder.encode_to_string(&REGISTRY.gather());
match res_custom {
Ok(s) => s,
Err(e) => {
warn!("Error encoding metrics: {:?}", e);
String::new()
}
}
}

View File

@ -106,7 +106,7 @@ pub async fn play_from_query(
user_id: UserId,
channel: Option<ChannelId>,
query: &str,
r#loop: bool,
loop_: bool,
) -> String {
let guild_id = guild.id;
@ -141,7 +141,7 @@ pub async fn play_from_query(
guild_data.read().await.volume,
&mut lock,
&data.database,
r#loop,
loop_,
)
.await
.unwrap();