plenum-bot/src/hedgedoc.rs

103 lines
3.4 KiB
Rust
Raw Normal View History

use crate::config_spec::{CfgField, CfgGroup};
use reqwest::blocking::Client;
2024-08-02 22:29:22 +02:00
use reqwest::blocking::Response;
use std::error::Error;
pub const CONFIG: CfgGroup<'static> = CfgGroup {
name: "hedgedoc",
description: "HedgeDoc markdown pad server settings",
fields: &[
CfgField::Default {
key: "server-url",
default: "https://md.berlin.ccc.de",
description: "Hedgedoc server storing the pads.",
},
CfgField::Default {
key: "template-name",
default: "plenum-template",
description: "Name of the pad containing the template to use.",
},
CfgField::Generated {
key: "last-id",
generator: make_pad_id,
generator_description: "Makes a new pad that's completely empty.",
description: "ID of last plenum's pad.",
},
CfgField::Generated {
key: "next-id",
generator: make_pad_id,
generator_description: "Makes a new pad that's completely empty.",
description: "ID of next plenum's pad.",
},
],
};
2024-08-17 21:52:54 +02:00
#[derive(Debug)]
pub struct HedgeDoc {
2024-08-02 22:29:22 +02:00
server_url: String,
is_dry_run: bool,
client: Client,
}
impl HedgeDoc {
2024-08-02 22:29:22 +02:00
pub fn new(server_url: &str, is_dry_run: bool) -> Self {
Self { server_url: server_url.to_string(), is_dry_run, client: Client::new() }
}
2024-08-02 22:29:22 +02:00
pub fn format_url(&self, pad_name: &str) -> String {
format!("{}/{}", self.server_url, pad_name)
}
2024-08-02 22:29:22 +02:00
fn format_action(&self, pad_name: &str, verb: &str) -> String {
format!("{}/{}/{}", self.server_url, pad_name, verb)
}
2024-08-02 22:29:22 +02:00
fn do_request(&self, url: &str) -> Result<Response, Box<dyn Error>> {
Ok(self.client.get(url).send().unwrap())
}
2024-08-02 22:29:22 +02:00
fn get_id_from_response(&self, res: Response) -> String {
res.url().to_string().trim_start_matches(&format!("{}/", self.server_url)).to_string()
}
2024-08-02 22:29:22 +02:00
pub fn download(&self, pad_name: &str) -> Result<String, Box<dyn Error>> {
Ok(self.do_request(&self.format_action(pad_name, "download"))?.text()?)
}
2024-08-02 22:29:22 +02:00
pub fn create_pad(&self) -> Result<String, Box<dyn Error>> {
if self.is_dry_run {
todo!("NYI: sane dry-run behavior")
}
2024-08-02 22:29:22 +02:00
let res = self.do_request(&format!("{}/new", self.server_url)).unwrap();
if res.status().is_success() {
Ok(self.get_id_from_response(res))
} else {
2024-08-02 22:29:22 +02:00
Err(format!("Failed to create pad {}", res.status()).into())
}
}
2024-08-02 22:29:22 +02:00
pub fn import_note(&self, id: Option<&str>, content: String) -> Result<String, Box<dyn Error>> {
if self.is_dry_run {
todo!("NYI: sane dry-run behavior")
}
let url = match id {
2024-08-02 22:29:22 +02:00
Some(id) => self.format_url(&format!("new/{id}")),
None => self.format_url("new"),
};
2024-08-02 22:29:22 +02:00
let res =
self.client.post(&url).header("Content-Type", "text/markdown").body(content).send()?;
if res.status().is_success() {
Ok(self.get_id_from_response(res))
} else {
2024-08-02 22:29:22 +02:00
Err(format!("Failed to import note: {}", res.status()).into())
}
}
}
/// For the config, make a new pad ID (by actually making a pad.)
2024-08-17 06:40:26 +02:00
fn make_pad_id(_key: &str, config: &crate::KV, is_dry_run: bool) -> Result<String, Box<dyn Error>> {
HedgeDoc::new(&config.get("hedgedoc-server-url").unwrap(), is_dry_run).create_pad()
}