use matrix_sdk::ruma::EventId;
use matrix_sdk::ruma::events::reaction::OriginalSyncReactionEvent;
use crate::prelude::*;
use crate::utils::Location;
mod inpost;
mod orlen;
#[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(mut bot: Rdzobot) {
if !bot.config().module.parcels.enabled {
return;
}
bot.add_command(clap::Command::new("!paczki"), on_cmd_paczki);
bot.add_regex(regex::Regex::new(inpost::RE_PARCEL_INPOST_1).unwrap(), inpost::on_regex_inpost);
bot.add_regex(regex::Regex::new(orlen::RE_PARCEL_ORLEN).unwrap(), orlen::on_regex_orlen);
bot.add_event_handler(on_reaction);
}
async fn on_cmd_paczki(
_arg_matches: clap::ArgMatches,
_event: OriginalSyncRoomMessageEvent,
_client: Client,
room: Room,
bot: Rdzobot,
) -> anyhow::Result<()> {
let room_id = room.room_id().to_owned();
let (body, html_body) =
tokio::task::spawn_blocking(move || -> anyhow::Result<(String, String)> {
let sqlite = bot.sqlite();
let mut body = String::new();
let mut html_body = String::new();
html_body.push_str("<ul>");
let mut stmt = sqlite.prepare(
"SELECT
event_qr,
parcels.operator,
code,
parcels.ref,
lat,
lon,
time_end
FROM parcels
LEFT JOIN parcel_points ON
parcels.operator = parcel_points.operator AND parcels.ref = parcel_points.ref
WHERE
room = ?1 AND
unixepoch('now') < unixepoch(time_end)
ORDER BY unixepoch(time_end) ASC;",
)?;
for res in stmt.query_map((room_id.as_str(),), |row| {
let lat_res = row.get::<usize, f64>(4);
let lon_res = row.get::<usize, f64>(5);
Ok((
room_id
.matrix_to_event_uri(
EventId::parse(row.get::<usize, String>(0)?.as_str()).unwrap(),
)
.to_string(),
row.get::<usize, String>(2)?,
row.get::<usize, String>(3)?,
if let (Ok(lat), Ok(lon)) = (lat_res, lon_res) {
Some(Location::new(lat, lon))
} else {
None
},
row.get::<usize, chrono::DateTime<chrono::Utc>>(6)?,
))
})? {
let (href, id, ref_, location, time_end) = res?;
body.push_str(format!("- {} {} {}\n", id, ref_, time_end).as_str());
html_body.push_str(
format!(
"<li>{} <a href=\"{}\">[QR]</a> — {}{} — {}",
id,
href,
ref_,
if let Some(l) = location {
format!(" <a href=\"{}\">[MAP]</a>", l.osm_shortlink(None, true))
} else {
"".to_string()
},
time_end.with_timezone(&bot.config().timezone),
)
.as_str(),
);
}
html_body.push_str("</ul>");
Ok((body, html_body))
})
.await??;
if !body.is_empty() {
room.send(RoomMessageEventContent::notice_html(body, html_body)).await?;
} else {
room.send(RoomMessageEventContent::notice_plain("Nie ma paczek.")).await?;
}
Ok(())
}
async fn on_reaction(
event: OriginalSyncReactionEvent,
room: Room,
bot: Ctx<Rdzobot>,
) -> anyhow::Result<()> {
tokio::task::spawn_blocking(move || {
bot.sqlite()
.prepare(
"DELETE FROM parcels
WHERE (
room = ?1 AND (event_orig = ?2 OR event_qr = ?2)
) OR unixepoch(time_end) < unixepoch('now');",
)?
.execute((room.room_id().as_str(), event.content.relates_to.event_id.as_str()))?;
Ok(())
})
.await?
}