use crate::prelude::*;
use anyhow::anyhow;
#[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.newag.enabled {
return;
}
bot.add_command(clap::Command::new("!rozprawa"), on_cmd_rozprawa);
}
type ParseError = String;
#[derive(Debug)]
#[allow(dead_code)]
struct Rozprawa {
wydział: String,
miejsce: String,
sygnatura: String,
data: String,
przewodniczący: String,
}
#[derive(Default)]
struct BuilderRozprawy {
wydział: Option<String>,
miejsce: Option<String>,
sygnatura: Option<String>,
data: Option<String>,
przewodniczący: Option<String>,
}
impl Rozprawa {
fn build() -> BuilderRozprawy { BuilderRozprawy::default() }
async fn fetch(http: &reqwest::Client) -> anyhow::Result<Self> {
let fragment = scraper::Html::parse_document(&http.get(
"https://bip.warszawa.so.gov.pl/e-wokanda/szukaj?keyword=&signature=XXII+GW+493%2F24&department_id=&start_time=&recaptcha_response=")
.send()
.await?
.text()
.await?);
let selector_tr = scraper::Selector::parse("table caption ~ * tr").unwrap();
let selector_th = scraper::Selector::parse("th").unwrap();
let selector_td = scraper::Selector::parse("td").unwrap();
let mut builder = Rozprawa::build();
for tr in fragment.select(&selector_tr) {
#[rustfmt::skip]
let th: String = tr
.select(&selector_th)
.next()
.unwrap()
.inner_html()
.trim()
.into();
let td: String = tr
.select(&selector_td)
.next()
.unwrap()
.inner_html()
.split_whitespace()
.collect::<Vec<_>>()
.join(" ");
match th.as_str() {
"Wydział" => builder.wydział(td),
"Miejsce rozprawy" => builder.miejsce(td),
"Sygnatura" => builder.sygnatura(td),
"Data" => builder.data(td),
"Przewodniczący" => builder.przewodniczący(td),
_ => &builder,
};
}
match builder.build() {
Ok(this) => Ok(this),
Err(e) => Err(anyhow!(e)),
}
}
}
impl BuilderRozprawy {
fn wydział(&mut self, wydział: String) -> &Self {
if self.wydział.is_none() {
self.wydział = Some(wydział);
}
self
}
fn miejsce(&mut self, miejsce: String) -> &Self {
if self.miejsce.is_none() {
self.miejsce = Some(miejsce);
}
self
}
fn sygnatura(&mut self, sygnatura: String) -> &Self {
if self.sygnatura.is_none() {
self.sygnatura = Some(sygnatura);
}
self
}
fn data(&mut self, data: String) -> &Self {
if self.data.is_none() {
self.data = Some(data);
}
self
}
fn przewodniczący(&mut self, przewodniczący: String) -> &Self {
if self.przewodniczący.is_none() {
self.przewodniczący = Some(przewodniczący);
}
self
}
fn build(self) -> Result<Rozprawa, ParseError> {
Ok(Rozprawa {
wydział: self.wydział.ok_or("missing 'wydział'")?,
miejsce: self.miejsce.ok_or("missing 'miejsce'")?,
sygnatura: self.sygnatura.ok_or("missing 'sygnatura'")?,
data: self.data.ok_or("missing 'data'")?,
przewodniczący: self.przewodniczący.ok_or("missing 'przewodniczący'")?,
})
}
}
async fn on_cmd_rozprawa(
_arg_matches: clap::ArgMatches,
_event: OriginalSyncRoomMessageEvent,
client: Client,
room: Room,
_bot: Rdzobot,
) -> anyhow::Result<()> {
let rozprawa = Rozprawa::fetch(client.http_client()).await?;
let content = RoomMessageEventContent::notice_plain(format!(
"następna rozprawa: {} {}",
&rozprawa.data, &rozprawa.miejsce
));
room.send(content).await?;
Ok(())
}