summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2017-12-23 15:19:16 +0100
committerGitHub <noreply@github.com>2017-12-23 15:19:16 +0100
commit898617ff62bf633d33472f9a9120323ac8806fa1 (patch)
treea30797b59f5e00942953002e3b96114e770b2c91
parent4819061d683b28a5dcf3c369ebe66cd8c72e43e6 (diff)
parent552d963980234cf90aa723133c5a10100aac749e (diff)
downloadimag-898617ff62bf633d33472f9a9120323ac8806fa1.zip
imag-898617ff62bf633d33472f9a9120323ac8806fa1.tar.gz
Merge pull request #593 from matthiasbeyer/libimagnotification/init
Libimagnotification/init
-rw-r--r--.travis.yml6
-rw-r--r--Cargo.toml1
-rw-r--r--default.nix2
-rw-r--r--doc/src/09020-changelog.md2
-rw-r--r--lib/etc/libimagnotification/Cargo.toml21
-rw-r--r--lib/etc/libimagnotification/src/error.rs36
-rw-r--r--lib/etc/libimagnotification/src/lib.rs28
-rw-r--r--lib/etc/libimagnotification/src/notificator.rs118
-rw-r--r--lib/etc/libimagnotification/src/result_notification.rs200
9 files changed, 414 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
index 8bbd91f..e77f18f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,6 +22,12 @@ matrix:
cache:
cargo: true
+addons:
+ apt:
+ packages:
+ - libdbus-1-dev
+ - pkg-config
+
script:
- cargo build --all --all-features --verbose -j 1
- cargo test --all --all-features --verbose -j 1
diff --git a/Cargo.toml b/Cargo.toml
index c8a2b9f..62b680d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,6 +43,7 @@ members = [
"lib/entry/libimagentrytag",
"lib/entry/libimagentryview",
"lib/etc/libimaginteraction",
+ "lib/etc/libimagnotification",
"lib/etc/libimagtimeui",
"lib/etc/libimagutil",
]
diff --git a/default.nix b/default.nix
index bbc0e81..6842975 100644
--- a/default.nix
+++ b/default.nix
@@ -15,6 +15,8 @@ let
pkgconfig
which
zlib
+ dbus
+ pkgconfig
];
in
diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md
index dfc23e4..8a3ec5d 100644
--- a/doc/src/09020-changelog.md
+++ b/doc/src/09020-changelog.md
@@ -44,6 +44,8 @@ This section contains the changelog from the last release to the next release.
any other crate.
* imag now reads the `IMAG_RTP` environment variable before trying to access
`$HOME/.imag` for its runtimepath.
+ * `libimagnotification` was introduced, though not yet integrated into the
+ CLI tools
* Bugfixes
* `Store::entries()` does not yield StoreIds which point to directories
diff --git a/lib/etc/libimagnotification/Cargo.toml b/lib/etc/libimagnotification/Cargo.toml
new file mode 100644
index 0000000..88cd385
--- /dev/null
+++ b/lib/etc/libimagnotification/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "libimagnotification"
+version = "0.4.0"
+authors = ["Matthias Beyer <mail@beyermatthias.de>"]
+
+description = "Library for the imag core distribution"
+
+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"
+
+[dependencies]
+notify-rust = "3.4.2"
+error-chain = "0.11"
+
+libimagerror = { version = "0.5.0", path = "../../../lib/core/libimagerror" }
+
diff --git a/lib/etc/libimagnotification/src/error.rs b/lib/etc/libimagnotification/src/error.rs
new file mode 100644
index 0000000..535a7c8
--- /dev/null
+++ b/lib/etc/libimagnotification/src/error.rs
@@ -0,0 +1,36 @@
+//
+// 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
+//
+
+error_chain! {
+ types {
+ NotificationError, NotificationErrorKind, ResultExt, Result;
+ }
+
+ foreign_links {
+ NotifyError(::notify_rust::error::Error);
+ }
+
+ errors {
+ Unknown {
+ description("Unknown Error")
+ display("Unknown Error")
+ }
+ }
+}
+
diff --git a/lib/etc/libimagnotification/src/lib.rs b/lib/etc/libimagnotification/src/lib.rs
new file mode 100644
index 0000000..6e1f27f
--- /dev/null
+++ b/lib/etc/libimagnotification/src/lib.rs
@@ -0,0 +1,28 @@
+//
+// 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
+//
+
+extern crate notify_rust;
+#[macro_use] extern crate error_chain;
+
+#[macro_use] extern crate libimagerror;
+
+pub mod error;
+pub mod notificator;
+pub mod result_notification;
+
diff --git a/lib/etc/libimagnotification/src/notificator.rs b/lib/etc/libimagnotification/src/notificator.rs
new file mode 100644
index 0000000..5772ff0
--- /dev/null
+++ b/lib/etc/libimagnotification/src/notificator.rs
@@ -0,0 +1,118 @@
+//
+// 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 error::Result;
+use error::ResultExt;
+
+/// A Notificator provides a function that can be called to notify about a certain object.
+///
+/// # TODO
+///
+/// The user of the library does _not_ get access to the notification handle.
+/// This is not optimal, but enough for today.
+///
+pub trait Notificator<T> {
+ fn notify(&self, item: &T) -> Result<()>;
+}
+
+pub mod default {
+ use std::fmt::Debug;
+ use std::fmt::Display;
+
+ use error::Result;
+
+ use notify_rust::Notification as RustNotification;
+ use notify_rust::NotificationUrgency;
+
+ use super::Notificator;
+
+ #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
+ pub enum Urgency {
+ Low,
+ Normal,
+ High
+ }
+
+ impl Default for Urgency {
+ fn default() -> Urgency {
+ Urgency::Normal
+ }
+ }
+
+ impl Into<NotificationUrgency> for Urgency {
+
+ fn into(self) -> NotificationUrgency {
+ match self {
+ Urgency::Low => NotificationUrgency::Low,
+ Urgency::Normal => NotificationUrgency::Normal,
+ Urgency::High => NotificationUrgency::Critical,
+ }
+ }
+
+ }
+
+ #[derive(Debug, Default, Clone)]
+ pub struct Notification {
+ pub timeout: i32,
+ pub message: String,
+ pub summary: String,
+ pub urgency: Urgency,
+ }
+
+ impl<T: Display> Notificator<T> for Notification {
+
+ /// A default implementation for all Types that implement Display
+ fn notify(&self, item: &T) -> Result<()> {
+ let mut n = RustNotification::new();
+ n.appname("imag");
+ n.summary(&self.summary);
+ n.urgency(self.urgency.clone().into());
+ n.body(&format!("{}: {}", &self.message, item));
+ let _ = n.finalize().show(); // Ignoring error here
+ Ok(())
+ }
+
+ }
+
+ #[derive(Debug, Default, Clone)]
+ pub struct DebugNotification(Notification);
+
+ impl From<Notification> for DebugNotification {
+ fn from(n: Notification) -> DebugNotification {
+ DebugNotification(n)
+ }
+ }
+
+ impl<T: Debug> Notificator<T> for DebugNotification {
+
+ /// A default implementation for all Types that implement Display
+ fn notify(&self, item: &T) -> Result<()> {
+ let mut n = RustNotification::new();
+ n.appname("imag");
+ n.summary(&self.0.summary);
+ n.urgency(self.0.urgency.clone().into());
+ n.body(&format!("{}: {:?}", &self.0.message, item));
+ let _ = n.finalize().show(); // Ignoring error here
+ Ok(())
+ }
+
+ }
+
+}
+
diff --git a/lib/etc/libimagnotification/src/result_notification.rs b/lib/etc/libimagnotification/src/result_notification.rs
new file mode 100644
index 0000000..b458f76
--- /dev/null
+++ b/lib/etc/libimagnotification/src/result_notification.rs
@@ -0,0 +1,200 @@
+//
+// 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 std::error::Error;
+
+use notificator::Notificator;
+use self::err::*;
+use self::ok::*;
+
+pub mod err {
+ use std::ops::Deref;
+ use std::ops::DerefMut;
+ use std::error::Error;
+
+ use notify_rust::Notification as RustNotification;
+ use notify_rust::NotificationUrgency;
+
+ use error::ResultExt;
+ use error::NotificationErrorKind as NEK;
+ use notificator::default::Urgency;
+ use notificator::default::Notification;
+ use notificator::Notificator;
+ use error::Result;
+
+ #[derive(Debug, Default, Clone)]
+ pub struct ErrorNotification(Notification, usize);
+
+ impl ErrorNotification {
+ pub fn new(trace: usize, timeout: i32) -> ErrorNotification {
+ let notif = Notification {
+ timeout: timeout,
+ message: String::new(), // Not used in this special case
+ summary: "[Error]".to_owned(),
+ urgency: Urgency::High,
+ };
+
+ ErrorNotification(notif, trace)
+ }
+ }
+
+ impl<T: Error> Notificator<T> for ErrorNotification {
+
+ /// A default implementation for all Types that implement Display
+ fn notify(&self, item: &T) -> Result<()>{
+ fn trace_notify(urgency: NotificationUrgency, e: &Error, u: usize) -> Result<()> {
+ let mut n = RustNotification::new();
+ n.appname("imag");
+ n.summary("[Error]");
+ n.urgency(urgency.clone());
+ n.body(e.description());
+ try!(n.finalize().show().map(|_| ()).chain_err(|| NEK::Unknown));
+
+ if u > 0 {
+ e.cause().map(|cause| trace_notify(urgency, cause, u - 1));
+ }
+
+ Ok(())
+ }
+
+ trace_notify(self.0.urgency.clone().into(), item, self.1)
+ }
+
+ }
+
+ impl Deref for ErrorNotification {
+ type Target = Notification;
+
+ fn deref(&self) -> &Notification {
+ &self.0
+ }
+
+ }
+
+ impl DerefMut for ErrorNotification {
+
+ fn deref_mut(&mut self) -> &mut Notification {
+ &mut self.0
+ }
+
+ }
+
+}
+
+pub mod ok {
+ use std::ops::Deref;
+ use std::ops::DerefMut;
+
+ use notify_rust::Notification as RustNotification;
+
+ use notificator::default::Notification;
+ use notificator::Notificator;
+ use error::NotificationErrorKind as NEK;
+ use error::Result;
+ use error::ResultExt;
+
+ #[derive(Debug, Default, Clone)]
+ pub struct OkNotification(Notification);
+
+ impl From<Notification> for OkNotification {
+
+ fn from(n: Notification) -> OkNotification {
+ OkNotification(n)
+ }
+
+ }
+
+ impl<T> Notificator<T> for OkNotification {
+
+ /// A default implementation for all Types that implement Display
+ fn notify(&self, _: &T) -> Result<()> {
+ let mut n = RustNotification::new();
+ n.appname("imag");
+ n.summary("[Ok]");
+ n.urgency(self.0.urgency.clone().into());
+ n.body(&"< >".to_owned());
+ n.finalize().show().map(|_| ())?;
+ Ok(())
+ }
+
+ }
+
+ impl Deref for OkNotification {
+ type Target = Notification;
+
+ fn deref(&self) -> &Notification {
+ &self.0
+ }
+
+ }
+
+ impl DerefMut for OkNotification {
+
+ fn deref_mut(&mut self) -> &mut Notification {
+ &mut self.0
+ }
+
+ }
+
+}
+
+/// An extension trait for Result types
+///
+/// Can be used to notify on error or on "Ok(_)" values.
+///
+/// # Warning
+///
+/// As the notification could go wrong, but inside a mapping function, the error cannot be given to
+/// someone, we ignore errors in the Notificator::notify() call.
+pub trait ResultNotification<T, E> {
+
+ /// Notify with a custom Notificator, only notify on Ok(T)
+ fn notify_with(self, n: &Notificator<T>) -> Self;
+
+ /// Notify with the OkNotification::default(), only notify on Ok(T)
+ fn notify(self) -> Self;
+
+ /// Notify with a custom Notificator, only notify on Err(E)
+ fn notify_on_err_with(self, n: &Notificator<E>) -> Self;
+
+ /// Notify with the ErrorNotification::default(), only notify on Err(E)
+ fn notify_on_err(self) -> Self;
+
+}
+
+impl<T, E: Error> ResultNotification<T, E> for Result<T, E> {
+
+ fn notify_with(self, n: &Notificator<T>) -> Self {
+ self.map(|item| { let _ = n.notify(&item); item })
+ }
+
+ fn notify(self) -> Self {
+ self.notify_with(&OkNotification::default())
+ }
+
+ fn notify_on_err_with(self, n: &Notificator<E>) -> Self {
+ self.map_err(|e| { let _ = n.notify(&e); e })
+ }
+
+ fn notify_on_err(self) -> Self {
+ self.notify_on_err_with(&ErrorNotification::default())
+ }
+
+}
+