summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-01-04 10:31:00 +0100
committerGitHub <noreply@github.com>2018-01-04 10:31:00 +0100
commitb60b5c89818eda8336459132919b6dc36f87cc34 (patch)
tree544c18cc13decefc3571214667640991b6099aea
parent4ceca39426c0044d45558029430f7ab5b109c87e (diff)
parenta6fd525c0fb0c32dab32aae0efbbbd98b89b6636 (diff)
downloadimag-b60b5c89818eda8336459132919b6dc36f87cc34.zip
imag-b60b5c89818eda8336459132919b6dc36f87cc34.tar.gz
Merge pull request #1184 from matthiasbeyer/imag-log/init
imag-log: init
-rw-r--r--Cargo.toml1
-rw-r--r--bin/domain/imag-log/Cargo.toml33
l---------bin/domain/imag-log/README.md1
-rw-r--r--bin/domain/imag-log/src/main.rs193
-rw-r--r--bin/domain/imag-log/src/ui.rs62
-rw-r--r--doc/src/04020-module-log.md40
-rw-r--r--imagrc.toml4
7 files changed, 334 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 6416893..0a6bcdd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,6 +15,7 @@ members = [
"bin/domain/imag-contact",
"bin/domain/imag-diary",
"bin/domain/imag-habit",
+ "bin/domain/imag-log",
"bin/domain/imag-mail",
"bin/domain/imag-notes",
"bin/domain/imag-timetrack",
diff --git a/bin/domain/imag-log/Cargo.toml b/bin/domain/imag-log/Cargo.toml
new file mode 100644
index 0000000..5c7a89e
--- /dev/null
+++ b/bin/domain/imag-log/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+name = "imag-log"
+version = "0.6.0"
+authors = ["Matthias Beyer <mail@beyermatthias.de>"]
+
+description = "Part of the imag core distribution: imag-bookmark command"
+
+keywords = ["imag", "PIM", "personal", "information", "management"]
+readme = "../../../README.md"
+license = "LGPL-2.1"
+
+documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html"
+repository = "https://github.com/matthiasbeyer/imag"
+homepage = "http://imag-pim.org"
+
+[badges]
+travis-ci = { repository = "matthiasbeyer/imag" }
+is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
+is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
+maintenance = { status = "actively-developed" }
+
+[dependencies]
+clap = ">=2.17"
+log = "0.3"
+version = "2.0.1"
+toml = "0.4"
+toml-query = "^0.4"
+is-match = "0.1"
+
+libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" }
+libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" }
+libimagdiary = { version = "0.6.0", path = "../../../lib/domain/libimagdiary" }
+libimaglog = { version = "0.6.0", path = "../../../lib/domain/libimaglog" }
diff --git a/bin/domain/imag-log/README.md b/bin/domain/imag-log/README.md
new file mode 120000
index 0000000..5c9729e
--- /dev/null
+++ b/bin/domain/imag-log/README.md
@@ -0,0 +1 @@
+../../../doc/src/04020-module-log.md \ No newline at end of file
diff --git a/bin/domain/imag-log/src/main.rs b/bin/domain/imag-log/src/main.rs
new file mode 100644
index 0000000..99f917f
--- /dev/null
+++ b/bin/domain/imag-log/src/main.rs
@@ -0,0 +1,193 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#![deny(
+ non_camel_case_types,
+ non_snake_case,
+ path_statements,
+ trivial_numeric_casts,
+ unstable_features,
+ unused_allocation,
+ unused_import_braces,
+ unused_imports,
+ unused_must_use,
+ unused_mut,
+ unused_qualifications,
+ while_true,
+)]
+
+extern crate clap;
+#[macro_use] extern crate is_match;
+#[macro_use] extern crate log;
+#[macro_use] extern crate version;
+extern crate toml;
+extern crate toml_query;
+
+extern crate libimaglog;
+extern crate libimagrt;
+extern crate libimagerror;
+extern crate libimagdiary;
+
+use libimagrt::runtime::Runtime;
+use libimagrt::setup::generate_runtime_setup;
+use libimagerror::trace::MapErrTrace;
+use libimagdiary::diary::Diary;
+use libimaglog::log::Log;
+use libimaglog::error::LogError as LE;
+
+mod ui;
+use ui::build_ui;
+
+use toml::Value;
+
+fn main() {
+ let rt = generate_runtime_setup("imag-log",
+ &version!()[..],
+ "Overlay to imag-diary to 'log' single lines of text",
+ build_ui);
+
+
+ if let Some(scmd) = rt.cli() .subcommand_name() {
+ match scmd {
+ "show" => show(&rt),
+ _ => {
+ error!("Unknown command");
+ ::std::process::exit(1)
+ },
+ }
+ } else {
+ let text = get_log_text(&rt);
+ let diary_name = rt.cli()
+ .value_of("diaryname")
+ .map(String::from)
+ .unwrap_or_else(|| get_diary_name(&rt));
+
+ debug!("Writing to '{}': {}", diary_name, text);
+
+ let _ = rt
+ .store()
+ .new_entry_now(&diary_name)
+ .map(|mut fle| {
+ let _ = fle.make_log_entry().map_err_trace_exit_unwrap(1);
+ *fle.get_content_mut() = text;
+ })
+ .map_err_trace_exit_unwrap(1);
+ info!("Ok");
+ }
+}
+
+fn show(rt: &Runtime) {
+ use libimagdiary::iter::DiaryEntryIterator;
+ use libimagdiary::entry::DiaryEntry;
+
+ let scmd = rt.cli().subcommand_matches("show").unwrap(); // safed by main()
+ let iters : Vec<DiaryEntryIterator> = match scmd.values_of("show-name") {
+ Some(values) => values
+ .map(|diary_name| Diary::entries(rt.store(), diary_name).map_err_trace_exit_unwrap(1))
+ .collect(),
+
+ None => if scmd.is_present("show-all") {
+ rt.store()
+ .diary_names()
+ .map_err_trace_exit_unwrap(1)
+ .map(|diary_name| {
+ let diary_name = diary_name.map_err_trace_exit_unwrap(1);
+ Diary::entries(rt.store(), &diary_name).map_err_trace_exit_unwrap(1)
+ })
+ .collect()
+ } else {
+ // showing default logs
+ vec![Diary::entries(rt.store(), &get_diary_name(rt)).map_err_trace_exit_unwrap(1)]
+ }
+ };
+
+ for iter in iters {
+ for element in iter {
+ let e = element.map_err_trace_exit_unwrap(1);
+ let id = e.diary_id().map_err_trace_exit_unwrap(1);
+ println!("{dname: >10} - {y: >4}-{m:0>2}-{d:0>2}T{H:0>2}:{M:0>2} - {text}",
+ dname = id.diary_name(),
+ y = id.year(),
+ m = id.month(),
+ d = id.day(),
+ H = id.hour(),
+ M = id.minute(),
+ text = e.get_content());
+ }
+ }
+
+ info!("Ready.");
+}
+
+fn get_diary_name(rt: &Runtime) -> String {
+ use toml_query::read::TomlValueReadExt;
+
+ let cfg = rt
+ .config()
+ .ok_or(LE::from("Configuration not present, cannot continue"))
+ .map_err_trace_exit_unwrap(1);
+
+ let logs = cfg
+ .read("log.logs")
+ .map_err_trace_exit_unwrap(1)
+ .ok_or(LE::from("Configuration missing: 'log.logs'"))
+ .map_err_trace_exit_unwrap(1)
+ .as_array()
+ .ok_or(LE::from("Configuration 'log.logs' is not an Array"))
+ .map_err_trace_exit_unwrap(1);
+
+ if !logs.iter().all(|e| is_match!(e, &Value::String(_))) {
+ error!("Configuration 'log.logs' is not an Array<String>!");
+ ::std::process::exit(1);
+ }
+
+ let logs = logs
+ .into_iter()
+ .map(Value::as_str)
+ .map(Option::unwrap)
+ .collect::<Vec<_>>();
+
+ let current_log = cfg
+ .read("log.default")
+ .map_err_trace_exit_unwrap(1)
+ .ok_or(LE::from("Configuration missing: 'log.default'"))
+ .map_err_trace_exit_unwrap(1)
+ .as_str()
+ .ok_or(LE::from("Configuration 'log.default' is not a String"))
+ .map_err_trace_exit_unwrap(1);
+
+ if !logs.contains(&current_log) {
+ error!("'log.logs' does not contain 'log.default'");
+ ::std::process::exit(1)
+ } else {
+ current_log.into()
+ }
+
+}
+
+fn get_log_text(rt: &Runtime) -> String {
+ rt.cli()
+ .values_of("text")
+ .unwrap() // safe by clap
+ .fold(String::with_capacity(500), |mut acc, e| {
+ acc.push_str(" ");
+ acc.push_str(e);
+ acc
+ })
+}
diff --git a/bin/domain/imag-log/src/ui.rs b/bin/domain/imag-log/src/ui.rs
new file mode 100644
index 0000000..fa7428a
--- /dev/null
+++ b/bin/domain/imag-log/src/ui.rs
@@ -0,0 +1,62 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+use clap::{Arg, App, SubCommand};
+
+pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
+ app
+ .arg(Arg::with_name("diaryname")
+ .long("to")
+ .short("t")
+ .takes_value(true)
+ .required(false)
+ .help("Use other than default diary"))
+
+ .arg(Arg::with_name("text")
+ .index(1)
+ .takes_value(true)
+ .multiple(true)
+ .required(false)
+ .help("Text to log. Multiple will be concatenated")
+ .value_name("TEXT"))
+
+ .subcommand(SubCommand::with_name("show")
+ .about("View log(s)")
+ .version("0.1")
+
+ .arg(Arg::with_name("show-all")
+ .long("all")
+ .short("a")
+ .takes_value(false)
+ .required(false)
+ .conflicts_with("show-name")
+ .help("Show all logs"))
+
+ .arg(Arg::with_name("show-name")
+ .index(1)
+ .takes_value(true)
+ .multiple(true)
+ .required(false)
+ .conflicts_with("show-all")
+ .help("Show logs. Multiple possible (will be sorted by date, still)."))
+
+ )
+
+}
+
diff --git a/doc/src/04020-module-log.md b/doc/src/04020-module-log.md
new file mode 100644
index 0000000..0f213a0
--- /dev/null
+++ b/doc/src/04020-module-log.md
@@ -0,0 +1,40 @@
+## Log {#sec:modules:log}
+
+The "imag-log" module is a lightweight interface to the "imag-diary" command.
+
+It is intended as a tumbeblog-like diary, where one does not care to fire up
+an editor and type in a long text, but rather type a few words and forget
+about it:
+
+### Usage
+
+Logs can be created via an entry in the configuration file in the section `log`:
+
+```
+[log]
+logs = ["work", "hobby", "music"]
+default = "hobby"
+```
+
+The `default` key is required and the name which is used here _must_ appear in
+the `logs` array.
+
+In the above configuration snippet, the logs `work`, `hobby` and `music` are
+created. The user may now log to one of these logs with:
+
+```
+imag log --to <logname> "Some message"
+# or
+imag log -t <logname> "Some message"
+# or, to the default log:
+imag log "Some message"
+```
+
+Logs can be read by naming the log:
+
+```
+imag log show work
+```
+
+which prints one log per line (including time it was logged).
+
diff --git a/imagrc.toml b/imagrc.toml
index 6700607..ac07ca0 100644
--- a/imagrc.toml
+++ b/imagrc.toml
@@ -316,3 +316,7 @@ Email : {{EMAIL}}
Address : {{ADR}}
"""
+[log]
+logs = ["default"]
+default = "default"
+