1
0
Fork 0

Refactor codes for recurring tasks

This commit is contained in:
Malte Brandy 2018-06-10 18:10:22 +02:00
parent 69b8993d4d
commit 3c643f1abc
No known key found for this signature in database
GPG key ID: 226A2D41EF5378C9
6 changed files with 204 additions and 127 deletions

View file

@ -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 {

View file

@ -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,

View file

@ -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;

View file

@ -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());
}

View file

@ -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(())
}

View file

@ -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();
}