Skip to content

Commit f706606

Browse files
jaredledvinaclaude
andcommitted
Merge main into remind-command branch
- Resolve conflict in plugin list (keep both quotes and remind) - Rename 6_remind.sql to 7_remind.sql to avoid migration conflict Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2 parents 0180fea + 8cd11aa commit f706606

11 files changed

Lines changed: 343 additions & 7 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/target
22
**/*.rs.bk
33
/*.db
4+
/*.db-*
45
/.env
56
/.vscode
67
/.direnv

.sqlx/query-759e79ffa0012e64f6bf96cbbbe5dfe27bd7c0b628bb0008f7db33ad3ef501c3.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-a6e6fa376094fe896748c3b19a90cd1f5245d0837a0436f4e4e5557bb35ad0da.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
devShells.default = pkgs.mkShell {
4646
nativeBuildInputs = [
47-
(pkgs.rust-bin.stable."1.88.0".default.override {
47+
(pkgs.rust-bin.stable."1.93.0".default.override {
4848
extensions = [ "rust-src" ];
4949
})
5050
pkgs.rust-analyzer

migrations/6_quotes.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE IF NOT EXISTS quotes (
2+
nick text NOT NULL,
3+
quote text NOT NULL
4+
);
5+
6+
CREATE INDEX IF NOT EXISTS idx_quotes_nick ON quotes(nick);

src/plugin.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ pub async fn load(bot: Arc<Client>) -> Result<Vec<PluginMetadata>> {
4747
"barista",
4848
"chance",
4949
"forecast",
50+
"joke",
5051
"karma",
5152
"mention",
5253
"minecraft",
5354
"net_tools",
5455
"noaa",
56+
"quotes",
5557
"remind",
5658
"riddle",
5759
"scryfall",
@@ -138,6 +140,10 @@ pub async fn load(bot: Arc<Client>) -> Result<Vec<PluginMetadata>> {
138140
ret.push(start_plugin::<plugins::NoaaPlugin>(&bot)?);
139141
}
140142

143+
if config.plugin_enabled("quotes") {
144+
ret.push(start_plugin::<plugins::QuotesPlugin>(&bot)?);
145+
}
146+
141147
if config.plugin_enabled("riddle") {
142148
ret.push(start_plugin::<plugins::RiddlePlugin>(&bot)?);
143149
}
@@ -150,6 +156,10 @@ pub async fn load(bot: Arc<Client>) -> Result<Vec<PluginMetadata>> {
150156
ret.push(start_plugin::<plugins::IntrospectionPlugin>(&bot)?);
151157
}
152158

159+
if config.plugin_enabled("joke") {
160+
ret.push(start_plugin::<plugins::JokePlugin>(&bot)?);
161+
}
162+
153163
if config.plugin_enabled("help") {
154164
ret.push(start_plugin::<plugins::HelpPlugin>(&bot)?);
155165
}

src/plugins/joke.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use std::time::Duration;
2+
3+
use serde::Deserialize;
4+
5+
use crate::prelude::*;
6+
7+
const API_BASE: &str = "https://v2.jokeapi.dev/joke";
8+
const CATEGORIES: &[&str] = &["any", "misc", "programming", "pun", "spooky", "christmas"];
9+
10+
pub struct JokePlugin {
11+
client: reqwest::Client,
12+
}
13+
14+
#[derive(Deserialize)]
15+
struct JokeResponse {
16+
error: bool,
17+
#[serde(rename = "type")]
18+
joke_type: String,
19+
joke: Option<String>,
20+
setup: Option<String>,
21+
delivery: Option<String>,
22+
message: Option<String>,
23+
}
24+
25+
impl JokePlugin {
26+
async fn fetch_joke(&self, category: &str) -> Result<JokeResponse> {
27+
let url = format!("{}/{}?safe-mode", API_BASE, category);
28+
29+
let resp: JokeResponse = self
30+
.client
31+
.get(&url)
32+
.send()
33+
.await?
34+
.error_for_status()?
35+
.json()
36+
.await?;
37+
38+
if resp.error {
39+
return Err(format_err!(
40+
"{}",
41+
resp.message
42+
.unwrap_or_else(|| "Unknown API error".to_string())
43+
));
44+
}
45+
46+
Ok(resp)
47+
}
48+
49+
async fn handle_joke(&self, ctx: &Arc<Context>, arg: Option<&str>) -> Result<()> {
50+
let category = arg.unwrap_or("Any");
51+
52+
let joke = self.fetch_joke(category).await?;
53+
54+
match joke.joke_type.as_str() {
55+
"single" => {
56+
if let Some(text) = joke.joke {
57+
ctx.reply(&text).await?;
58+
}
59+
}
60+
"twopart" => {
61+
if let (Some(setup), Some(delivery)) = (joke.setup, joke.delivery) {
62+
ctx.reply(&setup).await?;
63+
tokio::time::sleep(Duration::from_secs(3)).await;
64+
ctx.reply(&delivery).await?;
65+
}
66+
}
67+
joke_type => return Err(format_err!("unexpected joke type {}", joke_type)),
68+
}
69+
70+
Ok(())
71+
}
72+
}
73+
74+
#[async_trait]
75+
impl Plugin for JokePlugin {
76+
fn new_from_env() -> Result<Self> {
77+
let client = reqwest::Client::builder()
78+
.timeout(Duration::from_secs(5))
79+
.build()?;
80+
Ok(JokePlugin { client })
81+
}
82+
83+
fn command_metadata(&self) -> Vec<CommandMetadata> {
84+
vec![CommandMetadata {
85+
name: "joke".to_string(),
86+
short_help: format!(
87+
"usage: joke [category]. Categories: {}",
88+
CATEGORIES.join(", ")
89+
),
90+
full_help: format!("Gets a random joke. Categories: {}", CATEGORIES.join(", ")),
91+
}]
92+
}
93+
94+
async fn run(self, bot: Arc<Client>) -> Result<()> {
95+
let mut stream = bot.subscribe();
96+
97+
while let Ok(ctx) = stream.recv().await {
98+
let res = match ctx.as_event() {
99+
Ok(Event::Command("joke", arg)) => self.handle_joke(&ctx, arg).await,
100+
_ => Ok(()),
101+
};
102+
103+
crate::check_err(&ctx, res).await;
104+
}
105+
106+
Err(format_err!("joke plugin lagged"))
107+
}
108+
}

src/plugins/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ pub use self::scryfall::ScryfallPlugin;
3131
mod introspection;
3232
pub use self::introspection::IntrospectionPlugin;
3333

34+
mod joke;
35+
pub use self::joke::JokePlugin;
36+
37+
mod quotes;
38+
pub use self::quotes::QuotesPlugin;
39+
3440
mod help;
3541
pub use self::help::HelpPlugin;
3642

0 commit comments

Comments
 (0)