announcement/reminder
This commit is contained in:
		
							parent
							
								
									fecf6ebed5
								
							
						
					
					
						commit
						7093280d80
					
				
					 2 changed files with 107 additions and 45 deletions
				
			
		|  | @ -80,6 +80,14 @@ impl SimpleEmail { | ||||||
|             self.in_reply_to.clone(), |             self.in_reply_to.clone(), | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |     pub fn into_parts(self) -> (Email, String, Vec<String>, Option<String>) { | ||||||
|  |         (self.base, self.from, self.to, self.in_reply_to) | ||||||
|  |     } | ||||||
|  |     pub fn from_parts( | ||||||
|  |         base: Email, from: String, to: Vec<String>, in_reply_to: Option<String>, | ||||||
|  |     ) -> Self { | ||||||
|  |         Self { base, from, to, in_reply_to } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Email { | impl Email { | ||||||
|  |  | ||||||
							
								
								
									
										144
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										144
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -76,6 +76,7 @@ const CONFIG_SPEC: CfgSpec<'static> = CfgSpec { | ||||||
|                     default: "NORMAL", |                     default: "NORMAL", | ||||||
|                     description: "Named state of the program logic. (NORMAL, ANNOUNCED, REMINDED, LOGGED)", |                     description: "Named state of the program logic. (NORMAL, ANNOUNCED, REMINDED, LOGGED)", | ||||||
|                 }, |                 }, | ||||||
|  |                 CfgField::Optional { key: "toc", description: "Table of contents / pad summary." }, | ||||||
|                 CfgField::Optional { key: "last-run", |                 CfgField::Optional { key: "last-run", | ||||||
|                     description: "Last run of the program (used to figure out state of previous plenum mails.)", |                     description: "Last run of the program (used to figure out state of previous plenum mails.)", | ||||||
|                 }, |                 }, | ||||||
|  | @ -267,7 +268,7 @@ fn main() -> Result<(), Box<dyn Error>> { | ||||||
|         &config["email-password"], |         &config["email-password"], | ||||||
|         is_dry_run(), |         is_dry_run(), | ||||||
|     ); |     ); | ||||||
|     let email = SimpleEmail::new( |     let mut email = SimpleEmail::new( | ||||||
|         email_, |         email_, | ||||||
|         &config["email-from"], |         &config["email-from"], | ||||||
|         &config["email-to"], |         &config["email-to"], | ||||||
|  | @ -299,8 +300,12 @@ fn main() -> Result<(), Box<dyn Error>> { | ||||||
|             eprintln!("WARNING: last run was a long time ago, resetting state."); |             eprintln!("WARNING: last run was a long time ago, resetting state."); | ||||||
|             last_state = ProgramState::Normal; |             last_state = ProgramState::Normal; | ||||||
|             do_cleanup(999, &today, &config, &hedgedoc, &email, &wiki)?; |             do_cleanup(999, &today, &config, &hedgedoc, &email, &wiki)?; | ||||||
|  |             // reset will have cleared in-reply-to if it existed
 | ||||||
|  |             let (base, from, to, _) = email.into_parts(); | ||||||
|  |             email = SimpleEmail::from_parts(base, from, to, config.get("email-in-reply-to").ok()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     let email = email; | ||||||
|     let last_state = last_state; |     let last_state = last_state; | ||||||
|     // figure out where we should be
 |     // figure out where we should be
 | ||||||
|     // deltas has either 2 or 3 days, if 3 then the middle one is == 0 (i.e. today)
 |     // deltas has either 2 or 3 days, if 3 then the middle one is == 0 (i.e. today)
 | ||||||
|  | @ -415,7 +420,7 @@ fn main() -> Result<(), Box<dyn Error>> { | ||||||
|         .get("hedgedoc-next-id") |         .get("hedgedoc-next-id") | ||||||
|         .expect("ID des nächsten Pads undefiniert. Bitte in der DB eintragen oder generieren."); |         .expect("ID des nächsten Pads undefiniert. Bitte in der DB eintragen oder generieren."); | ||||||
| 
 | 
 | ||||||
|     let mut message_id: Option<String> = None; |     let mut message_id: String; | ||||||
| 
 | 
 | ||||||
|     // let in_3_days_is_plenum = true;
 |     // let in_3_days_is_plenum = true;
 | ||||||
|     //TEMPORÄR ANFANG: BEI PRODUCTION MUSS DAS HIER RAUS
 |     //TEMPORÄR ANFANG: BEI PRODUCTION MUSS DAS HIER RAUS
 | ||||||
|  | @ -453,7 +458,7 @@ Und hier ein TL;DR von den aktuellen Themen: | ||||||
| 
 | 
 | ||||||
| Bis morgen, 20 Uhr!"#
 | Bis morgen, 20 Uhr!"#
 | ||||||
|             ); // ADJ_TIMEYWIMEY
 |             ); // ADJ_TIMEYWIMEY
 | ||||||
|             message_id = send_email(&betreff, &message, &email, &config); |             message_id = send_email(&betreff, &message, &email, &config)?; | ||||||
|             // .expect("Plenum findet statt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!")
 |             // .expect("Plenum findet statt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!")
 | ||||||
|         } else { |         } else { | ||||||
|             // Mail an alle senden und absagen
 |             // Mail an alle senden und absagen
 | ||||||
|  | @ -467,23 +472,9 @@ Hier ist der Link zum Pad vom nächsten Plenum, das am {} statt finden wird: | ||||||
| Bis zum nächsten Plenum."#,
 | Bis zum nächsten Plenum."#,
 | ||||||
|                 nächster_plenumtermin |                 nächster_plenumtermin | ||||||
|             ); |             ); | ||||||
|             message_id = send_email(&betreff, &message, &email, &config); |             message_id = send_email(&betreff, &message, &email, &config)?; | ||||||
|             // .expect("Plenum wird abgesagt. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!"))
 |             // .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!"); |  | ||||||
|         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#"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}"#
 |  | ||||||
|             ); |  | ||||||
|             message_id = send_email(&betreff, &message, &email, &config); |  | ||||||
|             // .expect("Noch nicht genug Themen. Mail wurde versucht zu senden, konnte aber nicht gesendet werden!"))
 |  | ||||||
|         } |  | ||||||
|     } else if yesterday_was_plenum { |     } else if yesterday_was_plenum { | ||||||
|         // This logic breaks on 02/2034, but on every other month it works
 |         // This logic breaks on 02/2034, but on every other month it works
 | ||||||
|         let old_pad_content = |         let old_pad_content = | ||||||
|  | @ -516,7 +507,7 @@ Und hier ist das Protokoll des letzten Plenums: | ||||||
|         let betreff: String = |         let betreff: String = | ||||||
|             format!("Plenumsprotokoll vom {}: Es gab {} TOPs", nächster_plenumtermin, top_anzahl); |             format!("Plenumsprotokoll vom {}: Es gab {} TOPs", nächster_plenumtermin, top_anzahl); | ||||||
|         // XXX option x expect
 |         // XXX option x expect
 | ||||||
|         message_id = send_email(&betreff, &message, &email, &config); |         message_id = send_email(&betreff, &message, &email, &config)?; | ||||||
|         // .expect("Mail mit Plenumsprotokoll wurde versucht zu senden, konnte aber nicht gesendet werden!"));
 |         // .expect("Mail mit Plenumsprotokoll wurde versucht zu senden, konnte aber nicht gesendet werden!"));
 | ||||||
|         mediawiki::pad_ins_wiki(old_pad_content_without_top_instructions); |         mediawiki::pad_ins_wiki(old_pad_content_without_top_instructions); | ||||||
|     } |     } | ||||||
|  | @ -674,42 +665,103 @@ fn upper_first(s: &str) -> String { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ***** transition actions ***** */ | fn topic_count(n: usize, dative: bool) -> String { | ||||||
|  |     match n { | ||||||
|  |         0 => format!("noch keine{} Themen", if dative { "n" } else { "" }), | ||||||
|  |         1 => format!("ein{} Thema", if dative { "em" } else { "" }), | ||||||
|  |         _ => format!("{} Themen", n), | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // BBBBBBBBBB
 | /* ***** repeating action parts ***** */ | ||||||
| 
 | 
 | ||||||
| #[allow(unused_variables)] | fn get_pad_info(config: &KV, hedgedoc: &HedgeDoc) -> (String, String, usize) { | ||||||
| fn do_announcement( |  | ||||||
|     ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, |  | ||||||
|     wiki: &Mediawiki, |  | ||||||
| ) -> Result<(), Box<dyn Error>> { |  | ||||||
|     let current_pad_id = &config["hedgedoc-last-id"]; |     let current_pad_id = &config["hedgedoc-last-id"]; | ||||||
|     let pad_content = hedgedoc.download(current_pad_id).expect("Hedgedoc: Download-Fehler"); |     let pad_content = hedgedoc.download(current_pad_id).expect("Hedgedoc: Download-Fehler"); | ||||||
|     let toc = hedgedoc::summarize(pad_content); |     let toc = hedgedoc::summarize(pad_content); | ||||||
|     verboseln!("Zusammenfassung des aktuellen Plenum-Pads:\n{}", toc.cyan()); |     verboseln!("Zusammenfassung des aktuellen Plenum-Pads:\n{}", toc.cyan()); | ||||||
|     let n_topics = toc.lines().count(); |     let n_topics = toc.lines().count(); | ||||||
|     verboseln!("(Das sind {} Themen.)", n_topics.to_string().cyan()); |     verboseln!("(Also {}.)", topic_count(n_topics, false).cyan()); | ||||||
|     // TODO: if
 |     (current_pad_id.to_string(), toc, n_topics) | ||||||
|     //         summary empty: write message variant
 | } | ||||||
|     //         summary not empty: write other message variant
 | 
 | ||||||
|     // TODO: set/write state as Announced
 | /* ***** transition actions ***** */ | ||||||
|     // TODO: write summary
 | 
 | ||||||
|     todo!() | // BBBBBBBBBB
 | ||||||
|  | 
 | ||||||
|  | fn do_announcement( | ||||||
|  |     ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, | ||||||
|  |     _wiki: &Mediawiki, | ||||||
|  | ) -> Result<(), Box<dyn Error>> { | ||||||
|  |     // fetch current pad contents & summarize
 | ||||||
|  |     let (current_pad_id, toc, n_topics) = get_pad_info(config, hedgedoc); | ||||||
|  |     // construct email
 | ||||||
|  |     let subject = format!( | ||||||
|  |         "Plenum {} (am {}): bisher {}", | ||||||
|  |         relative_date(ttp), | ||||||
|  |         plenum_day.format("%d.%m.%Y"), | ||||||
|  |         topic_count(n_topics, false) | ||||||
|  |     ); | ||||||
|  |     let line1 = if n_topics == 0 { | ||||||
|  |         format!( "Es sind bisher leider noch keine Themen zusammengekommen. Wenn am Montag immer noch nix ist, dann fällt das Plenum aus." ) | ||||||
|  |     } else { | ||||||
|  |         format!("Die bisherigen Themen für das Plenum sind:\n\n{toc}") | ||||||
|  |     }; | ||||||
|  |     let line2 = format!( | ||||||
|  |         "Falls ihr noch Themen ergänzen wollt ist hier der Link zum Pad:\n  {}", | ||||||
|  |         hedgedoc.format_url(¤t_pad_id) | ||||||
|  |     ); | ||||||
|  |     let body = format!("{line1}\n\n{line2}"); | ||||||
|  |     // send it
 | ||||||
|  |     let message_id = send_email(&subject, &body, &email, &config)?; | ||||||
|  |     // on success, update state (ignore write errors, they'll be checked later)
 | ||||||
|  |     config.set("email-message-id", &message_id).ok(); | ||||||
|  |     config.set("state-name", &ProgramState::Announced.to_string()).ok(); | ||||||
|  |     config.set("state-toc", &toc).ok(); | ||||||
|  |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(unused_variables)] |  | ||||||
| fn do_reminder( | fn do_reminder( | ||||||
|     ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, |     ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, | ||||||
|     wiki: &Mediawiki, |     _wiki: &Mediawiki, | ||||||
| ) -> Result<(), Box<dyn Error>> { | ) -> Result<(), Box<dyn Error>> { | ||||||
|     // TODO: get pad
 |     // fetch current pad contents & summarize
 | ||||||
|     // TODO: make summary
 |     let (current_pad_id, toc, n_topics) = get_pad_info(config, hedgedoc); | ||||||
|     // TODO: if
 |     let old_toc = config.get("state-toc").unwrap_or_default(); | ||||||
|     //         summary empty: write message variant
 |     // construct email
 | ||||||
|     //         summary not empty: make diff, send diff etc.
 |     let subject_suffix = if n_topics == 0 { | ||||||
|     // TODO: set/write state as Reminded
 |         " fällt aus (keine Themen)".to_string() | ||||||
|     // TODO: write summary
 |     } else { | ||||||
|     todo!() |         format!(" findet mit {} statt", topic_count(n_topics, true)) | ||||||
|  |     }; | ||||||
|  |     let subject = format!( | ||||||
|  |         "Plenum {} (am {}) {}", | ||||||
|  |         relative_date(ttp), | ||||||
|  |         plenum_day.format("%d.%m.%Y"), | ||||||
|  |         subject_suffix | ||||||
|  |     ); | ||||||
|  |     let body_prefix = if old_toc == toc { | ||||||
|  |         format!("Die Themen sind gleich geblieben. ") | ||||||
|  |     } else { | ||||||
|  |         format!("Es gab nochmal Änderungen, die aktualisierten Themen für das Plenum sind:\n\n{toc}\n\n") | ||||||
|  |     }; | ||||||
|  |     let body = if n_topics > 0 { | ||||||
|  |         format!( | ||||||
|  |             "{body_prefix}Die vollen Details findet ihr im Pad:\n  {}", | ||||||
|  |             hedgedoc.format_url(¤t_pad_id) | ||||||
|  |         ) | ||||||
|  |     } else { | ||||||
|  |         "Da es immer noch keine Themen gibt fällt das Plenum aus.\n\n".to_string() | ||||||
|  |         + "(Natürlich könnt ihr im Bedarfsfall immer noch kurzfristig ein Treffen einberufen, aber bitte " | ||||||
|  |         + "kündigt das so früh wie möglich an, damit Leute sich darauf einstellen können.)" | ||||||
|  |         // TODO generate + add link for next pad
 | ||||||
|  |     }; | ||||||
|  |     // send it
 | ||||||
|  |     let _message_id = send_email(&subject, &body, &email, &config)?; | ||||||
|  |     // on success, update state (ignore write errors, they'll be checked later)
 | ||||||
|  |     config.set("state-name", &ProgramState::Reminded.to_string()).ok(); | ||||||
|  |     config.set("state-toc", &toc).ok(); | ||||||
|  |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(unused_variables)] | #[allow(unused_variables)] | ||||||
|  | @ -880,11 +932,13 @@ impl std::fmt::Display for ProgramState { | ||||||
| 
 | 
 | ||||||
| /* ***** wrappers ***** */ | /* ***** wrappers ***** */ | ||||||
| 
 | 
 | ||||||
| fn send_email(subject: &str, body: &str, email: &SimpleEmail, config: &KV) -> Option<String> { | fn send_email( | ||||||
|  |     subject: &str, body: &str, email: &SimpleEmail, config: &KV, | ||||||
|  | ) -> Result<String, Box<dyn Error>> { | ||||||
|     let full_subject = format!("[PleB] {}", subject); |     let full_subject = format!("[PleB] {}", subject); | ||||||
|     let full_body = format!( |     let full_body = format!( | ||||||
|         "{}\n\n{}\n\n{}", |         "{}\n\n{}\n\n{}", | ||||||
|         &config["text-email-greeting"], body, &config["text-email-signature"] |         &config["text-email-greeting"], body, &config["text-email-signature"] | ||||||
|     ); |     ); | ||||||
|     email.send_email(full_subject, full_body).ok() |     email.send_email(full_subject, full_body) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 nobody
						nobody