Refactor codes for recurring tasks
This commit is contained in:
parent
69b8993d4d
commit
3c643f1abc
|
@ -274,7 +274,7 @@ where
|
|||
T::Item: Into<Task>;
|
||||
}
|
||||
|
||||
fn gen_match(a: &Task, b: &Task) -> bool {
|
||||
pub fn gen_match(a: &Task, b: &Task) -> bool {
|
||||
a.gen_name() == b.gen_name() && a.gen_id() == b.gen_id()
|
||||
}
|
||||
impl TaskGenerator for TaskCache {
|
||||
|
|
|
@ -100,7 +100,7 @@ enum MPD {
|
|||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
struct State {
|
||||
pub struct State {
|
||||
mode: Mode,
|
||||
location: Location,
|
||||
connectivity: Connectivity,
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate uuid;
|
|||
extern crate task_hookrs;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate kairos;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
@ -17,6 +16,7 @@ pub mod refresh;
|
|||
pub mod update;
|
||||
pub mod kassandra;
|
||||
pub mod tasktree;
|
||||
pub mod well_known;
|
||||
|
||||
pub mod error {
|
||||
use task_hookrs::error as terror;
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
use chrono::offset::{Local, TimeZone};
|
||||
use chrono::Duration;
|
||||
|
||||
use kairos::timetype::TimeType as TT;
|
||||
use kairos::iter::Iter;
|
||||
use kairos::error::Result as KairosResult;
|
||||
use chrono::{NaiveDate, Duration, NaiveTime, Datelike, NaiveDateTime};
|
||||
|
||||
use task_hookrs::status::TaskStatus as TS;
|
||||
use task_hookrs::task::Task;
|
||||
|
@ -14,9 +10,47 @@ use task_hookrs::date::Date;
|
|||
use generate::TaskGenerator;
|
||||
use tasktree::TaskNode;
|
||||
|
||||
#[derive(Copy, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Timer {
|
||||
DeadTime(Duration),
|
||||
Repetition(Iter),
|
||||
Repetition(CalendarRepeater),
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Interval {
|
||||
Year(i32),
|
||||
Month(u32),
|
||||
Day(i32),
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct CalendarRepeater {
|
||||
pub time: NaiveTime,
|
||||
pub date: NaiveDate,
|
||||
pub repeat: Interval,
|
||||
}
|
||||
|
||||
impl Iterator for CalendarRepeater {
|
||||
type Item = NaiveDateTime;
|
||||
fn next(&mut self) -> Option<NaiveDateTime> {
|
||||
let ret = Some(self.date.clone().and_time(self.time));
|
||||
self.date = match self.repeat {
|
||||
Interval::Year(year) => {
|
||||
NaiveDate::from_ymd(self.date.year() + year, self.date.month(), self.date.day())
|
||||
}
|
||||
Interval::Month(month) => {
|
||||
NaiveDate::from_ymd(
|
||||
self.date.year() + ((self.date.month() + month - 1) / 12) as i32,
|
||||
1 + ((self.date.month() + month - 1) % 12),
|
||||
self.date.day(),
|
||||
)
|
||||
}
|
||||
Interval::Day(day) => NaiveDate::from_num_days_from_ce(
|
||||
self.date.num_days_from_ce() + day,
|
||||
),
|
||||
};
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TaskRefresher {
|
||||
|
@ -34,12 +68,10 @@ impl TaskRefresher for TaskCache {
|
|||
recurrence: Timer,
|
||||
) -> Result<()> {
|
||||
let now = Local::now();
|
||||
let now_moment = TT::Moment(Local::now().naive_local());
|
||||
let recent = match recurrence {
|
||||
Timer::DeadTime(time) => TT::Moment((now - time).naive_local()),
|
||||
Timer::DeadTime(time) => (now - time).naive_local(),
|
||||
Timer::Repetition(iter) => {
|
||||
iter.filter_map(KairosResult::ok)
|
||||
.take_while(|t| *t <= now_moment)
|
||||
iter.take_while(|t| *t <= now.naive_local())
|
||||
.last()
|
||||
.ok_or("Repetition starts in the future")?
|
||||
.clone()
|
||||
|
@ -50,13 +82,11 @@ impl TaskRefresher for TaskCache {
|
|||
.into_iter()
|
||||
.filter(|task| if let Some(old) = self.get_by_gen(&task) {
|
||||
if old.obsolete() &&
|
||||
TT::Moment(
|
||||
Local
|
||||
.from_utc_datetime(
|
||||
&**old.end().expect("Ended tasks have to have an end date"),
|
||||
)
|
||||
.naive_local(),
|
||||
) < recent
|
||||
Local
|
||||
.from_utc_datetime(
|
||||
&**old.end().expect("Ended tasks have to have an end date"),
|
||||
)
|
||||
.naive_local() < recent
|
||||
{
|
||||
uuids.push(old.uuid().clone());
|
||||
}
|
||||
|
|
|
@ -1,107 +1,17 @@
|
|||
use task_hookrs::{
|
||||
error::Result,
|
||||
cache::TaskCache,
|
||||
task::{Task, TaskBuilder}
|
||||
};
|
||||
use generate::GeneratedTask;
|
||||
use refresh::{TaskRefresher, Timer};
|
||||
use task_hookrs::error::Result;
|
||||
use task_hookrs::cache::TaskCache;
|
||||
|
||||
use refresh::TaskRefresher;
|
||||
use tasktree::TreeCache;
|
||||
use chrono::{NaiveDate,Duration};
|
||||
use kairos::{
|
||||
timetype::TimeType as TT,
|
||||
iter::extensions::{Weekly, Monthly, Daily}
|
||||
};
|
||||
|
||||
fn simple_task(name: &str) -> Task {
|
||||
let mut task = TaskBuilder::default().description(name).build().expect(
|
||||
"TaskBuilding failed inspite of set description",
|
||||
);
|
||||
task.set_gen_name(Some(name));
|
||||
task.set_gen_id(Some(name));
|
||||
task
|
||||
}
|
||||
|
||||
fn simple_tasks<'a>(names: impl IntoIterator<Item = &'a str>) -> impl Iterator<Item = Task> {
|
||||
names.into_iter().map(simple_task)
|
||||
}
|
||||
use well_known::{SIMPLE, WellKnown};
|
||||
|
||||
pub fn update_tasks(cache: &mut TaskCache) -> Result<()> {
|
||||
let daily = || {
|
||||
Timer::Repetition(
|
||||
TT::moment(NaiveDate::from_ymd(2018, 5, 8).and_hms(20, 0, 0))
|
||||
.daily(1)
|
||||
.unwrap(),
|
||||
)
|
||||
};
|
||||
let weekly = || {
|
||||
Timer::Repetition(
|
||||
TT::moment(NaiveDate::from_ymd(2018, 5, 8).and_hms(20, 0, 0))
|
||||
.weekly(1)
|
||||
.unwrap(),
|
||||
)
|
||||
};
|
||||
let monthly = || {
|
||||
Timer::Repetition(
|
||||
TT::moment(NaiveDate::from_ymd(2018, 5, 3).and_hms(20, 0, 0))
|
||||
.monthly(1)
|
||||
.unwrap(),
|
||||
)
|
||||
};
|
||||
cache.reactivate(
|
||||
simple_tasks(vec![
|
||||
"Staubsaugen",
|
||||
"Putze Waschbecken",
|
||||
"Wäsche sortieren und entscheiden, welche Waschgänge notwendig sind",
|
||||
]),
|
||||
Timer::DeadTime(Duration::weeks(2)),
|
||||
)?;
|
||||
cache.reactivate(
|
||||
simple_tasks(
|
||||
vec!["Reinige Toilette", "Zehennägel schneiden"],
|
||||
),
|
||||
Timer::DeadTime(Duration::weeks(4)),
|
||||
)?;
|
||||
cache.reactivate(
|
||||
simple_tasks(vec!["Friseurtermin machen"]),
|
||||
Timer::DeadTime(Duration::weeks(6)),
|
||||
)?;
|
||||
cache.reactivate(
|
||||
simple_tasks(vec![
|
||||
"Aktualisiere Buchhaltung",
|
||||
"Leere Inbox",
|
||||
"Sortiere Tasktree",
|
||||
"Sortiere Inbox",
|
||||
"Sortiere Inbox Auslandskoordination",
|
||||
"Sortiere Inbox Kiva",
|
||||
"Klavier üben",
|
||||
"Tasks der Woche kontrollieren"
|
||||
]),
|
||||
daily(),
|
||||
)?;
|
||||
cache.reactivate(
|
||||
simple_tasks(vec!["Kontrolliere +optional","Verbuche Kontoauszüge"]),
|
||||
monthly(),
|
||||
)?;
|
||||
cache.reactivate(
|
||||
simple_tasks(vec![
|
||||
"Kontrolliere Spam",
|
||||
"Korrigiere Portemonnaiezählstand",
|
||||
"Sortiere Archiv",
|
||||
"Sortiere Archiv Kiva",
|
||||
"Sortiere Archiv Auslandskoordination",
|
||||
"Kontrolliere +later",
|
||||
|
||||
"Kontrolliere +await",
|
||||
"Block leeren und wegsortieren",
|
||||
"Leere Kiva Fächer",
|
||||
"Inbox zu Hause wegsortieren",
|
||||
"Cryptpads sichern",
|
||||
"Update nixos apollo",
|
||||
"Update home hephaistos",
|
||||
"Tasks des Monats kontrollieren"
|
||||
]),
|
||||
weekly(),
|
||||
)?;
|
||||
for simple_task in SIMPLE.iter() {
|
||||
cache.reactivate(
|
||||
Some(simple_task.definition().clone()),
|
||||
simple_task.refresh(),
|
||||
)?;
|
||||
}
|
||||
cache.refresh_tree();
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,8 +1,145 @@
|
|||
use task_hookrs::task::{Task, TaskBuilder};
|
||||
use task_hookrs::cache::TaskCache;
|
||||
|
||||
pub Trait {
|
||||
fn definition() -> Task
|
||||
fn is_task(&Task) -> bool
|
||||
fn action_necessary(&TaskCache, State) -> Result<bool>
|
||||
fn process(&mut TaskCache) -> Result<()>
|
||||
fn refresh() -> refresh::Timer
|
||||
use error::Result;
|
||||
use kassandra::State;
|
||||
use generate::{gen_match, GeneratedTask};
|
||||
use refresh::{Timer, CalendarRepeater, Interval};
|
||||
|
||||
use chrono::{NaiveDate, NaiveTime, Duration};
|
||||
|
||||
pub trait WellKnown {
|
||||
fn definition(&self) -> &Task;
|
||||
fn is_this(&self, task: &Task) -> bool {
|
||||
gen_match(task, self.definition())
|
||||
}
|
||||
fn action_necessary(&self, &TaskCache, State) -> Result<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
fn process(&self, &mut TaskCache, State) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn refresh(&self) -> Timer;
|
||||
}
|
||||
|
||||
pub struct SimpleTask {
|
||||
definition: Task,
|
||||
timer: Timer,
|
||||
}
|
||||
|
||||
impl SimpleTask {
|
||||
fn new(
|
||||
description: impl Into<String>,
|
||||
gen_name: impl Into<String>,
|
||||
gen_id: impl Into<String>,
|
||||
timer: Timer,
|
||||
) -> Self {
|
||||
let mut task = TaskBuilder::default()
|
||||
.description(description.into())
|
||||
.build()
|
||||
.expect("TaskBuilding failed inspite of set description");
|
||||
task.set_gen_name(Some(gen_name.into()));
|
||||
task.set_gen_id(Some(gen_id.into()));
|
||||
SimpleTask {
|
||||
definition: task,
|
||||
timer: timer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl WellKnown for SimpleTask {
|
||||
fn definition(&self) -> &Task {
|
||||
&self.definition
|
||||
}
|
||||
fn refresh(&self) -> Timer {
|
||||
self.timer.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn simple_task(name: &str, timer: Timer) -> SimpleTask {
|
||||
SimpleTask::new(name, name, name, timer)
|
||||
}
|
||||
|
||||
fn simple_tasks<'a>(
|
||||
names: impl IntoIterator<Item = impl Into<String>>,
|
||||
timer: Timer,
|
||||
) -> impl Iterator<Item = SimpleTask> {
|
||||
names.into_iter().map(move |x| {
|
||||
simple_task(&x.into(), timer.clone())
|
||||
})
|
||||
}
|
||||
|
||||
fn make_simple() -> Vec<SimpleTask> {
|
||||
let daily = Timer::Repetition(CalendarRepeater {
|
||||
date: NaiveDate::from_ymd(2018, 5, 8),
|
||||
time: NaiveTime::from_hms(20, 0, 0),
|
||||
repeat: Interval::Day(1),
|
||||
});
|
||||
let weekly = Timer::Repetition(CalendarRepeater {
|
||||
date: NaiveDate::from_ymd(2018, 5, 8),
|
||||
time: NaiveTime::from_hms(20, 0, 0),
|
||||
repeat: Interval::Day(7),
|
||||
});
|
||||
let monthly = Timer::Repetition(CalendarRepeater {
|
||||
date: NaiveDate::from_ymd(2018, 5, 3),
|
||||
time: NaiveTime::from_hms(20, 0, 0),
|
||||
repeat: Interval::Month(1),
|
||||
});
|
||||
simple_tasks(
|
||||
vec![
|
||||
"Staubsaugen",
|
||||
"Putze Waschbecken",
|
||||
"Wäsche sortieren und entscheiden, welche Waschgänge notwendig sind",
|
||||
],
|
||||
Timer::DeadTime(Duration::weeks(2)),
|
||||
).chain(simple_tasks(
|
||||
vec!["Reinige Toilette", "Zehennägel schneiden"],
|
||||
Timer::DeadTime(Duration::weeks(4)),
|
||||
))
|
||||
.chain(simple_tasks(
|
||||
vec!["Friseurtermin machen"],
|
||||
Timer::DeadTime(Duration::weeks(6)),
|
||||
))
|
||||
.chain(simple_tasks(
|
||||
vec![
|
||||
"Aktualisiere Buchhaltung",
|
||||
"Leere Inbox",
|
||||
"Sortiere Tasktree",
|
||||
"Sortiere Inbox",
|
||||
"Sortiere Inbox Auslandskoordination",
|
||||
"Sortiere Inbox Kiva",
|
||||
"Klavier üben",
|
||||
"Tasks der Woche kontrollieren",
|
||||
],
|
||||
daily,
|
||||
))
|
||||
.chain(simple_tasks(
|
||||
vec!["Kontrolliere +optional", "Verbuche Kontoauszüge"],
|
||||
monthly,
|
||||
))
|
||||
.chain(simple_tasks(
|
||||
vec![
|
||||
"Kontrolliere Spam",
|
||||
"Korrigiere Portemonnaiezählstand",
|
||||
"Sortiere Archiv",
|
||||
"Sortiere Archiv Kiva",
|
||||
"Sortiere Archiv Auslandskoordination",
|
||||
"Kontrolliere +later",
|
||||
"Kontrolliere +await",
|
||||
"Block leeren und wegsortieren",
|
||||
"Leere Kiva Fächer",
|
||||
"Inbox zu Hause wegsortieren",
|
||||
"Cryptpads sichern",
|
||||
"Update nixos apollo",
|
||||
"Update home hephaistos",
|
||||
"Tasks des Monats kontrollieren",
|
||||
],
|
||||
weekly,
|
||||
))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref SIMPLE: Vec<SimpleTask> = make_simple();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue