use pyo3::exceptions::PyAttributeError;
use pyo3::prelude::*;
use pyo3::types::PyTuple;
use crate::prelude::*;
#[derive(Debug, Deserialize)]
#[serde(default)]
#[doc(hidden)]
pub struct Config {
enabled: bool,
}
impl Default for Config {
fn default() -> Self { Self { enabled: true } }
}
#[doc(hidden)]
pub fn load(bot: Rdzobot) {
if !bot.config().module.rcb.enabled {
return;
}
pyo3::prepare_freethreaded_python();
bot.add_command(RcbCommand::command().name("!rcb"), on_cmd_rcb);
bot.add_command(RcbCommand::command().name("!pis"), on_cmd_pis);
}
#[derive(clap::Parser, Debug)]
struct RcbCommand {
template: Option<String>,
}
async fn on_cmd_rcb(
arg_matches: clap::ArgMatches,
event: OriginalSyncRoomMessageEvent,
client: Client,
room: Room,
bot: Rdzobot,
) -> anyhow::Result<()> {
on_cmd_inner("rcb", arg_matches, event, client, room, bot).await
}
async fn on_cmd_pis(
arg_matches: clap::ArgMatches,
event: OriginalSyncRoomMessageEvent,
client: Client,
room: Room,
bot: Rdzobot,
) -> anyhow::Result<()> {
on_cmd_inner("pis", arg_matches, event, client, room, bot).await
}
async fn on_cmd_inner(
module: &str,
mut arg_matches: clap::ArgMatches,
event: OriginalSyncRoomMessageEvent,
_client: Client,
room: Room,
_bot: Rdzobot,
) -> anyhow::Result<()> {
let args = RcbCommand::from_arg_matches_mut(&mut arg_matches).unwrap();
if let Ok(alert) = get_alert(module, args.template.as_deref()) {
let content = RoomMessageEventContent::notice_plain(alert);
room.send(content).await?;
} else {
nie_zesraj_się(&event, &room).await?;
}
Ok(())
}
fn get_alert_inner(py: Python, module: &str, template: Option<&str>) -> PyResult<String> {
let render = PyModule::import(py, "alertrcb.tlib")?.getattr("render")?;
let modname = String::from("alertrcb.templates_") + module;
let templates = PyModule::import(py, modname.as_str())?;
let mut attrname = String::from("TEMPLATE");
if let Some(tname) = template {
attrname.push('_');
attrname.push_str(tname);
}
let template = templates.getattr(attrname.as_str())?;
let args = PyTuple::new(py, &[template])?;
let result: String = render.call1(args)?.extract()?;
Ok(result)
}
pub fn get_alert(module: &str, template: Option<&str>) -> Result<String, String> {
Python::with_gil(|py| match get_alert_inner(py, module, template) {
Ok(result) => Ok(result),
Err(error) if error.is_instance_of::<PyAttributeError>(py) => {
Err("Nie zesraj się.".to_string())
}
Err(error) => Err(error.to_string()),
})
}