commit
e702f049d0
12 changed files with 312 additions and 147 deletions
|
@ -8,16 +8,19 @@ clap = "2.4.3"
|
||||||
glob = "0.2.11"
|
glob = "0.2.11"
|
||||||
log = "0.3.6"
|
log = "0.3.6"
|
||||||
semver = "0.2.3"
|
semver = "0.2.3"
|
||||||
|
serde_json = "0.7.3"
|
||||||
|
task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" }
|
||||||
toml = "0.1.28"
|
toml = "0.1.28"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
task-hookrs = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies.libimagstore]
|
|
||||||
path = "../libimagstore"
|
|
||||||
|
|
||||||
[dependencies.libimagrt]
|
[dependencies.libimagrt]
|
||||||
path = "../libimagrt"
|
path = "../libimagrt"
|
||||||
|
|
||||||
|
[dependencies.libimagstore]
|
||||||
|
path = "../libimagstore"
|
||||||
|
|
||||||
|
[dependencies.libimagtodo]
|
||||||
|
path = "../libimagtodo"
|
||||||
|
|
||||||
[dependencies.libimagutil]
|
[dependencies.libimagutil]
|
||||||
path = "../libimagutil"
|
path = "../libimagutil"
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate glob;
|
extern crate glob;
|
||||||
extern crate task_hookrs;
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
extern crate serde_json;
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
#[macro_use] extern crate version;
|
#[macro_use] extern crate version;
|
||||||
|
|
||||||
|
extern crate task_hookrs;
|
||||||
|
|
||||||
extern crate libimagrt;
|
extern crate libimagrt;
|
||||||
extern crate libimagstore;
|
extern crate libimagstore;
|
||||||
extern crate libimagutil;
|
extern crate libimagutil;
|
||||||
|
extern crate libimagtodo;
|
||||||
|
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
use std::io::stdin;
|
||||||
|
use std::io::BufRead;
|
||||||
|
|
||||||
|
use task_hookrs::import::{import_task, import_tasks};
|
||||||
|
|
||||||
use libimagrt::runtime::Runtime;
|
use libimagrt::runtime::Runtime;
|
||||||
|
use libimagtodo::task::IntoTask;
|
||||||
|
use libimagutil::trace::trace_error;
|
||||||
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
@ -43,24 +52,90 @@ fn main() {
|
||||||
Some("tw-hook") => {
|
Some("tw-hook") => {
|
||||||
let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
|
let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
|
||||||
if subcmd.is_present("add") {
|
if subcmd.is_present("add") {
|
||||||
println!("To be implemented");
|
let stdin = stdin();
|
||||||
//
|
let mut stdin = stdin.lock();
|
||||||
// TODO @Kevin: import function aus task_hookrs benutzen, um
|
let mut line = String::new();
|
||||||
// stdin auszulesen, und dann auf dem
|
match stdin.read_line(&mut line) {
|
||||||
// task_hookrs::task::Task den Trait für die
|
Ok(_) => { }
|
||||||
// Umwandlung aufrufen.
|
Err(e) => {
|
||||||
//
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Ok(ttask) = import_task(&line.as_str()) {
|
||||||
|
let uuid = *ttask.uuid();
|
||||||
|
println!("{}", match serde_json::ser::to_string(&ttask) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
match ttask.into_filelockentry(rt.store()) {
|
||||||
|
Ok(val) => {
|
||||||
|
println!("Task {} stored in imag", uuid);
|
||||||
|
val
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
trace_error(&e);
|
||||||
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("No usable input");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if subcmd.is_present("delete") {
|
else if subcmd.is_present("delete") {
|
||||||
println!("To be implemented");
|
// The used hook is "on-modify". This hook gives two json-objects
|
||||||
//
|
// per usage und wants one (the second one) back.
|
||||||
// Functionality to delete Entry in the store
|
let mut counter = 0;
|
||||||
//
|
let stdin = stdin();
|
||||||
|
let stdin = stdin.lock();
|
||||||
|
if let Ok(ttasks) = import_tasks(stdin) {
|
||||||
|
for ttask in ttasks {
|
||||||
|
if counter % 2 == 1 {
|
||||||
|
// Only every second task is needed, the first one is the
|
||||||
|
// task before the change, and the second one after
|
||||||
|
// the change. The (maybe modified) second one is
|
||||||
|
// expected by taskwarrior.
|
||||||
|
println!("{}", match serde_json::ser::to_string(&ttask) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
match ttask.status() {
|
||||||
|
&task_hookrs::status::TaskStatus::Deleted => {
|
||||||
|
match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Deleted task {}", *ttask.uuid());
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
trace_error(&e);
|
||||||
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
}
|
||||||
|
} // end match ttask.status()
|
||||||
|
} // end if c % 2
|
||||||
|
counter += 1;
|
||||||
|
} // end for
|
||||||
|
} // end if let
|
||||||
|
else {
|
||||||
|
error!("No usable input");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Should not be possible, as one argument is required via
|
// Should not be possible, as one argument is required via
|
||||||
// ArgGroup
|
// ArgGroup
|
||||||
panic!("Reached unreachable Code");
|
unreachable!();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some("exec") => {
|
Some("exec") => {
|
||||||
|
@ -70,7 +145,7 @@ fn main() {
|
||||||
for e in exec_string {
|
for e in exec_string {
|
||||||
args.push(e);
|
args.push(e);
|
||||||
}
|
}
|
||||||
let mut tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
|
let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
|
||||||
panic!("failed to execute taskwarrior: {}", e);
|
panic!("failed to execute taskwarrior: {}", e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -84,9 +159,67 @@ fn main() {
|
||||||
} else {
|
} else {
|
||||||
panic!("faild to execute: You need to exec --command");
|
panic!("faild to execute: You need to exec --command");
|
||||||
}
|
}
|
||||||
},
|
|
||||||
_ => panic!("Reached unreachable Code"),
|
|
||||||
}
|
}
|
||||||
|
Some("list") => {
|
||||||
}
|
let subcmd = rt.cli().subcommand_matches("list").unwrap();
|
||||||
|
let mut args = Vec::new();
|
||||||
|
let verbose = subcmd.is_present("verbose");
|
||||||
|
let iter = match libimagtodo::read::get_todo_iterator(rt.store()) {
|
||||||
|
//let iter = match rt.store().retrieve_for_module("todo/taskwarrior") {
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ok(val) => val,
|
||||||
|
};
|
||||||
|
for task in iter {
|
||||||
|
match task {
|
||||||
|
Ok(val) => {
|
||||||
|
//let val = libimagtodo::task::Task::new(fle);
|
||||||
|
//println!("{:#?}", val.flentry);
|
||||||
|
let uuid = match val.flentry.get_header().read("todo.uuid") {
|
||||||
|
Ok(Some(u)) => u,
|
||||||
|
Ok(None) => continue,
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if verbose {
|
||||||
|
args.clear();
|
||||||
|
args.push(format!("uuid:{}", uuid));
|
||||||
|
args.push(format!("{}", "information"));
|
||||||
|
let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn()
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
error!("{}", e);
|
||||||
|
panic!("failed");
|
||||||
|
});
|
||||||
|
let output = tw_process.wait_with_output().unwrap_or_else(|e| {
|
||||||
|
panic!("failed to unwrap output: {}", e);
|
||||||
|
});
|
||||||
|
let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
|
||||||
|
panic!("failed to ececute: {}", e);
|
||||||
|
});
|
||||||
|
println!("{}", outstring);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("{}", match uuid {
|
||||||
|
toml::Value::String(s) => s,
|
||||||
|
_ => {
|
||||||
|
error!("Unexpected type for todo.uuid: {}", uuid);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} // end match task
|
||||||
|
} // end for
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
} // end match scmd
|
||||||
|
} // end main
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Args written in the string will be send directly to taskwarrior"))
|
.help("Args written in the string will be send directly to taskwarrior")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("add")
|
.subcommand(SubCommand::with_name("add")
|
||||||
|
@ -83,4 +83,17 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||||
.help("Frequency of the recurrence of a task")
|
.help("Frequency of the recurrence of a task")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.subcommand(SubCommand::with_name("list")
|
||||||
|
.about("List all tasks")
|
||||||
|
.version("0.1")
|
||||||
|
|
||||||
|
.arg(Arg::with_name("verbose")
|
||||||
|
.long("verbose")
|
||||||
|
.short("v")
|
||||||
|
.takes_value(false)
|
||||||
|
.required(false)
|
||||||
|
.help("Asks taskwarrior for all the details")
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ authors = ["mario <mario-krehl@gmx.de>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
semver = "0.2"
|
semver = "0.2"
|
||||||
task-hookrs = { git = "https://github.com/matthiasbeyer/task-hookrs.git" }
|
task-hookrs = { git = "https://github.com/mario-kr/task-hookrs.git" }
|
||||||
uuid = "0.2.0"
|
uuid = "0.2.0"
|
||||||
toml = "0.1.28"
|
toml = "0.1.28"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use module_path::ModuleEntryPath;
|
||||||
use error::{TodoError, TodoErrorKind};
|
use error::{TodoError, TodoErrorKind};
|
||||||
|
|
||||||
/// With the uuid we get the storeid and then we can delete the entry
|
/// With the uuid we get the storeid and then we can delete the entry
|
||||||
pub fn deleteFunc(uuid: Uuid, store : &Store) -> Result<(),TodoError> {
|
pub fn delete(store : &Store, uuid: Uuid) -> Result<(),TodoError> {
|
||||||
// With the uuid we get the storeid
|
// With the uuid we get the storeid
|
||||||
let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();
|
let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();
|
||||||
// It deletes an entry
|
// It deletes an entry
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::fmt::Error as FmtError;
|
use std::fmt::Error as FmtError;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
/// Enum of Error Types, as of now we have two:
|
/// Enum of Error Types, as of now we have two:
|
||||||
/// * ConversionError: for Errors concerning conversion failures from task_hookrs::task::Task to
|
/// * ConversionError: for Errors concerning conversion failures from task_hookrs::task::Task to
|
||||||
|
|
|
@ -2,21 +2,14 @@ extern crate semver;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
||||||
extern crate task_hookrs;
|
|
||||||
#[macro_use] extern crate libimagstore;
|
#[macro_use] extern crate libimagstore;
|
||||||
|
extern crate task_hookrs;
|
||||||
|
|
||||||
module_entry_path_mod!("todo", "0.1.0");
|
module_entry_path_mod!("todo", "0.1.0");
|
||||||
|
|
||||||
pub mod error;
|
|
||||||
pub mod task;
|
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
|
pub mod error;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub mod set;
|
pub mod result;
|
||||||
pub mod add;
|
pub mod task;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
|
|
||||||
use libimagstore::storeid::{StoreIdIterator, StoreId};
|
use libimagstore::storeid::{StoreIdIterator, StoreId};
|
||||||
use libimagstore::store::Store;
|
use libimagstore::store::Store;
|
||||||
use error::{TodoError, TodoErrorKind};
|
use error::{TodoError, TodoErrorKind};
|
||||||
use task::Task;
|
use task::Task;
|
||||||
|
use result::Result;
|
||||||
|
|
||||||
use std::result::Result as RResult;
|
pub fn get_todo_iterator(store: &Store) -> Result<TaskIterator> {
|
||||||
|
|
||||||
pub type Result<T> = RResult<T, TodoError>;
|
store.retrieve_for_module("todo/taskwarrior")
|
||||||
|
|
||||||
|
|
||||||
pub fn all_todos(store: &Store) -> Result<TaskIterator> {
|
|
||||||
|
|
||||||
store.retrieve_for_module("uuid")
|
|
||||||
.map(|iter| TaskIterator::new(store, iter))
|
.map(|iter| TaskIterator::new(store, iter))
|
||||||
.map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
.map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
||||||
}
|
}
|
||||||
|
|
5
libimagtodo/src/result.rs
Normal file
5
libimagtodo/src/result.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use error::TodoError;
|
||||||
|
|
||||||
|
use std::result::Result as RResult;
|
||||||
|
|
||||||
|
pub type Result<T> = RResult<T, TodoError>;
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ops::Deref;
|
use std::collections::BTreeMap;
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
|
|
||||||
use task_hookrs::task::Task as TTask;
|
use task_hookrs::task::Task as TTask;
|
||||||
|
@ -8,11 +8,12 @@ use libimagstore::storeid::IntoStoreId;
|
||||||
use module_path::ModuleEntryPath;
|
use module_path::ModuleEntryPath;
|
||||||
|
|
||||||
use error::{TodoError, TodoErrorKind};
|
use error::{TodoError, TodoErrorKind};
|
||||||
|
use result::Result;
|
||||||
|
|
||||||
/// Task struct containing a `FileLockEntry`
|
/// Task struct containing a `FileLockEntry`
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Task<'a> {
|
pub struct Task<'a> {
|
||||||
flentry : FileLockEntry<'a>,
|
pub flentry : FileLockEntry<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Task<'a> {
|
impl<'a> Task<'a> {
|
||||||
|
@ -42,20 +43,43 @@ pub trait IntoTask<'a> {
|
||||||
/// println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
|
/// println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
fn into_filelockentry(self, store : &'a Store) -> Result<Task<'a>, TodoError>;
|
fn into_filelockentry(self, store : &'a Store) -> Result<Task<'a>>;
|
||||||
}
|
}
|
||||||
impl<'a> IntoTask<'a> for TTask {
|
impl<'a> IntoTask<'a> for TTask {
|
||||||
fn into_filelockentry(self, store : &'a Store) -> Result<Task<'a>, TodoError> {
|
fn into_filelockentry(self, store : &'a Store) -> Result<Task<'a>> {
|
||||||
let uuid = self.uuid();
|
let uuid = self.uuid();
|
||||||
let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();
|
let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();
|
||||||
match store.retrieve(store_id) {
|
match store.retrieve(store_id) {
|
||||||
Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
|
Err(e) => {
|
||||||
Ok(mut fle) => {
|
return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
||||||
match fle.get_header_mut().set("todo.uuid", Value::String(format!("{}", uuid))) {
|
|
||||||
Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
|
|
||||||
Ok(_) => Ok(Task { flentry : fle })
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
Ok(mut fle) => {
|
||||||
|
{
|
||||||
|
let mut header = fle.get_header_mut();
|
||||||
|
match header.read("todo") {
|
||||||
|
Ok(None) => {
|
||||||
|
match header.set("todo", Value::Table(BTreeMap::new())) {
|
||||||
|
Ok(_) => { },
|
||||||
|
Err(e) => {
|
||||||
|
return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Some(_)) => { }
|
||||||
|
Err(e) => {
|
||||||
|
return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match header.set("todo.uuid", Value::String(format!("{}",uuid))) {
|
||||||
|
Ok(_) => { },
|
||||||
|
Err(e) => {
|
||||||
|
return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If none of the errors above have returned the function, everything is fine
|
||||||
|
Ok(Task { flentry : fle } )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue