1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-22 02:54:21 +00:00

Add /quote command

This commit is contained in:
Steffo 2024-10-28 06:30:05 +01:00
parent a26bad4cf6
commit 5a5ff6d63d
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
4 changed files with 121 additions and 3 deletions

View file

@ -1,5 +1,5 @@
use diesel::{Identifiable, Insertable, Queryable, Selectable};
use diesel::pg::Pg; use diesel::pg::Pg;
use diesel::{Identifiable, Insertable, Queryable, QueryableByName, Selectable};
use crate::interfaces::database::models::users::RoyalnetUserId; use crate::interfaces::database::models::users::RoyalnetUserId;
use crate::newtype_sql; use crate::newtype_sql;
@ -17,7 +17,7 @@ pub struct DiarioAddition {
pub context: Option<String>, pub context: Option<String>,
} }
#[derive(Debug, Clone, PartialEq, Identifiable, Queryable, Selectable, Insertable)] #[derive(Debug, Clone, PartialEq, Identifiable, Queryable, Selectable, Insertable, QueryableByName)]
#[diesel(table_name = diario)] #[diesel(table_name = diario)]
#[diesel(check_for_backend(Pg))] #[diesel(check_for_backend(Pg))]
pub struct Diario { pub struct Diario {

View file

@ -26,7 +26,7 @@ pub mod cat;
pub mod roll; pub mod roll;
pub mod diario; pub mod diario;
pub mod matchmaking; pub mod matchmaking;
mod quote; pub mod quote;
type CommandResult = AnyResult<()>; type CommandResult = AnyResult<()>;
@ -59,6 +59,8 @@ pub enum Command {
Diario(diario::DiarioArgs), Diario(diario::DiarioArgs),
#[command(description = "Chiedi chi è disponibile per giocare a qualcosa.")] #[command(description = "Chiedi chi è disponibile per giocare a qualcosa.")]
Matchmaking(matchmaking::MatchmakingArgs), Matchmaking(matchmaking::MatchmakingArgs),
#[command(description = "Invia una riga dal diario RYG.")]
Quote(quote::QuoteArgs),
} }
impl Command { impl Command {
@ -107,6 +109,7 @@ impl Command {
Command::Roll(ref roll) => roll::handler(&bot, &message, roll).await, Command::Roll(ref roll) => roll::handler(&bot, &message, roll).await,
Command::Diario(ref args) => diario::handler(&bot, &message, args, &database).await, Command::Diario(ref args) => diario::handler(&bot, &message, args, &database).await,
Command::Matchmaking(ref args) => matchmaking::handler(&bot, &message, args, &database).await, Command::Matchmaking(ref args) => matchmaking::handler(&bot, &message, args, &database).await,
Command::Quote(ref id) => quote::handler(&bot, &message, id, &database).await,
}; };
log::trace!("Delegating error handling to error handler..."); log::trace!("Delegating error handling to error handler...");

View file

@ -0,0 +1,102 @@
use crate::interfaces::database::models::{Diario, RoyalnetUser};
use crate::services::telegram::commands::CommandResult;
use crate::services::telegram::dependencies::interface_database::DatabaseInterface;
use crate::utils::telegram_string::TelegramWrite;
use anyhow::Context;
use diesel::{sql_query, RunQueryDsl};
use std::str::FromStr;
use teloxide::payloads::SendMessageSetters;
use teloxide::requests::Requester;
use teloxide::types::{Message, ParseMode, ReplyParameters};
use teloxide::Bot;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct QuoteArgs {
id: Option<i32>,
}
impl FromStr for QuoteArgs {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.is_empty() {
Ok(
Self {
id: None
}
)
} else {
Ok(
Self {
id: Some(
s.parse()?
)
}
)
}
}
}
pub async fn handler(bot: &Bot, message: &Message, args: &QuoteArgs, database: &DatabaseInterface) -> CommandResult {
let author = message.from.as_ref()
.context("Non è stato possibile determinare chi abbia inviato il comando.")?;
let mut database = database.connect()?;
let _: RoyalnetUser = {
use diesel::prelude::*;
use diesel::{ExpressionMethods, QueryDsl};
use crate::interfaces::database::schema::telegram::dsl::*;
use crate::interfaces::database::schema::users::dsl::*;
use crate::interfaces::database::models::RoyalnetUser;
telegram
.filter(telegram_id.eq::<i64>(
author.id.0.try_into()
.context("Non è stato possibile processare il tuo ID Telegram per via di un overflow.")?
))
.inner_join(users)
.select(RoyalnetUser::as_select())
.get_result(&mut database)
.context("Non è stato possibile recuperare il tuo utente Telegram dal database RYG.")?
};
let entry = match args.id {
None => {
sql_query(include_str!("quote_random.sql"))
.load::<Diario>(&mut database)
.context("Non è stato possibile recuperare una riga di diario dal database RYG.")?
.into_iter()
.next()
.context("Non è stata trovata nessuna riga di diario nel database RYG.")?
}
Some(requested_id) => {
use crate::interfaces::database::query_prelude::*;
use crate::interfaces::database::schema::diario;
diario::table
.filter(diario::id.eq(requested_id))
.select(Diario::as_select())
.get_result(&mut database)
.context("Non è stato possibile recuperare la riga di diario specificata dal database RYG. Forse non esiste?")?
}
};
let text = format!(
"📖 Dal diario RYG...\n\
\n\
{}",
entry.to_string_telegram(),
);
let _reply = bot
.send_message(message.chat.id, text)
.parse_mode(ParseMode::Html)
.reply_parameters(ReplyParameters::new(message.id))
.await
// teloxide does not support blockquotes yet and errors out on parsing the response
// .context("Non è stato possibile inviare la risposta.")?
;
Ok(())
}

View file

@ -0,0 +1,13 @@
SELECT id,
saver_id,
saved_on,
quoted_id,
quoted_name,
warning,
quote,
context
FROM diario
TABLESAMPLE
system_time(10)
ORDER BY RANDOM()
LIMIT 1;