diff --git a/Cargo.toml b/Cargo.toml index f01c9b3..bc05e47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,8 @@ lettre = "0.11.7" rand = "0.9.0-alpha.1" rusqlite = "0.31.0" uuid = { version = "1.10.0", features = ["v4"] } -log = "0.4.22" \ No newline at end of file +log = "0.4.22" +mediawiki = "0.3.1" +serde = { version = "1.0.204", features = ["derive"] } +api = "0.2.0" +base64 = "0.22.1" \ No newline at end of file diff --git a/src/create_new_pads.rs b/src/create_new_pads.rs index ef31333..e5b457f 100644 --- a/src/create_new_pads.rs +++ b/src/create_new_pads.rs @@ -1,18 +1,18 @@ -use reqwest::Client; +use reqwest::blocking::Client; use std::error::Error; -pub async fn create_pad(client: &Client, hedgedoc_url: &str) -> Result> { - let res = client.get(format!("{}/new", hedgedoc_url)).send().await?; +pub fn create_pad(client: &Client, hedgedoc_url: &str) -> Result> { + let resp = client.get(format!("{}/new", hedgedoc_url)).send().unwrap(); - if res.status().is_success() { - let pad_url = res.url().to_string(); + if resp.status().is_success() { + let pad_url: String = resp.url().to_string(); Ok(pad_url) } else { - Err(format!("Failed to create pad: {} - {}", res.status(), res.text().await?).into()) + Err(format!("Failed to create pad: {} - {:?}", resp.status(), resp.text()).into()) } } -pub async fn import_note(client: &Client, content: String, note_id: Option<&str>, hedgedoc_url: &str) -> Result> { +pub fn import_note(client: &Client, content: String, note_id: Option<&str>, hedgedoc_url: &str) -> Result> { let post_url = match note_id { Some(id) => format!("{}/new/{}", hedgedoc_url, id), None => format!("{}/new", hedgedoc_url), @@ -22,17 +22,17 @@ pub async fn import_note(client: &Client, content: String, note_id: Option<&str> println!("Content Parsed:"); println!("{}", content_parsed); - let res = client.post(&post_url) + let resp = client.post(&post_url) .header("Content-Type", "text/markdown") .body(content_parsed) .send() - .await?; + .unwrap(); - if res.status().is_success() { - let final_url = res.url().to_string(); + if resp.status().is_success() { + let final_url = resp.url().to_string(); Ok(final_url) } else { - Err(format!("Failed to import note: {} - {}", res.status(), res.text().await?).into()) + Err(format!("Failed to import note: {} - {}", resp.status(), resp.text()?).into()) } } /* diff --git a/src/main.rs b/src/main.rs index 92d346c..f179eef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,35 +19,41 @@ Pad-ins-Wiki-und-versenden-Skript • Neue Wiki-Seite erstellen und dort das umgewandelte Pad hochladen */ -// Import other .rs files as modules -mod key_value; - use std::borrow::Cow; -use key_value::KeyValueStore as KV; -mod create_new_pads; -pub mod variables_and_settings; - -use chrono::{Datelike, Local, NaiveDate, Weekday}; -use regex::Regex; -use uuid::Uuid; -use reqwest::Client; +use std::collections::HashMap; use std::error::Error; -// use std::future::Future; - -// For MediaWiki-conversion -use pandoc; -use std::io; -use std::io::prelude::*; use std::fs::File; +use std::io::prelude::*; -// use std::process::Command; -// use headers::ContentType; - +use api::Api; +use chrono::{Datelike, Local, NaiveDate, Weekday}; // MAIL START use lettre::{Message, SmtpTransport, Transport}; use lettre::message::{header, SinglePart}; use lettre::transport::smtp::authentication::Credentials; -use pandoc::{MarkdownExtension, Pandoc, PandocError, PandocOutput}; +// For MediaWiki-conversion +use pandoc; +use regex::Regex; +use reqwest::blocking::{Client, get, Response}; +use reqwest::header as rqwheader; +use serde::Deserialize; +use uuid::Uuid; +use mediawiki; +use base64::Engine; + +use key_value::KeyValueStore as KV; + +// Import other .rs files as modules +mod key_value; + +mod create_new_pads; +pub mod variables_and_settings; + +// use std::future::Future; + +// use std::process::Command; +// use headers::ContentType; + // MAIL END #[derive(PartialEq)] @@ -72,8 +78,8 @@ fn kv_defaults (kv: &KV) { // email-last-message-id has no default kv.default("email-signature", "\n\n[Diese Nachricht wurde automatisiert vom Plenumsbot erstellt und ist daher ohne Unterschrift gültig.]"); } -#[tokio::main] -async fn main() -> Result<(), Box> { + +fn main() -> Result<(), Box> { // config let config = KV::new("plenum_config.sqlite").unwrap(); kv_defaults(&config); @@ -139,7 +145,7 @@ async fn main() -> Result<(), Box> { let yesterday_was_plenum = true; // Das ist nur zu Testzwecken, kommt noch weg if in_1_day_is_plenum { println!("In 1 Tag ist Plenum, deshalb wird eine Erinnerung raus geschickt!"); - let pad_content = download_and_return_pad(format!("{}/download", current_pad_link.clone())).await.expect("Fehler beim Download des Pads!"); + let pad_content = download_and_return_pad(format!("{}/download", current_pad_link.clone())).expect("Fehler beim Download des Pads!"); let pad_content_without_top_instructions = try_to_remove_top_instructions(pad_content); let tldr_vec = create_tldr(&pad_content_without_top_instructions); let mut tldr = String::new(); @@ -163,7 +169,7 @@ async fn main() -> Result<(), Box> { } } else if in_3_days_is_plenum { println!("In 3 Tagen ist Plenum, deshalb wird eine Erinnerung raus geschickt!"); - let pad_content = download_and_return_pad(current_pad_link.clone()).await.expect("Fehler beim Download des Pads!"); + let pad_content = download_and_return_pad(current_pad_link.clone()).expect("Fehler beim Download des Pads!"); let pad_content_without_top_instructions = try_to_remove_top_instructions(pad_content); println!("Pad-content geladen!"); if number_of_tops(&pad_content_without_top_instructions) == 0 { @@ -176,8 +182,8 @@ async fn main() -> Result<(), Box> { println!("message id: {}", message_id) } else if yesterday_was_plenum { // This logic breaks on 02/2034, but on every other month it works - let old_pad_content = download_and_return_pad(format!("{}/download", current_pad_link.clone())).await.expect("Fehler beim Download des Pads!"); - // MUSS WIEDER REIN NACH DEM TESTEN: generate_new_pad_for_following_date(übernächster_plenumtermin, überübernächster_plenumtermin, &config).await.expect("Fehler! Plenumspad konnte nicht generiert werden!"); + let old_pad_content = download_and_return_pad(format!("{}/download", current_pad_link.clone())).expect("Fehler beim Download des Pads!"); + // MUSS WIEDER REIN NACH DEM TESTEN: generate_new_pad_for_following_date(übernächster_plenumtermin, überübernächster_plenumtermin, &config).expect("Fehler! Plenumspad konnte nicht generiert werden!"); println!("DATENBANK: aktuelles-plenumspad: {:?} und zukünftiges plenumspad: {:?}", &config.get("aktuelles-plenumspad"), &config.get("zukünftiges-plenumspad")); let old_pad_content_without_top_instructions = try_to_remove_top_instructions(old_pad_content); @@ -200,12 +206,10 @@ async fn main() -> Result<(), Box> { } -async fn download_and_return_pad(pad_link: String) -> Result> { +fn download_and_return_pad(pad_link: String) -> Result> { //https://md.berlin.ccc.de/OlizTqsSQEeqil0OZmo-Qw/download - let pad_content: String = reqwest::get(pad_link) - .await? - .text() - .await?; + let pad_content: String = reqwest::blocking::get(pad_link)? + .text()?; //println!("{}", pad_content); Ok(pad_content) } @@ -298,17 +302,17 @@ fn mail_versenden(inhalt: String, betreff: String) -> std::result::Result Result<(), Box> { let client = Client::new(); - match create_new_pads::create_pad(&client, HEDGEDOC_SERVER_URL).await { + match create_new_pads::create_pad(&client, HEDGEDOC_SERVER_URL) { Ok(pad_url) => { println!("Pad created successfully at URL: {}", pad_url); // Get the most recent plenum template and replace the placeholders: - let template_from_pad = download_and_return_pad(PLENUM_TEMPLATE_URL.to_string()).await; // Download Pad + let template_from_pad = download_and_return_pad(PLENUM_TEMPLATE_URL.to_string()); // Download Pad let template_content: String = template_from_pad.unwrap_or_else(|error| FALLBACK_TEMPLATE.to_string()); // If Download wasn't successful, use offline Template let template_modified: String = replace_placeholders(&template_content, übernächster_plenumtermin, überübernächster_plenumtermin).unwrap_or_else(|error |template_content); // Try regex, if not successful use without regex let future_pad_id: &str = pad_url.trim_start_matches(&format!("{}/", HEDGEDOC_SERVER_URL)); - match create_new_pads::import_note(&client, template_modified, Some(future_pad_id), HEDGEDOC_SERVER_URL).await { + match create_new_pads::import_note(&client, template_modified, Some(future_pad_id), HEDGEDOC_SERVER_URL) { Ok(_) => { println!("Pad updated successfully with template content."); rotate (future_pad_id, kv); @@ -345,27 +349,53 @@ fn try_to_remove_top_instructions (pad_content: String) -> String { result.to_string() // Wenn es nicht geklappt hat, wird einfach das Pad mit dem Kommentar zurückgegeben } - - fn pad_ins_wiki(old_pad_content: String) { + convert_markdown_to_mediawiki_and_save_as_txt(old_pad_content); + + // Textdatei wieder einlesen + let mut file = File::open("pandoc-output.txt").expect("Fehler beim öffnen der MediaWiki-Textdatei!"); + let mut contents = String::new(); + file.read_to_string(&mut contents).expect("Fehler beim auslesen der MediaWiki-Textdatei!"); + + // Passwörter aus Datenbank lesen (ToBeDone) + let plenum_bot_user = String::from("PlenumBot@PlenumBot-PW1"); + let plenum_bot_pw = String::from("**OLD_API_PW_REMOVED**"); + let login_token = login_to_mediawiki(plenum_bot_user.clone(), plenum_bot_pw.clone()).expect("Fehler beim Einloggen!"); + println!("plenum_bot_user: {plenum_bot_user}, plenum_bot_pw: {plenum_bot_pw}, login_token: {login_token}") +} + +fn convert_markdown_to_mediawiki_and_save_as_txt (old_pad_content: String) { //Convert Markdown into Mediawiki // Vanilla pandoc Befehl: pandoc --from markdown --to mediawiki --no-highlight let mut p = pandoc::new(); p.set_input(pandoc::InputKind::Pipe(old_pad_content)); p.set_input_format(pandoc::InputFormat::Markdown, vec![]); - // p.set_output_format(Pandoc::OutputFormat::mediawiki, vec![MarkdownExtension::Smart]); p.set_output(pandoc::OutputKind::File("./pandoc-output.txt".parse().unwrap())); p.set_output_format(pandoc::OutputFormat::MediaWiki, vec![]); p.execute().expect("Fehler beim Umwandeln des und speichern des Pads in eine mediawiki-Textdatei"); - - // Textdatei wieder einlesen - let mut file = File::open("pandoc-output.txt").expect("Fehler beim öffnen der MediaWiki-Textdatei!"); - let mut contents = String::new(); - file.read_to_string(&mut contents).expect("Fehler beim auslesen der MediaWiki-Textdatei!"); - - // Passwörter aus Datenbank lesen (ToBeDone) - let plenum_bot_user = String::from("PlenumBot@PlenumBot-PW1"); - let plenum_bot_pw = String::from("**OLD_API_PW_REMOVED**"); - - } + +fn login_to_mediawiki (plenum_bot_user: String, plenum_bot_pw: String) -> Result> { + //let mut map = HashMap::new(); + //map.insert("logintoken", "result"); + let username = "cccb-wiki"; + let password = "**OLD_PW_REMOVED**"; + let auth_header_value = format!("{}:{}", username, password); + // let auth_header_value = format!("Basic {}", Engine::encode(&auth_value, ())); + + let client = reqwest::blocking::Client::new(); + let resp = client + .get("https://wiki.berlin.ccc.de/api.php?action=query&meta=tokens&type=login&format=json") + .send()? + .text()?; + //let response = client + // .post("https://wiki.berlin.ccc.de/api.php?action=query&meta=tokens&type=login&format=json") + // .form(&[("Username", "cccb-wiki"), ("Password", "**OLD_PW_REMOVED**")]) + // .send() + // .unwrap(); + //.json(&map); + let html_source = resp.text()?; + //let login_token: String = map.get("logintoken").unwrap().to_string().clone(); + println!("---HTML:---\n{}\n-----------", html_source); + Ok(String::from("unimplemented")) +} \ No newline at end of file