main: more date logic
This commit is contained in:
parent
e4aae07113
commit
88450b7a61
124
src/main.rs
124
src/main.rs
|
@ -179,22 +179,23 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
&config["wiki-http-password"],
|
||||
is_dry_run(),
|
||||
);
|
||||
// get next plenum days
|
||||
let today = Local::now().date_naive();
|
||||
let plenum_spec = date::parse_spec(&config["date-spec"])?;
|
||||
let nearest_plenum_days = date::get_matching_dates_around(today, plenum_spec);
|
||||
// figure out where we are
|
||||
let mut last_state = ProgramState::parse(&config["state-name"]);
|
||||
let last_run = config.get("state-last-run").unwrap_or_default();
|
||||
let last_run = NaiveDate::parse_from_str(&last_run, "%Y-%m-%d").unwrap_or_default();
|
||||
// figure out where we should be
|
||||
let today = Local::now().date_naive();
|
||||
if (today - last_run).num_days() > 10 {
|
||||
if !matches!(last_state, ProgramState::Normal) {
|
||||
eprintln!("WARNING: last run was a long time ago, resetting state.");
|
||||
last_state = ProgramState::Normal;
|
||||
do_cleanup(999, &config, &hedgedoc, &email, &wiki)?;
|
||||
do_cleanup(999, &today, &config, &hedgedoc, &email, &wiki)?;
|
||||
}
|
||||
}
|
||||
let last_state = last_state;
|
||||
let plenum_spec = date::parse_spec(&config["date-spec"])?;
|
||||
let nearest_plenum_days = date::get_matching_dates_around(today, plenum_spec);
|
||||
// deltas has either 2 or 3 days, if 3 then the middle one is == 0 (i.e. today)
|
||||
let deltas: Vec<i64> = nearest_plenum_days.iter().map(|&d| (d - today).num_days()).collect();
|
||||
// find the relevant one:
|
||||
|
@ -212,6 +213,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
},
|
||||
}
|
||||
.unwrap(); // always has at least 2 elems
|
||||
let plenum_day = today.checked_add_signed(chrono::TimeDelta::days(delta)).unwrap();
|
||||
let intended_state = if delta > 3 {
|
||||
ProgramState::Normal // nothing to do 3+ days in advance
|
||||
} else if delta > 1 {
|
||||
|
@ -224,8 +226,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
ProgramState::Logged // after that, we want to log it to the list & the wiki
|
||||
};
|
||||
|
||||
let action: TransitionFunction = TRANSITION_LUT[last_state.index()][intended_state.index()];
|
||||
action(delta, &config, &hedgedoc, &email, &wiki)?;
|
||||
let action: TransitionFunction = TRANSITION_LUT[last_state as usize][intended_state as usize];
|
||||
action(delta, &plenum_day, &config, &hedgedoc, &email, &wiki)?;
|
||||
|
||||
// TODO: cleanup / write new state
|
||||
|
||||
|
@ -513,31 +515,62 @@ 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
|
||||
}
|
||||
|
||||
/* ***** formatting helpers ***** */
|
||||
|
||||
fn relative_date( ttp: i64 ) -> String {
|
||||
if ttp.abs() > 2 {
|
||||
if ttp.is_negative() {
|
||||
format!( "vor {} Tagen", -ttp )
|
||||
} else {
|
||||
format!( "in {} Tagen", ttp )
|
||||
}
|
||||
} else {
|
||||
match ttp {
|
||||
2 => "übermorgen",
|
||||
1 => "morgen",
|
||||
0 => "heute",
|
||||
-1 => "gestern",
|
||||
-2 => "vorgestern",
|
||||
_ => unreachable!(),
|
||||
}.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn upper_first(s: &str) -> String {
|
||||
let mut c = s.chars();
|
||||
match c.next() {
|
||||
Some(fst) => fst.to_uppercase().collect::<String>() + c.as_str(),
|
||||
None => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/* ***** transition actions ***** */
|
||||
|
||||
fn do_announcement(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// use TTP to adjust text if needed (in {ttp} days)
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn do_reminder(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// use TTP to adjust text if needed (tomorrow or today / in {ttp} days)
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn do_protocol(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// use TTP to adjust text if needed ({-ttp} days ago)
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// General cleanup function. Call as `(999, today, …)` for a complete reset
|
||||
/// based on today as the base date.
|
||||
fn do_cleanup(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
todo!()
|
||||
}
|
||||
|
@ -546,6 +579,7 @@ fn do_cleanup(
|
|||
|
||||
type TransitionFunction = fn(
|
||||
ttp: i64,
|
||||
plenum_day: &NaiveDate,
|
||||
config: &KV,
|
||||
hedgedoc: &HedgeDoc,
|
||||
email: &SimpleEmail,
|
||||
|
@ -562,22 +596,22 @@ const TRANSITION_LUT: [[TransitionFunction; 5]; 5] = [
|
|||
/* LOGGED */ [do_cleanup, do_clean_announcement, do_clean_reminder, nop, do_cleanup],
|
||||
];
|
||||
|
||||
fn nop(_: i64, _: &KV, _: &HedgeDoc, _: &SimpleEmail, _: &Mediawiki) -> Result<(), Box<dyn Error>> {
|
||||
fn nop(_: i64, _: &NaiveDate, _: &KV, _: &HedgeDoc, _: &SimpleEmail, _: &Mediawiki) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_clean_announcement(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
do_cleanup(ttp, config, hedgedoc, email, wiki)?;
|
||||
do_announcement(ttp, config, hedgedoc, email, wiki)
|
||||
do_cleanup(ttp, plenum_day, config, hedgedoc, email, wiki)?;
|
||||
do_announcement(ttp, plenum_day, config, hedgedoc, email, wiki)
|
||||
}
|
||||
|
||||
fn do_clean_reminder(
|
||||
ttp: i64, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
ttp: i64, plenum_day: &NaiveDate, config: &KV, hedgedoc: &HedgeDoc, email: &SimpleEmail, wiki: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
do_cleanup(ttp, config, hedgedoc, email, wiki)?;
|
||||
do_reminder(ttp, config, hedgedoc, email, wiki)
|
||||
do_cleanup(ttp, plenum_day, config, hedgedoc, email, wiki)?;
|
||||
do_reminder(ttp, plenum_day, config, hedgedoc, email, wiki)
|
||||
}
|
||||
|
||||
/// State machine type for the announcement logic, ensuring we can deal with
|
||||
|
@ -590,30 +624,32 @@ fn do_clean_reminder(
|
|||
/// - Waiting – just a day of delay (after it makes sense to send a reminder)
|
||||
/// - Logged – protocol was written to wiki & mailing list
|
||||
///
|
||||
/// The bot knows in which state it is at all times. It knows this because it
|
||||
/// knows in which state it isn't. By comparing where it is with where it
|
||||
/// isn't, it obtains a difference, or deviation. The program logic uses
|
||||
/// deviations to generate corrective commands to drive the bot from a state
|
||||
/// where it is to a state where it isn't, and arriving in a state where it
|
||||
/// wasn't, it now is. Consequently, the state where it is, is now the state
|
||||
/// that it wasn't, and it follows that the state that it was in, is now the
|
||||
/// state that it isn't in.
|
||||
///
|
||||
/// In the event that the state that it is in is not the state that it wasn't,
|
||||
/// the system has acquired a variation, the variation being the difference
|
||||
/// between where the bot is, and where it wasn't. If variation is considered
|
||||
/// to be a significant factor, it too may be corrected by the program logic.
|
||||
/// However, the bot must also know where it was.
|
||||
///
|
||||
/// The program logic works as follows. Because a delay has modified some
|
||||
/// of the information the bot has obtained, it is not sure just when it is.
|
||||
/// However, it is sure when it isn't, within reason, and it knows when it was.
|
||||
/// It now subtracts when it should be from when it wasn't, or vice-versa, and
|
||||
/// by differentiating this from the algebraic sum of when it shouldn't be,
|
||||
/// and when it was, it is able to obtain the deviation and its variation,
|
||||
/// which is called error.
|
||||
/// > The bot knows in which state it is at all times. It knows this because
|
||||
/// > it knows in which state it isn't. By comparing where it is with where
|
||||
/// > it isn't, it obtains a difference, or deviation. The program logic uses
|
||||
/// > deviations to generate corrective commands to drive the bot from a state
|
||||
/// > where it is to a state where it isn't, and arriving in a state where it
|
||||
/// > wasn't, it now is. Consequently, the state where it is, is now the state
|
||||
/// > that it wasn't, and it follows that the state that it was in, is now the
|
||||
/// > state that it isn't in.
|
||||
/// >
|
||||
/// > In the event that the state that it is in is not the state that it wasn't,
|
||||
/// > the system has acquired a variation, the variation being the difference
|
||||
/// > between where the bot is, and where it wasn't. If variation is considered
|
||||
/// > to be a significant factor, it too may be corrected by the program logic.
|
||||
/// > However, the bot must also know where it was.
|
||||
/// >
|
||||
/// > The program logic works as follows. Because a delay has modified some
|
||||
/// > of the information the bot has obtained, it is not sure just when it is.
|
||||
/// > However, it is sure when it isn't, within reason, and it knows when it was.
|
||||
/// > It now subtracts when it should be from when it wasn't, or vice-versa, and
|
||||
/// > by differentiating this from the algebraic sum of when it shouldn't be,
|
||||
/// > and when it was, it is able to obtain the deviation and its variation,
|
||||
/// > which is called error.
|
||||
#[derive(Default, Debug)]
|
||||
enum ProgramState {
|
||||
/// Normal is the default state, with no actions currently outstanding.
|
||||
#[default]
|
||||
Normal,
|
||||
/// There is an upcoming event, and the first announcement has been sent.
|
||||
Announced,
|
||||
|
@ -636,16 +672,6 @@ impl ProgramState {
|
|||
_ => ProgramState::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
fn index(&self) -> usize {
|
||||
match self {
|
||||
ProgramState::Normal => 0,
|
||||
ProgramState::Announced => 1,
|
||||
ProgramState::Reminded => 2,
|
||||
ProgramState::Waiting => 3,
|
||||
ProgramState::Logged => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ProgramState {
|
||||
|
|
Loading…
Reference in a new issue