mit cargo fmt alles formatiert
This commit is contained in:
parent
c026a38239
commit
c8031dfc01
|
@ -70,7 +70,7 @@ pub fn populate_defaults(config: &KV) {
|
|||
CfgField::Default { default, .. } => {
|
||||
config.default(&field.full_key(group.name), default)
|
||||
},
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,16 +86,26 @@ pub fn interactive_check(config: KV) -> Result<(), Box<dyn Error>> {
|
|||
let todo = needs_info(&config, group);
|
||||
// TODO: add distinction between edit all / edit necessary only
|
||||
let choices = if !todo.is_empty() {
|
||||
println!( "{}The following fields need adjustment: {}{}", ANSI_NOTICE, todo.join(", "), ANSI_RESET );
|
||||
println!(
|
||||
"{}The following fields need adjustment: {}{}",
|
||||
ANSI_NOTICE,
|
||||
todo.join(", "),
|
||||
ANSI_RESET
|
||||
);
|
||||
&["[E]dit (default)", "[L]ist all", "[S]kip group"]
|
||||
} else {
|
||||
println!( "{}This group looks fine. OK to [S]kip, unless you want to adjust values here.{}", ANSI_NOTICE, ANSI_RESET );
|
||||
&["[S]kip group (default)", "[E]dit", "[L]ist all", ]
|
||||
println!(
|
||||
"{}This group looks fine. OK to [S]kip, unless you want to adjust values here.{}",
|
||||
ANSI_NOTICE, ANSI_RESET
|
||||
);
|
||||
&["[S]kip group (default)", "[E]dit", "[L]ist all"]
|
||||
};
|
||||
loop {
|
||||
let choice = prompt_action(choices);
|
||||
match choice {
|
||||
'L' => { show_group(&config, group); },
|
||||
'L' => {
|
||||
show_group(&config, group);
|
||||
},
|
||||
'E' => {
|
||||
for field in group.fields {
|
||||
check_field(&config, group.name, field, &mut all_valid)?;
|
||||
|
@ -103,10 +113,14 @@ pub fn interactive_check(config: KV) -> Result<(), Box<dyn Error>> {
|
|||
break;
|
||||
},
|
||||
'S' => {
|
||||
if !todo.is_empty() { all_valid = false; }
|
||||
if !todo.is_empty() {
|
||||
all_valid = false;
|
||||
}
|
||||
break;
|
||||
},
|
||||
_ => { unreachable!(); }, // (prompt already checks)
|
||||
_ => {
|
||||
unreachable!();
|
||||
}, // (prompt already checks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,30 +131,49 @@ pub fn interactive_check(config: KV) -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_field( config: &KV, grpname: &str, field: &CfgField, ok: &mut bool ) -> Result<(), Box<dyn Error>> {
|
||||
if field.is_silent() { return Ok(()) }
|
||||
fn check_field(
|
||||
config: &KV, grpname: &str, field: &CfgField, ok: &mut bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
if field.is_silent() {
|
||||
return Ok(());
|
||||
}
|
||||
show_field(config, grpname, field);
|
||||
let key = field.full_key(grpname);
|
||||
let value = config.get(&key).ok();
|
||||
let mut actions: Vec<&'static str> = Vec::new();
|
||||
// TODO: adjust order: empty password should offer input first
|
||||
// TODO: RandomId should offer generating as [R]egenerate
|
||||
if value.is_some() | field.is_password() | field.is_optional() { actions.push("[K]eep as-is"); }
|
||||
if field.default_description().is_some() { actions.push("[R]eset to default"); }
|
||||
if field.is_password() { actions.push( "[R]emove" ); }
|
||||
if value.is_some() | field.is_password() | field.is_optional() {
|
||||
actions.push("[K]eep as-is");
|
||||
}
|
||||
if field.default_description().is_some() {
|
||||
actions.push("[R]eset to default");
|
||||
}
|
||||
if field.is_password() {
|
||||
actions.push("[R]emove");
|
||||
}
|
||||
actions.push("[I]nput new value");
|
||||
if !field.is_password() { actions.push( "[L]ong (multiline) input" ) };
|
||||
if !field.is_password() {
|
||||
actions.push("[L]ong (multiline) input")
|
||||
};
|
||||
|
||||
match prompt_action(&actions) {
|
||||
'K' => {
|
||||
// we allow leaving a password empty, but that means config is incomplete
|
||||
if value.is_none() & !field.is_optional() { *ok &= false; }
|
||||
if value.is_none() & !field.is_optional() {
|
||||
*ok &= false;
|
||||
}
|
||||
},
|
||||
'R' => {
|
||||
match field.default_value()? {
|
||||
Some(value) => { config.set(&key, &value)?; },
|
||||
Some(value) => {
|
||||
config.set(&key, &value)?;
|
||||
},
|
||||
// password again
|
||||
None => { config.delete(&key)?; *ok &= false; },
|
||||
None => {
|
||||
config.delete(&key)?;
|
||||
*ok &= false;
|
||||
},
|
||||
}
|
||||
},
|
||||
'I' => {
|
||||
|
@ -151,7 +184,9 @@ fn check_field( config: &KV, grpname: &str, field: &CfgField, ok: &mut bool ) ->
|
|||
let value = prompt_multiline();
|
||||
config.set(&key, &value)?;
|
||||
},
|
||||
_ => { return Err("Wat.".into()); }
|
||||
_ => {
|
||||
return Err("Wat.".into());
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -171,11 +206,15 @@ fn show_group( config: &KV, group: &CfgGroup ) {
|
|||
}
|
||||
|
||||
fn show_field(config: &KV, grpname: &str, field: &CfgField) {
|
||||
if field.is_silent() { return }
|
||||
if field.is_silent() {
|
||||
return;
|
||||
}
|
||||
let key = field.full_key(grpname);
|
||||
println!("{}{}{} - {}", ANSI_FIELD, &key, ANSI_RESET, field.description());
|
||||
println!(" default: {}", field.default_description().unwrap_or(EMPTY_VALUE.to_string()));
|
||||
let value = config.get(&key).ok()
|
||||
let value = config
|
||||
.get(&key)
|
||||
.ok()
|
||||
.map(|s| if field.is_password() { HIDDEN_PASSWORD.to_string() } else { s })
|
||||
.unwrap_or(EMPTY_VALUE.to_string());
|
||||
println!(" current: {}", value);
|
||||
|
@ -211,7 +250,10 @@ fn prompt_action( choices: &[&str] ) -> char {
|
|||
let input = input.trim().to_uppercase().chars().next().unwrap_or(default_choice);
|
||||
|
||||
// Check list of choices for match
|
||||
if choices.iter().any(|&choice| choice.to_uppercase().chars().nth(1).unwrap_or_default() == input) {
|
||||
if choices
|
||||
.iter()
|
||||
.any(|&choice| choice.to_uppercase().chars().nth(1).unwrap_or_default() == input)
|
||||
{
|
||||
return input;
|
||||
} else {
|
||||
println!("Invalid choice. Try again!");
|
||||
|
@ -264,7 +306,12 @@ enum CfgField<'a> {
|
|||
/// Empty by default, required, will prompt without echo.
|
||||
Password { key: &'a str, description: &'a str },
|
||||
/// Empty by default, can be user-provided, or will be generated randomly.
|
||||
RandomId { key: &'a str, generator: fn() -> Result<String,Box<dyn Error>>, generator_description: &'a str, description: &'a str },
|
||||
RandomId {
|
||||
key: &'a str,
|
||||
generator: fn() -> Result<String, Box<dyn Error>>,
|
||||
generator_description: &'a str,
|
||||
description: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
/// A group of related config fields. The final key of an inner value will be
|
||||
|
@ -304,7 +351,10 @@ impl<'a> CfgField<'a> {
|
|||
/// *necessarily* always have a value. Optional is optional. Only
|
||||
/// Password and RandomId might need actions if they are missing.)
|
||||
fn is_action_required(&self, config: &KV, grpname: &str) -> bool {
|
||||
if matches!( self, CfgField::Silent { .. } | CfgField::Default { .. } | CfgField::Optional { .. } ) {
|
||||
if matches!(
|
||||
self,
|
||||
CfgField::Silent { .. } | CfgField::Default { .. } | CfgField::Optional { .. }
|
||||
) {
|
||||
false
|
||||
} else {
|
||||
config.get(self.full_key(grpname).as_str()).ok().is_none()
|
||||
|
@ -319,7 +369,8 @@ impl<'a> CfgField<'a> {
|
|||
CfgField::Optional { key, .. } => key,
|
||||
CfgField::Password { key, .. } => key,
|
||||
CfgField::RandomId { key, .. } => key,
|
||||
}.to_string()
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Full field name / key used in the DB (currently `{grpname}-{fieldname}`.)
|
||||
|
@ -335,7 +386,8 @@ impl<'a> CfgField<'a> {
|
|||
CfgField::Optional { description, .. } => description,
|
||||
CfgField::Password { description, .. } => description,
|
||||
CfgField::RandomId { description, .. } => description,
|
||||
}.to_string()
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Gets a description of the default value if one exists.
|
||||
|
@ -344,7 +396,9 @@ impl<'a> CfgField<'a> {
|
|||
match self {
|
||||
CfgField::Silent { default, .. } => Some(default.to_string()),
|
||||
CfgField::Default { default, .. } => Some(default.to_string()),
|
||||
CfgField::RandomId { generator_description, .. } => Some(format!("{}{}{}",'(',generator_description,')')),
|
||||
CfgField::RandomId { generator_description, .. } => {
|
||||
Some(format!("{}{}{}", '(', generator_description, ')'))
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use reqwest::blocking::Response;
|
||||
use reqwest::blocking::Client;
|
||||
use reqwest::blocking::Response;
|
||||
use std::error::Error;
|
||||
|
||||
// TODO: implement dry-run logic
|
||||
|
@ -49,10 +49,8 @@ impl HedgeDoc {
|
|||
None => self.format_url("new"),
|
||||
};
|
||||
|
||||
let res = self.client.post(&url)
|
||||
.header( "Content-Type", "text/markdown" )
|
||||
.body(content)
|
||||
.send()?;
|
||||
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))
|
||||
|
|
141
src/main.rs
141
src/main.rs
|
@ -32,12 +32,11 @@ mod mediawiki;
|
|||
|
||||
mod config_check;
|
||||
|
||||
|
||||
pub mod variables_and_settings;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::error::Error;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
// use std::future::Future;
|
||||
|
@ -47,9 +46,9 @@ use clap::{Arg, Command};
|
|||
use regex::Regex;
|
||||
use uuid::Uuid;
|
||||
|
||||
use lettre::{Message, SmtpTransport, Transport};
|
||||
use lettre::message::{header, SinglePart};
|
||||
use lettre::transport::smtp::authentication::Credentials;
|
||||
use lettre::{Message, SmtpTransport, Transport};
|
||||
|
||||
const FALLBACK_TEMPLATE: &str = variables_and_settings::FALLBACK_TEMPLATE;
|
||||
|
||||
|
@ -86,7 +85,8 @@ fn parse_args() -> Args {
|
|||
.action(clap::ArgAction::Set)
|
||||
.default_value("config.sqlite")
|
||||
.help("specifies an alternate config file"),
|
||||
).get_matches();
|
||||
)
|
||||
.get_matches();
|
||||
Args {
|
||||
check_mode: *matches.get_one::<bool>("check").unwrap(),
|
||||
config_file: matches.get_one::<String>("config_file").unwrap().clone(),
|
||||
|
@ -129,23 +129,25 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
// Nächste Plena nachschauen:
|
||||
|
||||
let nächster_plenumtermin: &String = if all_tuesdays[1] >= yesterday { // Für das Pad rumschicken am nächsten Tag wird das Datum einen Tag nach Hinten gesetzt,
|
||||
let nächster_plenumtermin: &String = if all_tuesdays[1] >= yesterday {
|
||||
// Für das Pad rumschicken am nächsten Tag wird das Datum einen Tag nach Hinten gesetzt,
|
||||
&zweiter_dienstag
|
||||
} else {
|
||||
&vierter_dienstag
|
||||
};
|
||||
let übernächster_plenumtermin = if all_tuesdays[1] >= yesterday { // hier das Gleiche.
|
||||
let übernächster_plenumtermin = if all_tuesdays[1] >= yesterday {
|
||||
// hier das Gleiche.
|
||||
&vierter_dienstag
|
||||
} else {
|
||||
&zweiter_dienstag_nächster_monat
|
||||
};
|
||||
let überübernächster_plenumtermin = if all_tuesdays[1] >= yesterday { // hier das Gleiche.
|
||||
let überübernächster_plenumtermin = if all_tuesdays[1] >= yesterday {
|
||||
// hier das Gleiche.
|
||||
&zweiter_dienstag_nächster_monat
|
||||
} 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(nächster_plenumtermin.clone(), in_1_day);
|
||||
|
@ -153,8 +155,12 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let yesterday_was_plenum: bool = check_if_plenum(nächster_plenumtermin.clone(), yesterday);
|
||||
|
||||
// Pad-Links aus der Datenbank laden:
|
||||
let current_pad_id = config.get("hedgedoc-last-id").expect("ID des aktuellen Pads undefiniert. Bitte in der DB eintragen oder generieren.");
|
||||
let future_pad_id = config.get("hedgedoc-next-id").expect("ID des nächsten Pads undefiniert. Bitte in der DB eintragen oder generieren.");
|
||||
let current_pad_id = config
|
||||
.get("hedgedoc-last-id")
|
||||
.expect("ID des aktuellen Pads undefiniert. Bitte in der DB eintragen oder generieren.");
|
||||
let future_pad_id = config
|
||||
.get("hedgedoc-next-id")
|
||||
.expect("ID des nächsten Pads undefiniert. Bitte in der DB eintragen oder generieren.");
|
||||
|
||||
let mut message_id: Option<String> = None;
|
||||
|
||||
|
@ -180,7 +186,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
if number_of_tops(&pad_content_without_top_instructions) != 0 {
|
||||
// Mail an alle senden, findet statt
|
||||
let betreff = "Morgen ist Plenum!".to_string(); // ADJ_TIMEYWIMEY
|
||||
let message: String = format!(r#"{email_greeting}
|
||||
let message: String = format!(
|
||||
r#"{email_greeting}
|
||||
|
||||
Es gibt Themen, deshalb wird das morgige Plenum statt finden. Anbei das Plenumspad:
|
||||
{current_pad_link}
|
||||
|
@ -190,14 +197,16 @@ Und hier ein TL;DR von den aktuellen Themen:
|
|||
|
||||
Bis morgen, 20 Uhr!
|
||||
|
||||
{email_signature}"#); // ADJ_TIMEYWIMEY
|
||||
{email_signature}"#
|
||||
); // ADJ_TIMEYWIMEY
|
||||
println!("---E-Mail:---\n{}\n-----------", message);
|
||||
// XXX option x expect
|
||||
message_id = Some(mail_versenden(&config, betreff, message).expect("Plenum findet statt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!"))
|
||||
} else {
|
||||
// Mail an alle senden und absagen
|
||||
let betreff = format!("Plenum am {} fällt mangels Themen aus", nächster_plenumtermin);
|
||||
let message: String = format!(r#"{email_greeting}
|
||||
let message: String = format!(
|
||||
r#"{email_greeting}
|
||||
|
||||
Es gibt keine Themen, deshalb wird das morgige Plenum leider nicht statt finden.
|
||||
|
||||
|
@ -206,7 +215,9 @@ Hier ist der Link zum Pad vom nächsten Plenum, das am {} statt finden wird:
|
|||
|
||||
Bis zum nächsten Plenum.
|
||||
|
||||
{email_signature}"#, nächster_plenumtermin);
|
||||
{email_signature}"#,
|
||||
nächster_plenumtermin
|
||||
);
|
||||
println!("---E-Mail:---\n{}\n-----------", message);
|
||||
// XXX option x expect
|
||||
message_id = Some(mail_versenden(&config, betreff, message).expect("Plenum wird abgesagt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!"))
|
||||
|
@ -216,29 +227,38 @@ Bis zum nächsten Plenum.
|
|||
if number_of_tops(&pad_content_without_top_instructions) == 0 {
|
||||
// Mail an alle senden und sagen, dass es noch keine Themen gibt
|
||||
let betreff = format!("Plenum vom {}: Bisher noch keine Themen", nächster_plenumtermin);
|
||||
let message: String = format!(r#"{email_greeting}
|
||||
let message: String = format!(
|
||||
r#"{email_greeting}
|
||||
|
||||
Es sind bisher leider keine Themen zusammengekommen. Wenn es bis Sonntag Abend keine Themen gibt, wird das Plenum voraussichtlich nicht statt finden.
|
||||
|
||||
Hier ist der Link zum Pad, wo ihr noch Themen eintragen könnt:
|
||||
{current_pad_link}
|
||||
|
||||
{email_signature}"#);
|
||||
{email_signature}"#
|
||||
);
|
||||
println!("---E-Mail:---\n{}\n-----------", message);
|
||||
// XXX option x expect
|
||||
message_id = Some(mail_versenden(&config, betreff, message).expect("Noch nicht genug Themen. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!"))
|
||||
}
|
||||
} else if yesterday_was_plenum {
|
||||
// This logic breaks on 02/2034, but on every other month it works
|
||||
let old_pad_content = hedgedoc.download(¤t_pad_id).expect("Fehler beim Hedgedoc-Pad-Download!");
|
||||
let old_pad_content =
|
||||
hedgedoc.download(¤t_pad_id).expect("Fehler beim Hedgedoc-Pad-Download!");
|
||||
// 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!");
|
||||
println!("DATENBANK: aktuelles-plenumspad: {:?} und zukünftiges plenumspad: {:?}", &config.get("hedgedoc-last-id"), &config.get("hedgedoc-next-id"));
|
||||
println!(
|
||||
"DATENBANK: aktuelles-plenumspad: {:?} und zukünftiges plenumspad: {:?}",
|
||||
&config.get("hedgedoc-last-id"),
|
||||
&config.get("hedgedoc-next-id")
|
||||
);
|
||||
|
||||
let old_pad_content_without_top_instructions = try_to_remove_top_instructions(old_pad_content);
|
||||
let old_pad_content_without_top_instructions =
|
||||
try_to_remove_top_instructions(old_pad_content);
|
||||
let tldr_vec = create_tldr(&old_pad_content_without_top_instructions);
|
||||
let tldr = tldr_vec.join("\n");
|
||||
// XXX nächstes/übernächstes?
|
||||
let message: String = format!(r#"{email_greeting}
|
||||
let message: String = format!(
|
||||
r#"{email_greeting}
|
||||
|
||||
Anbei das gestrige Plenumspad. Hier sind die Links zum nächsten:
|
||||
{current_pad_link}
|
||||
|
@ -252,8 +272,10 @@ Und hier ist das Protokoll des letzten Plenums:
|
|||
|
||||
{old_pad_content_without_top_instructions}
|
||||
|
||||
{email_signature}"#);
|
||||
let betreff: String = format!("Plenumsprotokoll vom {}: Es gab {} TOPs", nächster_plenumtermin, top_anzahl);
|
||||
{email_signature}"#
|
||||
);
|
||||
let betreff: String =
|
||||
format!("Plenumsprotokoll vom {}: Es gab {} TOPs", nächster_plenumtermin, top_anzahl);
|
||||
println!("---E-Mail:---\n{}\n-----------", message);
|
||||
// XXX option x expect
|
||||
message_id = Some(mail_versenden(&config, betreff, message).expect("Mail mit Plenumsprotokoll wurde versucht zu senden, konnte aber nicht gesendet werden!"));
|
||||
|
@ -264,7 +286,11 @@ Und hier ist das Protokoll des letzten Plenums:
|
|||
println!("[ENDE]\nAktueller Zustand der DB:");
|
||||
config.dump_redacting(&["email-password", "matrix-password", "wiki-password"]).ok();
|
||||
|
||||
if config.has_errors() { Err("There were errors.".into()) } else { Ok(()) }
|
||||
if config.has_errors() {
|
||||
Err("There were errors.".into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_all_weekdays(month_offset: i32, week_day: Weekday) -> Vec<NaiveDate> {
|
||||
|
@ -274,7 +300,8 @@ fn get_all_weekdays(month_offset: i32, week_day: Weekday) -> Vec<NaiveDate>{
|
|||
1 => date.checked_add_months(chrono::Months::new(month_offset as u32)),
|
||||
-1 => date.checked_sub_months(chrono::Months::new((-month_offset) as u32)),
|
||||
_ => unreachable!(),
|
||||
}.expect("(very) invalid month offset");
|
||||
}
|
||||
.expect("(very) invalid month offset");
|
||||
let month = date.month();
|
||||
let mut current_date = NaiveDate::from_ymd_opt(date.year(), date.month(), 1);
|
||||
let mut dates = Vec::new();
|
||||
|
@ -290,11 +317,7 @@ fn get_all_weekdays(month_offset: i32, week_day: Weekday) -> Vec<NaiveDate>{
|
|||
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();
|
||||
return if infrage_kommendes_plenum == date_to_check {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
return if infrage_kommendes_plenum == date_to_check { true } else { false };
|
||||
}
|
||||
|
||||
fn number_of_tops(pad_content: &String) -> i32 {
|
||||
|
@ -313,7 +336,9 @@ fn create_tldr (pad_content: &String) -> Vec<&str> {
|
|||
//tldr_vec.append() = m.iter()
|
||||
}
|
||||
|
||||
fn mail_versenden(config: &KV, betreff: String, inhalt: String) -> std::result::Result<String, Box<dyn std::error::Error>> {
|
||||
fn mail_versenden(
|
||||
config: &KV, betreff: String, inhalt: String,
|
||||
) -> std::result::Result<String, Box<dyn std::error::Error>> {
|
||||
// Define the email
|
||||
let message_id: String = Uuid::new_v4().to_string() + &String::from("@berlin.ccc.de");
|
||||
|
||||
|
@ -328,33 +353,39 @@ fn mail_versenden(config: &KV, betreff: String, inhalt: String) -> std::result::
|
|||
.in_reply_to("19de3985-05b4-42f3-9a6a-e941479be2ed@berlin.ccc.de".to_string())
|
||||
// Set the subject of the email
|
||||
.subject(betreff)
|
||||
.singlepart(SinglePart::builder()
|
||||
.header(header::ContentType::TEXT_PLAIN)
|
||||
.body(inhalt))
|
||||
.singlepart(SinglePart::builder().header(header::ContentType::TEXT_PLAIN).body(inhalt))
|
||||
.unwrap();
|
||||
|
||||
if !is_dry_run() {
|
||||
// Set up the SMTP client
|
||||
let creds = Credentials::new(config["email-user"].to_string(), config["email-password"].to_string());
|
||||
let creds = Credentials::new(
|
||||
config["email-user"].to_string(),
|
||||
config["email-password"].to_string(),
|
||||
);
|
||||
// Open a remote connection to gmail
|
||||
|
||||
let mailer = SmtpTransport::starttls_relay(&config["email-server"])?
|
||||
.credentials(creds)
|
||||
.build();
|
||||
let mailer =
|
||||
SmtpTransport::starttls_relay(&config["email-server"])?.credentials(creds).build();
|
||||
|
||||
// Send the email
|
||||
match mailer.send(&email) {
|
||||
Ok(_) => println!("Email sent successfully!"),
|
||||
Err(e) => eprintln!("Could not send email: {:?}", e), }
|
||||
Err(e) => eprintln!("Could not send email: {:?}", e),
|
||||
}
|
||||
Ok(message_id)
|
||||
} else {
|
||||
println!( "[DRY RUN - NOT] sending email\n(raw message:)\n{}", std::str::from_utf8(&email.formatted()).unwrap_or("((UTF-8 error))") );
|
||||
println!(
|
||||
"[DRY RUN - NOT] sending email\n(raw message:)\n{}",
|
||||
std::str::from_utf8(&email.formatted()).unwrap_or("((UTF-8 error))")
|
||||
);
|
||||
Ok("dummy-message-id@localhost".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_new_pad_for_following_date(config : KV, hedgedoc : HedgeDoc, übernächster_plenumtermin: &String, überübernächster_plenumtermin: &String, kv: &KV) -> Result<(), Box<dyn Error>> {
|
||||
|
||||
fn generate_new_pad_for_following_date(
|
||||
config: KV, hedgedoc: HedgeDoc, übernächster_plenumtermin: &String,
|
||||
überübernächster_plenumtermin: &String, kv: &KV,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
match hedgedoc.create_pad() {
|
||||
Err(e) => println!("Failed to create pad: {}", e),
|
||||
Ok(pad_id) => {
|
||||
|
@ -362,11 +393,18 @@ fn generate_new_pad_for_following_date(config : KV, hedgedoc : HedgeDoc, übern
|
|||
|
||||
// Get the most recent plenum template and replace the placeholders:
|
||||
let template_content: String = match config.get("hedgedoc-template-name") {
|
||||
Ok(content) => hedgedoc.download(&content.clone()).unwrap_or_else(|_| FALLBACK_TEMPLATE.to_string()),
|
||||
Ok(content) => hedgedoc
|
||||
.download(&content.clone())
|
||||
.unwrap_or_else(|_| FALLBACK_TEMPLATE.to_string()),
|
||||
Err(_) => FALLBACK_TEMPLATE.to_string(),
|
||||
};
|
||||
// XXX you don't just use the template as-is…
|
||||
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 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
|
||||
|
||||
match hedgedoc.import_note(Some(&pad_id), template_modified) {
|
||||
Ok(_) => {
|
||||
|
@ -375,12 +413,14 @@ fn generate_new_pad_for_following_date(config : KV, hedgedoc : HedgeDoc, übern
|
|||
},
|
||||
Err(e) => println!("Failed to update pad: {}", e),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_placeholders(template: &str, übernächster_plenumtermin: &str, überübernächster_plenumtermin: &str) -> Result<String, Box<dyn Error>> {
|
||||
fn replace_placeholders(
|
||||
template: &str, übernächster_plenumtermin: &str, überübernächster_plenumtermin: &str,
|
||||
) -> Result<String, Box<dyn Error>> {
|
||||
let re_datum = Regex::new(r"\{\{Datum\}\}")?;
|
||||
let result = re_datum.replace_all(template, übernächster_plenumtermin);
|
||||
let re_naechstes_plenum = Regex::new(r"\{\{naechstes-plenum\}\}")?;
|
||||
|
@ -391,10 +431,15 @@ fn replace_placeholders(template: &str, übernächster_plenumtermin: &str, über
|
|||
fn rotate(future_pad_id: &str, kv: &KV) {
|
||||
let next_plenum_pad = kv.get("zukünftiges-plenumspad").ok();
|
||||
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"))
|
||||
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"))
|
||||
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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,16 @@ pub 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 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!");
|
||||
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}")
|
||||
}
|
||||
|
||||
|
@ -25,10 +27,13 @@ fn convert_markdown_to_mediawiki_and_save_as_txt (old_pad_content: String) {
|
|||
p.set_input_format(pandoc::InputFormat::Markdown, vec![]);
|
||||
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");
|
||||
p.execute()
|
||||
.expect("Fehler beim Umwandeln des und speichern des Pads in eine mediawiki-Textdatei");
|
||||
}
|
||||
|
||||
fn login_to_mediawiki (plenum_bot_user: String, plenum_bot_pw: String) -> Result<String, Box<dyn Error>> {
|
||||
fn login_to_mediawiki(
|
||||
plenum_bot_user: String, plenum_bot_pw: String,
|
||||
) -> Result<String, Box<dyn Error>> {
|
||||
//let mut map = HashMap::new();
|
||||
//map.insert("logintoken", "result");
|
||||
let username = "cccb-wiki";
|
||||
|
|
Loading…
Reference in a new issue