1
0
Fork 0

Improve routine using

This commit is contained in:
Malte Brandy 2018-06-14 23:59:36 +02:00
parent ca16d4edd5
commit dc0fe66016
No known key found for this signature in database
GPG key ID: 226A2D41EF5378C9
4 changed files with 232 additions and 139 deletions

View file

@ -1,10 +0,0 @@
extern crate rust_scripts;
use rust_scripts::{
error::Result,
kassandra::kassandra
};
fn main() -> Result<()> {
kassandra()
}

View file

@ -13,11 +13,11 @@ use dialog::rofi::RofiDialogProvider;
use dialog::DialogProvider;
use dialog::errors::ErrorKind as DEK;
use update::update_tasks;
use generate::GeneratedTask;
use update::{update_tasks, process_task};
use error::{Result, ResultExt, ErrorKind as EK, Error};
use hotkeys::{str2cmd, term_cmd};
use hotkeys::str2cmd;
use tasktree::{TreeCache, TaskNode};
use well_known::{INBOX, ACCOUNTING, TREESORT};
fn prio_name(prio: Option<&TaskPriority>) -> &'static str {
match prio {
@ -47,7 +47,9 @@ fn print_task(task: &Task) -> String {
info.push(format!("project: {}", project));
}
if let Some(tags) = task.tags() {
info.push(format!("tags: +{}", tags.join(", +")));
if tags.len() > 0 {
info.push(format!("tags: +{}", tags.join(", +")));
}
}
info.push(format!("priority: {}", prio_name(task.priority())));
info.join("\n")
@ -107,7 +109,7 @@ pub struct State {
mpd: MPD,
}
fn task_blocked(cache: &TaskCache, task: &Task) -> bool {
pub fn task_blocked(cache: &TaskCache, task: &Task) -> bool {
task.depends()
.map(|dependencies| {
for dependency in dependencies {
@ -123,8 +125,7 @@ fn task_blocked(cache: &TaskCache, task: &Task) -> bool {
.unwrap_or(false)
}
fn task_inbox(cache: &TaskCache, task: &Task) -> bool {
pub fn task_in_inbox(cache: &TaskCache, task: &Task) -> bool {
task.pending() && !task.tagged() && !task_blocked(cache, task)
}
@ -166,14 +167,14 @@ fn enter_new_task<T: DialogProvider, S: Into<String>>(dialog: &mut T, msg: S) ->
.build()?)
}
fn needs_sorting(task: &Task) -> bool {
pub fn needs_sorting(task: &Task) -> bool {
!task.has_tag("project") && task.partof().map(|x| x.is_none()).unwrap_or(false)
}
struct Kassandra {
state: State,
dialog: RofiDialogProvider,
cache: TaskCache,
pub struct Kassandra {
pub state: State,
pub dialog: RofiDialogProvider,
pub cache: TaskCache,
}
@ -186,36 +187,21 @@ impl Kassandra {
})
}
fn run(&mut self) -> Result<()> {
self.cache.load()?;
update_tasks(&mut self.cache)?;
self.cache.write()?;
self.handle_active_tasks()?;
self.clear_inbox()?;
self.cache.refresh_tree();
self.assure_all_sorted()?;
// check unread E-Mail + ak?
// update
// system
// home
// mails
// sort inbox
// sort inboxkiva
// sort inboxak
// sort to sort
// go trough todo
// go trough toread
// go trough readlater
// pick tasks
// optional, later
// await
// dirty gits
// task generator
// task completion helper
self.update_accounting()?;
// CHECK_UNREAD_CHATS
// CHECK_INBOXES
// maralorn.de
// kiva
// ak
process_task(self, &*INBOX)?;
process_task(self, &*TREESORT)?;
process_task(self, &*ACCOUNTING)?;
self.select_next_task()?;
Ok(())
}
@ -341,27 +327,13 @@ What's the progress?",
}
pub fn assure_all_sorted(&mut self) -> Result<()> {
if self.cache
.filter(|t| {
t.gen_name() == Some(&"Sortiere Tasktree".into()) && t.pending()
})
self.cache.refresh_tree();
while let Some(uuid) = self.get_sorted_uuids(|t| !t.obsolete() && needs_sorting(t))
.into_iter()
.next()
.is_some()
{
while let Some(uuid) = self.get_sorted_uuids(|t| !t.obsolete() && needs_sorting(t))
.into_iter()
.next()
{
self.sort(&uuid)?;
}
for task in self.cache.filter_mut(|t| {
t.gen_name() == Some(&"Sortiere Tasktree".into()) && t.pending()
})
{
task.tw_done()
}
self.sort(&uuid)?;
self.cache.refresh_tree();
self.cache.write()?;
}
Ok(())
}
@ -609,26 +581,11 @@ What's the progress?",
}
pub fn clear_inbox(&mut self) -> Result<()> {
if self.cache
.filter(|t| {
t.gen_name() == Some(&"Leere Inbox".into()) && t.pending()
})
while let Some(uuid) = self.get_sorted_uuids(|t| task_in_inbox(&self.cache, t))
.into_iter()
.next()
.is_some()
{
while let Some(uuid) = self.get_sorted_uuids(|t| task_inbox(&self.cache, t))
.into_iter()
.next()
{
self.handle_task(&uuid)?;
}
for task in self.cache.filter_mut(|t| {
t.gen_name() == Some(&"Leere Inbox".into()) && t.pending()
})
{
task.tw_done()
}
self.cache.write()?;
self.handle_task(&uuid)?;
}
Ok(())
}
@ -813,22 +770,6 @@ What's the progress?",
Ok(())
}
pub fn update_accounting(&mut self) -> Result<()> {
if self.cache
.filter(|t| {
t.gen_name() == Some(&"Aktualisiere Buchhaltung".into()) && t.pending()
})
.next()
.is_some()
{
str2cmd(&term_cmd("sh -c"))
.arg("jali -l. && task gen_id:'Aktualisiere Buchhaltung' done")
.output()?;
}
self.cache.write()?;
Ok(())
}
pub fn select_next_task(&mut self) -> Result<()> {
#[derive(PartialEq)]
enum State {
@ -983,9 +924,7 @@ What's the progress?",
match self.state.mode {
Mode::Research => task.has_tag("research"),
Mode::Work => {
task.has_tag("work") || task.has_tag("pc") || can_do_this_here(self.state.location)
}
Mode::Work => task.has_tag("work") || can_do_this_here(self.state.location),
Mode::Orga => task.has_tag("pc") || can_do_this_here(self.state.location),
Mode::Idle => false,
}

View file

@ -1,17 +1,62 @@
use task_hookrs::error::Result;
use task_hookrs::cache::TaskCache;
use refresh::TaskRefresher;
use tasktree::TreeCache;
use well_known::{SIMPLE, WellKnown};
use tasktree::{TreeCache, TaskNode};
use well_known::{SIMPLE, WellKnown, INBOX, ACCOUNTING, TREESORT};
use error::Result;
use kassandra::Kassandra;
fn check_completion(cache: &mut TaskCache, task: &impl WellKnown) -> Result<()> {
if !task.action_necessary(cache)? {
let uuid = cache
.filter(|t| task.is_this(t) && t.pending())
.map(|t| t.uuid().clone())
.next();
if let Some(uuid) = uuid {
cache.get_mut(&uuid).unwrap().tw_done();
}
}
Ok(())
}
fn is_active(cache: &TaskCache, task: &impl WellKnown) -> bool {
cache
.filter(|t| task.is_this(t) && t.pending())
.next()
.is_some()
}
fn update_task(cache: &mut TaskCache, task: &impl WellKnown) -> Result<()> {
cache.reactivate(
Some(task.definition().clone()),
task.refresh(),
)?;
check_completion(cache, task)
}
pub fn process_task(kassandra: &mut Kassandra, task: &impl WellKnown) -> Result<()> {
update_task(&mut kassandra.cache, task)?;
if is_active(&mut kassandra.cache, task) {
kassandra.cache.write()?;
task.process(kassandra)?;
kassandra.cache.refresh()?;
update_task(&mut kassandra.cache, task)?;
}
kassandra.cache.write()?;
Ok(())
}
pub fn update_tasks(cache: &mut TaskCache) -> Result<()> {
for simple_task in SIMPLE.iter() {
cache.reactivate(
Some(simple_task.definition().clone()),
simple_task.refresh(),
)?;
update_task(cache, simple_task)?;
}
update_task(cache, &*INBOX)?;
update_task(cache, &*TREESORT)?;
update_task(cache, &*ACCOUNTING)?;
cache.refresh_tree();
// CREATE TODOS FROM MAIL
// FROM GITLAB
// FROM OTRS
// FROM GITHUBgT
Ok(())
}

View file

@ -2,9 +2,11 @@ use task_hookrs::task::{Task, TaskBuilder};
use task_hookrs::cache::TaskCache;
use error::Result;
use kassandra::State;
use generate::{gen_match, GeneratedTask};
use refresh::{Timer, CalendarRepeater, Interval};
use kassandra::{Kassandra, task_in_inbox, needs_sorting};
use hotkeys::{str2cmd, term_cmd};
use tasktree::TaskNode;
use chrono::{NaiveDate, NaiveTime, Duration};
@ -13,15 +15,53 @@ pub trait WellKnown {
fn is_this(&self, task: &Task) -> bool {
gen_match(task, self.definition())
}
fn action_necessary(&self, &TaskCache, State) -> Result<bool> {
fn action_necessary(&self, &TaskCache) -> Result<bool> {
Ok(true)
}
fn process(&self, &mut TaskCache, State) -> Result<()> {
fn process(&self, &mut Kassandra) -> Result<()> {
Ok(())
}
fn refresh(&self) -> Timer;
}
lazy_static! {
pub static ref SIMPLE: Vec<SimpleTask> = make_simple();
pub static ref INBOX: Inbox = Inbox {
timer: Timer::Repetition(CalendarRepeater {
date: NaiveDate::from_ymd(2018, 5, 8),
time: NaiveTime::from_hms(20, 0, 0),
repeat: Interval::Day(1),
})};
pub static ref TREESORT: Treesort = Treesort {
timer: Timer::Repetition(CalendarRepeater {
date: NaiveDate::from_ymd(2018, 5, 8),
time: NaiveTime::from_hms(20, 0, 0),
repeat: Interval::Day(1),
})};
pub static ref ACCOUNTING: Accounting = Accounting {
timer: Timer::Repetition(CalendarRepeater {
date: NaiveDate::from_ymd(2018, 5, 8),
time: NaiveTime::from_hms(20, 0, 0),
repeat: Interval::Day(1),
})};
pub static ref CHECK_MEDIUM: SimpleTask = unimplemented!(); // auch +await // einfach
pub static ref CHECK_LOW: SimpleTask = unimplemented!(); // einfach
pub static ref CHECK_NONE: SimpleTask = unimplemented!(); //einfach
pub static ref CHECK_OPTIONAL: SimpleTask = unimplemented!(); // zufällig 10 //einfach
pub static ref CHECK_DIRTY_GITS: SimpleTask = unimplemented!(); // nicht so wichtig
pub static ref SORT_INBOX: SimpleTask = unimplemented!(); // wichtig
pub static ref SORT_INBOX_KIVA: SimpleTask = unimplemented!(); // wichtig
pub static ref SORT_INBOX_AK: SimpleTask = unimplemented!(); // wichtig
pub static ref SORT_MAIL: SimpleTask = unimplemented!(); // zufällige 50? nicht so wichtig
pub static ref SORT_MAIL_KIVA: SimpleTask = unimplemented!(); // nicht so wichtig
pub static ref SORT_MAIL_AK: SimpleTask = unimplemented!(); // nicht so wichtig
pub static ref SORT_SPAM: SimpleTask = unimplemented!(); // nicht so wichtig
pub static ref UPDATE_APOLLO: SimpleTask = unimplemented!(); // einfach aber nicht dringend
pub static ref GC_APOLLO: SimpleTask = unimplemented!(); // einfach aber nicht dringend
pub static ref OPT_APOLLO: SimpleTask = unimplemented!(); // einfach aber nicht dringend
pub static ref BACKUP_APOLLO: SimpleTask = unimplemented!(); // einfach aber nicht dringend
}
pub struct SimpleTask {
definition: Task,
timer: Timer,
@ -61,7 +101,7 @@ fn simple_task(name: &str, timer: Timer) -> SimpleTask {
SimpleTask::new(name, name, name, timer)
}
fn simple_tasks<'a>(
fn simple_tasks(
names: impl IntoIterator<Item = impl Into<String>>,
timer: Timer,
) -> impl Iterator<Item = SimpleTask> {
@ -101,45 +141,124 @@ fn make_simple() -> Vec<SimpleTask> {
vec!["Friseurtermin machen"],
Timer::DeadTime(Duration::weeks(6)),
))
.chain(simple_tasks(vec!["Klavier üben"], daily))
.chain(simple_tasks(vec!["Verbuche Kontoauszüge"], monthly))
.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();
pub struct Inbox {
timer: Timer,
}
impl WellKnown for Inbox {
fn definition(&self) -> &Task {
lazy_static! {
static ref TASK: Task = {
let mut t = TaskBuilder::default()
.description("Leere Inbox")
.build()
.expect("TaskBuilding failed inspite of set description");
t.set_gen_name(Some("inbox"));
t.set_gen_id(Some("inbox"));
t
};
};
&TASK
}
fn action_necessary(&self, cache: &TaskCache) -> Result<bool> {
Ok(cache.filter(|t| task_in_inbox(&cache, t)).next().is_some())
}
fn process(&self, kassandra: &mut Kassandra) -> Result<()> {
kassandra.clear_inbox()
}
fn refresh(&self) -> Timer {
self.timer.clone()
}
}
pub struct Accounting {
timer: Timer,
}
impl WellKnown for Accounting {
fn definition(&self) -> &Task {
lazy_static! {
static ref TASK: Task = {
let mut t = TaskBuilder::default()
.description("Aktualisiere Buchhaltung")
.build()
.expect("TaskBuilding failed inspite of set description");
t.set_gen_name(Some("accounting"));
t.set_gen_id(Some("accounting"));
t
};
};
&TASK
}
fn action_necessary(&self, _cache: &TaskCache) -> Result<bool> {
Ok(true)
}
fn process(&self, _kassandra: &mut Kassandra) -> Result<()> {
str2cmd(&term_cmd("sh -c"))
.arg("jali -l. && task gen_id:accounting done")
.output()?;
Ok(())
}
fn refresh(&self) -> Timer {
self.timer.clone()
}
}
pub struct Treesort {
timer: Timer,
}
impl WellKnown for Treesort {
fn definition(&self) -> &Task {
lazy_static! {
static ref TASK: Task = {
let mut t = TaskBuilder::default()
.description("Sortiere Tasktree")
.build()
.expect("TaskBuilding failed inspite of set description");
t.set_gen_name(Some("treesort"));
t.set_gen_id(Some("treesort"));
t
};
};
&TASK
}
fn action_necessary(&self, cache: &TaskCache) -> Result<bool> {
Ok(
cache
.filter(|t| !t.obsolete() && needs_sorting(t))
.next()
.is_some(),
)
}
fn process(&self, kassandra: &mut Kassandra) -> Result<()> {
kassandra.assure_all_sorted()
}
fn refresh(&self) -> Timer {
self.timer.clone()
}
}