Added urban
This commit is contained in:
@@ -69,5 +69,136 @@ pub async fn say(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct UrbanResponse {
|
||||||
|
list: Vec<UrbanEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, Clone)]
|
||||||
|
struct UrbanEntry {
|
||||||
|
definition: String,
|
||||||
|
permalink: String,
|
||||||
|
thumbs_up: u64,
|
||||||
|
thumbs_down: u64,
|
||||||
|
author: String,
|
||||||
|
word: String,
|
||||||
|
example: String,
|
||||||
|
#[serde(rename = "written_on")]
|
||||||
|
written_on: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[poise::command(slash_command, prefix_command)]
|
||||||
|
pub async fn urban(
|
||||||
|
ctx: Context<'_>,
|
||||||
|
#[description = "Word to search for"] term: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
ctx.defer().await?;
|
||||||
|
|
||||||
|
let url = format!("https://api.urbandictionary.com/v0/define?term={}", term);
|
||||||
|
let response = reqwest::get(&url).await?.json::<UrbanResponse>().await?;
|
||||||
|
|
||||||
|
if response.list.is_empty() {
|
||||||
|
ctx.say(format!("No definition found for `{}`.", term)).await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let entries = response.list;
|
||||||
|
let mut current_page = 0;
|
||||||
|
let ctx_id = ctx.id();
|
||||||
|
let prev_custom_id = format!("{}prev", ctx_id);
|
||||||
|
let next_custom_id = format!("{}next", ctx_id);
|
||||||
|
|
||||||
|
let create_page = |page: usize, entries: &[UrbanEntry]| {
|
||||||
|
let entry = &entries[page];
|
||||||
|
let description = format!(
|
||||||
|
"{}\n\n**Example:**\n{}\n\n**Author:** {}\n**Date:** {}",
|
||||||
|
entry.definition.replace("[", "").replace("]", ""),
|
||||||
|
entry.example.replace("[", "").replace("]", ""),
|
||||||
|
entry.author,
|
||||||
|
entry.written_on
|
||||||
|
);
|
||||||
|
|
||||||
|
let description = if description.len() > 4096 {
|
||||||
|
format!("{}...", &description[..4093])
|
||||||
|
} else {
|
||||||
|
description
|
||||||
|
};
|
||||||
|
|
||||||
|
let embed = serenity::CreateEmbed::new()
|
||||||
|
.title(&entry.word)
|
||||||
|
.url(&entry.permalink)
|
||||||
|
.description(description)
|
||||||
|
.field("Thumbs Up", entry.thumbs_up.to_string(), true)
|
||||||
|
.field("Thumbs Down", entry.thumbs_down.to_string(), true)
|
||||||
|
.footer(serenity::CreateEmbedFooter::new(format!(
|
||||||
|
"Page {}/{}",
|
||||||
|
page + 1,
|
||||||
|
entries.len()
|
||||||
|
)))
|
||||||
|
.color(0xEFFF00);
|
||||||
|
|
||||||
|
let prev_button = serenity::CreateButton::new(&prev_custom_id)
|
||||||
|
.label("Previous")
|
||||||
|
.style(serenity::ButtonStyle::Primary)
|
||||||
|
.disabled(page == 0);
|
||||||
|
|
||||||
|
let next_button = serenity::CreateButton::new(&next_custom_id)
|
||||||
|
.label("Next")
|
||||||
|
.style(serenity::ButtonStyle::Primary)
|
||||||
|
.disabled(page == entries.len() - 1);
|
||||||
|
|
||||||
|
let components = vec![serenity::CreateActionRow::Buttons(vec![
|
||||||
|
prev_button,
|
||||||
|
next_button,
|
||||||
|
])];
|
||||||
|
|
||||||
|
(embed, components)
|
||||||
|
};
|
||||||
|
|
||||||
|
let (embed, components) = create_page(current_page, &entries);
|
||||||
|
ctx.send(
|
||||||
|
poise::CreateReply::default()
|
||||||
|
.embed(embed)
|
||||||
|
.components(components),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while let Some(mci) = serenity::ComponentInteractionCollector::new(ctx)
|
||||||
|
.author_id(ctx.author().id)
|
||||||
|
.channel_id(ctx.channel_id())
|
||||||
|
.timeout(std::time::Duration::from_secs(60 * 5))
|
||||||
|
.filter(move |mci| mci.data.custom_id == prev_custom_id || mci.data.custom_id == next_custom_id)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
if mci.data.custom_id == prev_custom_id {
|
||||||
|
if current_page > 0 {
|
||||||
|
current_page -= 1;
|
||||||
|
}
|
||||||
|
} else if mci.data.custom_id == next_custom_id {
|
||||||
|
if current_page < entries.len() - 1 {
|
||||||
|
current_page += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (embed, components) = create_page(current_page, &entries);
|
||||||
|
|
||||||
|
if let Err(e) = mci
|
||||||
|
.create_response(
|
||||||
|
ctx.http(),
|
||||||
|
serenity::CreateInteractionResponse::UpdateMessage(
|
||||||
|
serenity::CreateInteractionResponseMessage::new()
|
||||||
|
.embed(embed)
|
||||||
|
.components(components),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
tracing::error!("Failed to update urban message: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
void-sentinel
BIN
void-sentinel
Binary file not shown.
Reference in New Issue
Block a user