From 7bdaaf35fcdfe15fffb80e7faee1aa49f8f8c1b2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 28 Jul 2016 16:05:19 +0200 Subject: [PATCH 1/4] Initial import --- Cargo.toml | 1 + default.nix | 2 + lib/etc/libimagnotification/Cargo.toml | 20 ++ lib/etc/libimagnotification/src/lib.rs | 28 +++ .../libimagnotification/src/notificator.rs | 117 ++++++++++ .../src/result_notification.rs | 199 ++++++++++++++++++ 6 files changed, 367 insertions(+) create mode 100644 lib/etc/libimagnotification/Cargo.toml create mode 100644 lib/etc/libimagnotification/src/lib.rs create mode 100644 lib/etc/libimagnotification/src/notificator.rs create mode 100644 lib/etc/libimagnotification/src/result_notification.rs diff --git a/Cargo.toml b/Cargo.toml index c8a2b9f1..62b680d1 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 bbc0e812..68429750 100644 --- a/default.nix +++ b/default.nix @@ -15,6 +15,8 @@ let pkgconfig which zlib + dbus + pkgconfig ]; in diff --git a/lib/etc/libimagnotification/Cargo.toml b/lib/etc/libimagnotification/Cargo.toml new file mode 100644 index 00000000..510ffda0 --- /dev/null +++ b/lib/etc/libimagnotification/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "libimagnotification" +version = "0.4.0" +authors = ["Matthias Beyer "] + +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" + +libimagerror = { version = "0.5.0", path = "../../../lib/core/libimagerror" } + diff --git a/lib/etc/libimagnotification/src/lib.rs b/lib/etc/libimagnotification/src/lib.rs new file mode 100644 index 00000000..7ecb963c --- /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 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 libimagerror; + +pub mod error; +pub mod notificator; +pub mod result; +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 00000000..b10b8a1b --- /dev/null +++ b/lib/etc/libimagnotification/src/notificator.rs @@ -0,0 +1,117 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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 result::Result; + +/// 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 { + fn notify(&self, item: &T) -> Result<()>; +} + +pub mod default { + use std::fmt::Debug; + use std::fmt::Display; + + use result::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 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 Notificator 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 for DebugNotification { + fn from(n: Notification) -> DebugNotification { + DebugNotification(n) + } + } + + impl Notificator 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 00000000..ca540de5 --- /dev/null +++ b/lib/etc/libimagnotification/src/result_notification.rs @@ -0,0 +1,199 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer 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::NotificationErrorKind as NEK; + use error::MapErrInto; + use notificator::default::Urgency; + use notificator::default::Notification; + use notificator::Notificator; + use result::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 Notificator 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(|_| ()).map_err_into(NEK::NotificationError)); + + 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 error::MapErrInto; + use error::NotificationErrorKind as NEK; + use notificator::default::Notification; + use notificator::Notificator; + use result::Result; + + #[derive(Debug, Default, Clone)] + pub struct OkNotification(Notification); + + impl From for OkNotification { + + fn from(n: Notification) -> OkNotification { + OkNotification(n) + } + + } + + impl Notificator 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(|_| ()).map_err_into(NEK::NotificationError) + } + + } + + 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 { + + /// Notify with a custom Notificator, only notify on Ok(T) + fn notify_with(self, n: &Notificator) -> 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) -> Self; + + /// Notify with the ErrorNotification::default(), only notify on Err(E) + fn notify_on_err(self) -> Self; + +} + +impl ResultNotification for Result { + + fn notify_with(self, n: &Notificator) -> 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) -> Self { + self.map_err(|e| { let _ = n.notify(&e); e }) + } + + fn notify_on_err(self) -> Self { + self.notify_on_err_with(&ErrorNotification::default()) + } + +} + From f0ae62868799bb5b4ed0acce572823716cb335ce Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 22 Dec 2017 13:55:05 +0100 Subject: [PATCH 2/4] Transform to use error-chain --- lib/etc/libimagnotification/Cargo.toml | 1 + lib/etc/libimagnotification/src/error.rs | 36 +++++++++++++++++++ lib/etc/libimagnotification/src/lib.rs | 2 +- .../libimagnotification/src/notificator.rs | 5 +-- .../src/result_notification.rs | 15 ++++---- 5 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 lib/etc/libimagnotification/src/error.rs diff --git a/lib/etc/libimagnotification/Cargo.toml b/lib/etc/libimagnotification/Cargo.toml index 510ffda0..88cd3852 100644 --- a/lib/etc/libimagnotification/Cargo.toml +++ b/lib/etc/libimagnotification/Cargo.toml @@ -15,6 +15,7 @@ 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 00000000..535a7c89 --- /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 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 index 7ecb963c..6e1f27f1 100644 --- a/lib/etc/libimagnotification/src/lib.rs +++ b/lib/etc/libimagnotification/src/lib.rs @@ -18,11 +18,11 @@ // extern crate notify_rust; +#[macro_use] extern crate error_chain; #[macro_use] extern crate libimagerror; pub mod error; pub mod notificator; -pub mod result; pub mod result_notification; diff --git a/lib/etc/libimagnotification/src/notificator.rs b/lib/etc/libimagnotification/src/notificator.rs index b10b8a1b..5772ff0d 100644 --- a/lib/etc/libimagnotification/src/notificator.rs +++ b/lib/etc/libimagnotification/src/notificator.rs @@ -17,7 +17,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // -use result::Result; +use error::Result; +use error::ResultExt; /// A Notificator provides a function that can be called to notify about a certain object. /// @@ -34,7 +35,7 @@ pub mod default { use std::fmt::Debug; use std::fmt::Display; - use result::Result; + use error::Result; use notify_rust::Notification as RustNotification; use notify_rust::NotificationUrgency; diff --git a/lib/etc/libimagnotification/src/result_notification.rs b/lib/etc/libimagnotification/src/result_notification.rs index ca540de5..b458f767 100644 --- a/lib/etc/libimagnotification/src/result_notification.rs +++ b/lib/etc/libimagnotification/src/result_notification.rs @@ -31,12 +31,12 @@ pub mod err { use notify_rust::Notification as RustNotification; use notify_rust::NotificationUrgency; + use error::ResultExt; use error::NotificationErrorKind as NEK; - use error::MapErrInto; use notificator::default::Urgency; use notificator::default::Notification; use notificator::Notificator; - use result::Result; + use error::Result; #[derive(Debug, Default, Clone)] pub struct ErrorNotification(Notification, usize); @@ -64,7 +64,7 @@ pub mod err { n.summary("[Error]"); n.urgency(urgency.clone()); n.body(e.description()); - try!(n.finalize().show().map(|_| ()).map_err_into(NEK::NotificationError)); + try!(n.finalize().show().map(|_| ()).chain_err(|| NEK::Unknown)); if u > 0 { e.cause().map(|cause| trace_notify(urgency, cause, u - 1)); @@ -103,11 +103,11 @@ pub mod ok { use notify_rust::Notification as RustNotification; - use error::MapErrInto; - use error::NotificationErrorKind as NEK; use notificator::default::Notification; use notificator::Notificator; - use result::Result; + use error::NotificationErrorKind as NEK; + use error::Result; + use error::ResultExt; #[derive(Debug, Default, Clone)] pub struct OkNotification(Notification); @@ -129,7 +129,8 @@ pub mod ok { n.summary("[Ok]"); n.urgency(self.0.urgency.clone().into()); n.body(&"< >".to_owned()); - n.finalize().show().map(|_| ()).map_err_into(NEK::NotificationError) + n.finalize().show().map(|_| ())?; + Ok(()) } } From 420af751fcd0224767de489c92758eb52a928dd9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 22 Dec 2017 15:03:17 +0100 Subject: [PATCH 3/4] Add dbus and pkgconfig dependencies in travis.yml --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8bbd91f4..e77f18f5 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 From 552d963980234cf90aa723133c5a10100aac749e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 23 Dec 2017 12:59:14 +0100 Subject: [PATCH 4/4] Add changelog entry --- doc/src/09020-changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index dfc23e47..8a3ec5d7 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