From abbfef233f4b022c7373f71e2ba7040e843579dc Mon Sep 17 00:00:00 2001 From: murmeldin Date: Tue, 23 Jul 2024 21:11:36 +0200 Subject: [PATCH] added rotate-function --- src/main.rs | 109 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5a5329d..6fb9e95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,41 +40,43 @@ use lettre::{Message, SmtpTransport, Transport}; use lettre::message::{header, SinglePart}; use lettre::message::header::MessageId; use lettre::transport::smtp::authentication::Credentials; -use log::error; // MAIL END const HEDGEDOC_SERVER_URL: &str = variables_and_settings::HEDGEDOC_SERVER_URL; const PLENUM_TEMPLATE_URL: &str = variables_and_settings::PLENUM_TEMPLATE_URL; const FALLBACK_TEMPLATE: &str = variables_and_settings::FALLBACK_TEMPLATE; +const TESTING_MODE: bool = true; -fn kv_defaults (kv: KV) { +fn kv_defaults (kv: &KV) { kv.default("template-url", "https://md.berlin.ccc.de/plenum-template"); 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() { // BEGIN ANKÜNDIGUNGSSCRIPT - + // config let config = KV::new("plenum_config.sqlite").unwrap(); - kv_defaults(config); + kv_defaults(&config); // Dienstage diesen Monat let all_tuesdays: Vec> = get_tuesdays(0); let zweiter_dienstag: String = all_tuesdays[1].unwrap().to_string(); // z.B. 2024-07-09 let vierter_dienstag: String = all_tuesdays[3].unwrap().to_string(); // z.B. 2024-07-23 - //Dienstage nächsten Monat + //Dienstage des nächsten Monats definieren let all_tuesdays_next_month: Vec> = get_tuesdays(1); let zweiter_dienstag_nächster_monat: String = all_tuesdays_next_month[1].unwrap().to_string(); - let _vierter_dienstag_nächster_monat: String = all_tuesdays_next_month[3].unwrap().to_string(); + let vierter_dienstag_nächster_monat: String = all_tuesdays_next_month[3].unwrap().to_string(); + // Daten, die später benutzt werden, definieren let today= Local::now(); let today_simple = NaiveDate::from_ymd_opt(today.year(), today.month(), today.day()).unwrap(); let in_1_day: NaiveDate = NaiveDate::from_ymd_opt(today.year(), today.month(), today.day()).unwrap().succ_opt().unwrap(); let in_2_days: NaiveDate = in_1_day.succ_opt().unwrap(); let in_3_days: NaiveDate = in_2_days.succ_opt().unwrap(); + let yesterday: NaiveDate = NaiveDate::from_ymd_opt(today.year(), today.month(), today.day()).unwrap().pred_opt().unwrap(); // Nächste Plena nachschauen: @@ -89,52 +91,73 @@ async fn main() { } else { zweiter_dienstag_nächster_monat.clone() }; + let überübernächster_plenumtermin = if all_tuesdays[1].unwrap() >= today_simple.pred_opt().unwrap() { // hier das Gleiche. + zweiter_dienstag_nächster_monat.clone() + } else { + vierter_dienstag_nächster_monat + }; + + // Der Code muss nur für vor dem 2. und vor dem 4. Dienstag gebaut werden, weil im nächsten Monat der Code frühestens 7 Tage vor dem Plenum wieder passt. - - - let in_1_day_is_plenum: bool = check_if_plenum(zweiter_dienstag.clone(), vierter_dienstag.clone(), in_1_day); - let in_3_days_is_plenum: bool = check_if_plenum(zweiter_dienstag.clone(), vierter_dienstag.clone(), in_3_days); - let pad_id: String = String::from("OlizTqsSQEeqil0OZmo-Qw"); + let in_1_day_is_plenum: bool = check_if_plenum(nächster_plenumtermin.clone(), in_1_day); + let in_3_days_is_plenum: bool = check_if_plenum(nächster_plenumtermin.clone(), in_3_days); + let yesterday_was_plenum: bool = check_if_plenum(nächster_plenumtermin.clone(), yesterday); + + // Pad-Links aus der Datenbank laden: + let pad_id: String = config.clone().get("aktuelles-plenumspad").unwrap().unwrap(); let current_pad_link: String = format!("https://md.berlin.ccc.de/{}/download", pad_id); - let future_pad_id:String = String::from("NOCH NICHT IMPLIMENTIERT"); + let future_pad_id:String = config.clone().get("zukünftiges-plenumspad").unwrap().unwrap(); let future_pad_link: String = format!("https://md.berlin.ccc.de/{}/download", future_pad_id); - - let mut message_id: String = String::from("FEHLER"); + + let mut message_id: String = String::from("FEHLER"); // message id initialisieren let in_3_days_is_plenum = true; + + let top_anzahl: i32 = 10; // Muss noch gecodet werden + 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(current_pad_link.clone()).await.expect("Fehler beim Download des Pads!"); println!("Pad-content geladen!"); if did_the_pad_change(&pad_content) { // Mail an alle senden, findet statt let message: String = format!("Hallo liebe Mitreisenden,\nEs gibt Themen, deshalb wird das morgige Plenum statt finden.\nAnbei das Plenumspad:\n{current_pad_link}\n Bis morgen, 20 Uhr!"); - println!("{}", message); + println!("---E-Mail:---\n{}\n-----------", message); let betreff = format!("Plenum vom {} findet statt", nächster_plenumtermin); message_id = mail_versenden(message, betreff).expect("Plenum findet statt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!") } else { // Mail an alle senden und absagen - let message: String = format!("Hallo liebe Mitreisenden,\nEs sind leider keine Themen zusammengekommen, deshalb wird das morgige Plenum leider nicht statt finden.\nHier ist der Link zum Pad vom nächsten Plenum, das am {} statt finden wird: {future_pad_link} und hier der morgige Padlink, der nicht mehr gebraucht wird: {current_pad_link}\nBis zum nächsten Plenum.\n\n[Diese Nachricht wurde automatisiert vom Plenumsbot erstellt und ist daher ohne Unterschrift gültig.]", nächster_plenumtermin); - println!("{}", message); + let message: String = format!("Hallo liebe Mitreisenden,\nEs sind keine Themen zusammengekommen, deshalb wird das morgige Plenum leider nicht statt finden.\nHier ist der Link zum Pad vom nächsten Plenum, das am {} statt finden wird: {future_pad_link} und hier der morgige Padlink, der nicht mehr gebraucht wird: {current_pad_link}\nBis zum nächsten Plenum.\n\n[Diese Nachricht wurde automatisiert vom Plenumsbot erstellt und ist daher ohne Unterschrift gültig.]", nächster_plenumtermin); + println!("---E-Mail:---\n{}\n-----------", message); let betreff = format!("Plenum vom {} muss leider ausfallen", nächster_plenumtermin); message_id = mail_versenden(message, betreff).expect("Plenum wird abgesagt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!") } } 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!"); println!("Pad-content geladen!"); if !did_the_pad_change(&pad_content) { // Mail an alle senden und absagen let message: String = format!("Hallo liebe Mitreisenden,\nEs sind leider bisher keine Themen zusammengekommen. Wenn bis Sonntag Abend keine Themen zusammenkommen, wird das Plenum voraussichtlich nicht statt finden.\nHier ist der Link zum Pad, wo ihr noch Themen einragen könnt: {}\n\n[Diese Nachricht wurde automatisiert vom Plenumsbot erstellt und ist daher ohne Unterschrift gültig.]", current_pad_link.clone()); let betreff = format!("Plenum vom {}:Bisher noch keine Plenumsthemen", nächster_plenumtermin); - println!("{}", message); + println!("---E-Mail:---\n{}\n-----------", message); message_id = mail_versenden(message, betreff).expect("Noch nicht genug Themen. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!") } 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(current_pad_link.clone()).await.expect("Fehler beim Download des Pads!"); + generate_new_pad_for_following_date(übernächster_plenumtermin, überübernächster_plenumtermin, &config).await.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 message: String = format!("Hallo liebe Mitreisenden,\nAnbei das gestrige Plenumspad.\nHier sind die Links zum nächsten: {}\nund zum übernächsten Plenum: {}\nUnd hier ist das Protokoll des letzten Plenums:\n{}\n[Diese Nachricht wurde automatisiert vom Plenumsbot erstellt und ist daher ohne Unterschrift gültig.]", current_pad_link, future_pad_link, old_pad_content.clone()); + let betreff: String = format!("Plenumsprotokoll vom {}: Es gab {} TOPs", nächster_plenumtermin, top_anzahl); + println!("---E-Mail:---\n{}\n-----------", message); + message_id = mail_versenden(message, betreff).expect("Mail mit Plenumsprotokoll wurde versucht zu senden, konnte aber nicht gesendet werden!"); + pad_ins_wiki(old_pad_content); } // END ANKÜNDIGUNGSSCRIPT - generate_new_pad_for_following_date(nächster_plenumtermin, übernächster_plenumtermin).await.expect("Fehler! Plenumspad konnte nicht generiert werden!"); - - } @@ -175,10 +198,10 @@ fn get_tuesdays(month_offset: u32) -> Vec>{ all_tuesdays } -fn check_if_plenum(zweiter_dienstag: String, vierter_dienstag: String, date_to_check: NaiveDate) -> bool { +fn check_if_plenum(infrage_kommendes_plenum: String, date_to_check: NaiveDate) -> bool { // Überprüfen, ob an dem Datum Plenum ist let date_to_check = date_to_check.to_string(); - if zweiter_dienstag == date_to_check || vierter_dienstag == date_to_check { + if infrage_kommendes_plenum == date_to_check { println!("Heute ist Plenum!"); return true } else { @@ -197,11 +220,13 @@ fn mail_versenden(inhalt: String, betreff: String) -> std::result::Result"} else {"CCCB Intern "}; + let email = Message::builder() // Set the sender's name and email address .from("Plenum Bot ".parse().unwrap()) // Set the recipient's name and email address - .to("Marek Krug ".parse().unwrap()) + .to(mail_to.parse().unwrap()) .message_id(Option::from(message_id.clone())) .in_reply_to("19de3985-05b4-42f3-9a6a-e941479be2ed@berlin.ccc.de".to_string()) // Set the subject of the email @@ -225,7 +250,7 @@ fn mail_versenden(inhalt: String, betreff: String) -> std::result::Result Result<(), Box> { +async fn generate_new_pad_for_following_date(übernächster_plenumtermin: String, überübernächster_plenumtermin: String, kv: &KV) -> Result<(), Box> { let client = Client::new(); match create_new_pads::create_pad(&client, HEDGEDOC_SERVER_URL).await { @@ -235,26 +260,42 @@ async fn generate_new_pad_for_following_date(nächster_plenumtermin: String, üb // 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_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, nächster_plenumtermin, übernächster_plenumtermin).unwrap_or_else(|error |template_content); // Try regex, if not successful use without regex + 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 pad_id: &str = pad_url.trim_start_matches(&format!("{}/", HEDGEDOC_SERVER_URL)); - match create_new_pads::import_note(&client, template_modified, Some(pad_id), HEDGEDOC_SERVER_URL).await { - Ok(_) => println!("Pad updated successfully with template content."), + 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 { + Ok(_) => { + println!("Pad updated successfully with template content."); + rotate (future_pad_id, kv); + }, Err(e) => println!("Failed to update pad: {}", e), } } Err(e) => println!("Failed to create pad: {}", e), } - Ok(()) } -fn replace_placeholders(template: &str, nächster_plenumtermin: String, übernächster_plenumtermin: String) -> Result> { +fn replace_placeholders(template: &str, übernächster_plenumtermin: String, überübernächster_plenumtermin: String) -> Result> { let re_datum = Regex::new(r"\{\{Datum\}\}")?; let re_naechstes_plenum = Regex::new(r"\{\{naechstes-plenum\}\}")?; - let result = re_datum.replace_all(template, nächster_plenumtermin); - let result = re_naechstes_plenum.replace_all(&result, übernächster_plenumtermin); + let result = re_datum.replace_all(template, übernächster_plenumtermin); + let result = re_naechstes_plenum.replace_all(&result, überübernächster_plenumtermin); Ok(result.to_string()) -} \ No newline at end of file +} + +fn rotate (future_pad_id: &str, kv: &KV) { + let next_plenum_pad = kv.get("zukünftiges-plenumspad").unwrap_or_else(|error | None); + if next_plenum_pad == None { + kv.set("zukünftiges-plenumspad", &future_pad_id).expect("Fehler beim Beschreiben der Datenbank mit neuem Plenumslink!"); // Beispiel: aktuelles-plenumspad: Ok(Some("eCH24zXGS9S8Stg5xI3aRg")) + } else { + kv.set("aktuelles-plenumspad", &next_plenum_pad.unwrap()).expect("Fehler beim Beschreiben der Datenbank mit neuem Plenumslink!"); // Beispiel: aktuelles-plenumspad: Ok(Some("eCH24zXGS9S8Stg5xI3aRg")) + kv.set("zukünftiges-plenumspad", &future_pad_id).expect("Fehler beim Beschreiben der Datenbank mit neuem Plenumslink!"); // Beispiel: aktuelles-plenumspad: Ok(Some("eCH24zXGS9S8Stg5xI3aRg")) + } +} + +fn pad_ins_wiki(old_pad_content: String) { + +}