commit
e6b355196e
11 changed files with 109 additions and 215 deletions
|
@ -59,7 +59,7 @@ use ui::build_ui;
|
|||
|
||||
fn main() {
|
||||
let version = make_imag_version!();
|
||||
let rt = generate_runtime_setup("imag-store",
|
||||
let rt = generate_runtime_setup("imag-tag",
|
||||
&version,
|
||||
"Direct interface to the store. Use with great care!",
|
||||
build_ui);
|
||||
|
|
|
@ -58,7 +58,7 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock
|
|||
|
||||
let create = rt.cli().subcommand_matches("create").unwrap();
|
||||
|
||||
let create_timed = create.value_of("timed")
|
||||
create.value_of("timed")
|
||||
.map(|t| parse_timed_string(t, diaryname).map_err_trace_exit_unwrap(1))
|
||||
.map(Some)
|
||||
.unwrap_or_else(|| {
|
||||
|
@ -70,24 +70,20 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock
|
|||
None
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let entry = match create_timed {
|
||||
Some(timed) => {
|
||||
})
|
||||
.map(|timed| {
|
||||
let id = create_id_from_clispec(&create, &diaryname, timed);
|
||||
diary.retrieve(id).chain_err(|| DEK::StoreReadError)
|
||||
},
|
||||
|
||||
None => {
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
debug!("Creating non-timed entry");
|
||||
diary.new_entry_today(diaryname)
|
||||
}
|
||||
};
|
||||
|
||||
let e = entry.map_err_trace_exit_unwrap(1);
|
||||
|
||||
debug!("Created: {}", e.get_location());
|
||||
e
|
||||
})
|
||||
.map(|e| {
|
||||
debug!("Created: {}", e.get_location());
|
||||
e
|
||||
})
|
||||
.map_err_trace_exit_unwrap(1)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -124,6 +124,12 @@ fn create(rt: &Runtime) {
|
|||
},
|
||||
};
|
||||
|
||||
debug!("Building habit: name = {name}, basedate = {date}, recurr = {recu}, comment = {comm}",
|
||||
name = name,
|
||||
date = date,
|
||||
recu = recu,
|
||||
comm = comm);
|
||||
|
||||
let hb = HabitBuilder::default()
|
||||
.with_name(name)
|
||||
.with_basedate(parsedate(date, "date"))
|
||||
|
@ -136,6 +142,8 @@ fn create(rt: &Runtime) {
|
|||
hb
|
||||
};
|
||||
|
||||
debug!("Builder = {:?}", hb);
|
||||
|
||||
hb.build(rt.store()).map_err_trace_exit_unwrap(1);
|
||||
}
|
||||
|
||||
|
|
29
bin/domain/imag-timetrack/etc/timew-import.sh
Normal file
29
bin/domain/imag-timetrack/etc/timew-import.sh
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# timewarrior import script
|
||||
#
|
||||
# pipe `timew export` to this script for importing timew data into imag.
|
||||
#
|
||||
# Requirements for running this script:
|
||||
# - imag
|
||||
# - imag-timetrack
|
||||
# - sed
|
||||
# - jq
|
||||
#
|
||||
|
||||
# This might be hacky, but it works.
|
||||
|
||||
fixtimeformat() {
|
||||
sed -E 's/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z/\1-\2-\3T\4:\5:\6/'
|
||||
}
|
||||
|
||||
tail -n +2 | head -n -2 | while read line; do
|
||||
json=$(echo "$line" | sed 's/,$//')
|
||||
start=$(echo "$json" | jq '.start' | fixtimeformat | sed 's/"//g' )
|
||||
end=$(echo "$json" | jq '.end' | fixtimeformat | sed 's/"//g' )
|
||||
tags=$(echo "$json" | jq '.tags' | grep "\"" | sed 's/,//; s/"//g')
|
||||
|
||||
echo imag timetrack track "$start" "$end" $tags
|
||||
imag timetrack track "$start" "$end" $tags
|
||||
done
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
## libimagcontacts
|
||||
|
||||
The contact library basically only creates references to the actual icalendar
|
||||
and vcard files, though it also can parse (via the `vobject` crate) the
|
||||
The contact library basically only creates references to the actual
|
||||
vcard files, though it also can parse (via the `vobject` crate) the
|
||||
information and return it from an entry directly.
|
||||
|
||||
The architecture of indirections is as follows:
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
# Roadmap
|
||||
|
||||
This chapter contains the Roadmap to imag 1.0. This is, of course, a _really_
|
||||
long roadmap and should considered to be approximate.
|
||||
|
||||
Things done will be moved to the @sec:changelog.
|
||||
|
||||
## Modules
|
||||
|
||||
These modules are planned right now. Each release should contain 3 new modules
|
||||
maximum.
|
||||
|
||||
- [ ] imag-bibliography - For handling bibliographic references when writing
|
||||
scientific papers. Like Citavi, for example.
|
||||
- [ ] imag-borrow - If you lend something to someone.
|
||||
- [ ] imag-cuecards - Cuecards for learning things, for example vocabulary.
|
||||
- [ ] imag-filter - command to read the store from stdin, filter out entries
|
||||
based on a predicate specified via the CLI and write the store back todo
|
||||
stdout.
|
||||
- [ ] imag-image - Image referencing, categorizing, etc.
|
||||
- [ ] imag-item - Creating entries for Items in the store
|
||||
- [ ] imag-ledger - Ledger functionality like beancountcand others
|
||||
- [ ] imag-list - Managing lists
|
||||
- [ ] imag-movie - Managing movies
|
||||
- [ ] imag-music - Managing music, Possibly a scrobble server.
|
||||
- [ ] imag-news - A RSS Reader
|
||||
- [ ] imag-project - A project planner, integrated with imag-timetrack and
|
||||
imag-todo
|
||||
- [ ] imag-read - Command to load the store and pipe it to stdout (usefull for
|
||||
piping/ chaining commands)
|
||||
- [ ] imag-receipt - Creating, categorizing, managing receipts
|
||||
- [ ] imag-shoppinglists - Managing shopping lists
|
||||
- [ ] imag-summary - Meta-command to call a set of imag commands (configurable
|
||||
which) and displaying their outputs.
|
||||
- [ ] imag-url - Extracting URLs from enties, saving URLs to the imag store
|
||||
- [ ] imag-weather - Weather tooling for getting forecast and recording a
|
||||
history of weather
|
||||
- [ ] imag-fitness - A fitness tracker
|
||||
- [ ] imag-fitness-workout - Tools for tracking workouts.
|
||||
- [ ] imag-fitness-weight - Weight tracker
|
||||
- [ ] imag-fitness-step-counter - Step counting tool
|
||||
- [ ] imag-write - Command to read the store from stdin and write it to the
|
||||
filesystem store (usefull for piping/chaining commands)
|
||||
|
||||
## Other Todos
|
||||
|
||||
* [ ] TUI frontend
|
||||
* [ ] TUI for 'imag'
|
||||
* [ ] TUI for 'imag-annotate'
|
||||
* [ ] TUI for 'imag-diagnostics'
|
||||
* [ ] TUI for 'imag-gps'
|
||||
* [ ] TUI for 'imag-grep'
|
||||
* [ ] TUI for 'imag-link'
|
||||
* [ ] TUI for 'imag-mv'
|
||||
* [ ] TUI for 'imag-ref'
|
||||
* [ ] TUI for 'imag-store'
|
||||
* [ ] TUI for 'imag-tag'
|
||||
* [ ] TUI for 'imag-view'
|
||||
* [ ] TUI for 'imag-bookmark'
|
||||
* [ ] TUI for 'imag-contact'
|
||||
* [ ] TUI for 'imag-counter'
|
||||
* [ ] TUI for 'imag-diary'
|
||||
* [ ] TUI for 'imag-habit'
|
||||
* [ ] TUI for 'imag-mail'
|
||||
* [ ] TUI for 'imag-notes'
|
||||
* [ ] TUI for 'imag-timetrack'
|
||||
* [ ] TUI for 'imag-todo'
|
||||
* [ ] TUI for ...
|
||||
* [ ] Find a way to include the CLI interfaces from core modules into domain
|
||||
modules. This is an experiment and we are not sure whether we want such a thing.
|
||||
Example:
|
||||
* `imag-link` -> `imag diary create and-link --to foo`
|
||||
* `imag-ref` -> `imag diary create and-ref --to /home/user/file.txt`
|
||||
* `imag-tag` -> `imag contact add and-view`
|
||||
* `imag-annotate` -> `imag contact add and-annotate and-ref --to /file and-link --to contacts/alice`
|
||||
|
||||
## 0.6.0
|
||||
|
||||
- [ ] imag-wiki - A wiki for personal use
|
||||
- [ ] imag-init - A command to initialize a imag directory
|
||||
- [ ] imag-git - wrapper to call git commands on the imag store no matter
|
||||
whether the current working directory is the store or not
|
||||
|
||||
## 0.7.0
|
||||
|
||||
- [ ] imag-rate - Attaching a rating to an entry
|
||||
- [ ] Move away from github
|
||||
- [ ] Have own issue tracking (possibly git-dit)
|
||||
- [ ] Find a solution to having no travis-ci via github anymore
|
||||
- [ ] Setup a viewer for the mailinglist archive
|
||||
- [ ] Add maintainer scripts to repository
|
||||
- [ ] To check patches for Signed-off-by lines
|
||||
- [ ] To automatically craft a reply to a contributor about a missing
|
||||
signed-off-by line
|
||||
- [ ] To automatically craft a reply to a contributor about a patchset that
|
||||
cannot be applied
|
||||
- [ ] To check pull requests for GPG signatures
|
||||
- [ ] To apply a patchset in a new branch
|
||||
|
||||
## 0.8.0
|
||||
|
||||
* ...
|
||||
|
||||
## 0.9.0
|
||||
|
||||
* ...
|
||||
|
||||
## 0.10.0
|
||||
|
||||
* ...
|
||||
|
|
@ -22,8 +22,43 @@ This section contains the changelog from the last release to the next release.
|
|||
* `imag-timetrack list --from/--to` now have `kairos` support - that means
|
||||
that complex `--from/--to` arguments (like `yesterday` or `today-2weeks`)
|
||||
are now possible
|
||||
* `libimagerror` got a major refactoring and uses `ChainedError` from
|
||||
`error-chain` for logging errors now.
|
||||
* `libimagentryref` and all libraries using it were rewritten.
|
||||
`libimagentryref` was rewritten to make its API simpler and yet more powerful.
|
||||
Also because it used to put entries under a "ref" collection in the store,
|
||||
but users of the library really should be be able to put entries under
|
||||
custom collections.
|
||||
* Minor changes
|
||||
* A license-checker was included into the CI setup, which checks whether all
|
||||
".rs"-files have the license header at the top of the file
|
||||
* `imag-link` does not allow linking the entry to itself
|
||||
* `imag` sorts available commands alphabetically now
|
||||
* `imag` has a new subcommand `help` for consistency with other tools
|
||||
* `imag-grep` does not print grep statistics when only files with matches
|
||||
are listed
|
||||
* The `"Ok"` output which was printed on success was removed from all
|
||||
commands
|
||||
* `imag-log show` was aliased to `imag-log list`
|
||||
* `imag-* --version` shows `git describe` output if binary was compiled in
|
||||
"debug" mode.
|
||||
* Bugfixes
|
||||
* imag does not panic anymore when piping and breaking that pipe, for
|
||||
example like with `imag store ids | head -n 1`.
|
||||
For that, `libimagerror` got a `Result` extension which can translate
|
||||
errors into exit codes and one for unwrapping or exiting with the
|
||||
`Err(i32)` from the result.
|
||||
|
||||
|
||||
## 0.6.1
|
||||
|
||||
Bugfix release for fixing two severe bugs in `imag-init`:
|
||||
|
||||
* `imag-init` created the git directory inside the imag directory. Fixed by
|
||||
defaulting to `{imag directory}/.git`.
|
||||
* `imag-init` was buggy as it did not include the `imagrc.toml` file in the
|
||||
release, thus building it from crates.io failed
|
||||
|
||||
|
||||
## 0.6.0
|
||||
|
||||
|
|
22
imagrc.toml
22
imagrc.toml
|
@ -89,6 +89,11 @@ error = "[imag][{{red level}}]: {{red message}}"
|
|||
# not be wanted behaviour.
|
||||
#
|
||||
|
||||
[imag.logging.modules.libimagnotification]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagutil]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
|
@ -124,11 +129,21 @@ destinations = []
|
|||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimaghabit]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagnotes]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagcontact]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagdiary]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
|
@ -139,6 +154,11 @@ destinations = []
|
|||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimaglog]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagtodo]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
|
@ -204,7 +224,7 @@ destinations = []
|
|||
level = "debug"
|
||||
enabled = true
|
||||
|
||||
[imag.logging.modules.libimagentrydatetime]
|
||||
[imag.logging.modules.libimagentryutil]
|
||||
destinations = []
|
||||
level = "debug"
|
||||
enabled = true
|
||||
|
|
|
@ -19,51 +19,6 @@
|
|||
|
||||
use error_chain::ChainedError;
|
||||
|
||||
/// An iterator that maps `f` over the `ChainedError` elements of `iter`, similar to
|
||||
/// `std::iter::Map`.
|
||||
///
|
||||
/// This `struct` is created by the `on_err()` method on `TraceIterator`. See its
|
||||
/// documentation for more information.
|
||||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
|
||||
#[derive(Clone)]
|
||||
pub struct OnErr<I, F>{
|
||||
iter: I,
|
||||
f: F
|
||||
}
|
||||
|
||||
impl<I, F, T, E> Iterator for OnErr<I, F> where
|
||||
I: Iterator<Item = Result<T, E>>,
|
||||
F: FnMut(&E)
|
||||
{
|
||||
type Item = Result<T, E>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map(|r| r.map_err(|e| { (self.f)(&e); e }))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, F> ExactSizeIterator for OnErr<I, F> where
|
||||
I: ExactSizeIterator,
|
||||
OnErr<I, F>: Iterator
|
||||
{
|
||||
}
|
||||
|
||||
impl<I, F, T, E> DoubleEndedIterator for OnErr<I, F> where
|
||||
I: DoubleEndedIterator<Item = Result<T, E>>,
|
||||
F: FnMut(&E)
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next_back().map(|r| r.map_err(|e| { (self.f)(&e); e }))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that unwraps the `Ok` items of `iter`, while passing the `Err` items to its
|
||||
/// closure `f`.
|
||||
///
|
||||
|
@ -178,17 +133,6 @@ pub trait TraceIterator<T, E> : Iterator<Item = Result<T, E>> + Sized {
|
|||
UnwrapExit(self, exitcode)
|
||||
}
|
||||
|
||||
/// Takes a closure and creates an iterator that will call that closure for each `Err` element.
|
||||
/// The resulting iterator will yield the exact same items as the original iterator. A close
|
||||
/// analogue from the standard library would be `Iterator::inspect`.
|
||||
///
|
||||
/// As with all iterators, the processing is lazy. The result of this method must be evaluated
|
||||
/// for the closure to be called.
|
||||
#[inline]
|
||||
fn on_err<F>(self, f: F) -> OnErr<Self, F> where F: FnMut(&E) {
|
||||
OnErr { iter: self, f: f }
|
||||
}
|
||||
|
||||
/// Takes a closure and creates an iterator that will yield the items inside all `Ok` items
|
||||
/// yielded by the original iterator. All `Err` items will be filtered out, and the contents
|
||||
/// of each `Err` will be passed to the closure.
|
||||
|
@ -243,32 +187,4 @@ mod test {
|
|||
assert_eq!(&errs, &[TestError(4), TestError(2)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_on_err() {
|
||||
let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))];
|
||||
let mut errs = vec![];
|
||||
|
||||
let result = original
|
||||
.into_iter()
|
||||
.on_err(|e|errs.push(e.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(&result, &[Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))]);
|
||||
assert_eq!(&errs, &[TestError(2), TestError(4)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_on_err_backward() {
|
||||
let original = vec![Ok(1), Err(TestError(2)), Ok(3), Err(TestError(4))];
|
||||
let mut errs = vec![];
|
||||
|
||||
let result = original
|
||||
.into_iter()
|
||||
.rev()
|
||||
.on_err(|e|errs.push(e.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(&result, &[Err(TestError(4)), Ok(3), Err(TestError(2)), Ok(1)]);
|
||||
assert_eq!(&errs, &[TestError(4), TestError(2)]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ pub mod builder {
|
|||
use libimagutil::date::date_to_string;
|
||||
use habit::IsHabitTemplate;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HabitBuilder {
|
||||
name: Option<String>,
|
||||
comment: Option<String>,
|
||||
|
|
|
@ -18,7 +18,7 @@ check() {
|
|||
}
|
||||
}
|
||||
|
||||
find -name "*.rs" -type f | while read filename; do
|
||||
find lib bin -name "*.rs" -type f | grep -v target | while read filename; do
|
||||
check "$filename" 2 \
|
||||
"imag - the personal information management suite for the commandline" \
|
||||
"Description line" \
|
||||
|
|
Loading…
Reference in a new issue