Desktop notifications for Linux (#353)
* Enable desktop notifications for Linux * Fix macOS * Fix unused variable * Add missing message * Pass a title to notify-send
This commit is contained in:
committed by
GitHub
parent
f9374e3ddf
commit
16efada11b
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1905,6 +1905,7 @@ name = "topgrade"
|
|||||||
version = "4.1.0"
|
version = "4.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
"anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ strum = { version = "0.17.1", features = ["derive"] }
|
|||||||
thiserror = "1.0.9"
|
thiserror = "1.0.9"
|
||||||
anyhow = "1.0.25"
|
anyhow = "1.0.25"
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
cfg-if = "0.1.10"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
notify-rust = "3.6.3"
|
notify-rust = "3.6.3"
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use crate::utils::which;
|
||||||
use chrono::{Local, Timelike};
|
use chrono::{Local, Timelike};
|
||||||
use console::{style, Term};
|
use console::{style, Term};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use log::debug;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use notify_rust::Notification;
|
use notify_rust::{Notification, Timeout};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::time::Duration;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use which_crate::which;
|
use which_crate::which;
|
||||||
|
|
||||||
@@ -35,6 +41,8 @@ struct Terminal {
|
|||||||
term: Term,
|
term: Term,
|
||||||
set_title: bool,
|
set_title: bool,
|
||||||
desktop_notification: bool,
|
desktop_notification: bool,
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
notify_send: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Terminal {
|
impl Terminal {
|
||||||
@@ -48,6 +56,8 @@ impl Terminal {
|
|||||||
.unwrap_or_else(|_| String::new()),
|
.unwrap_or_else(|_| String::new()),
|
||||||
set_title: true,
|
set_title: true,
|
||||||
desktop_notification: false,
|
desktop_notification: false,
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
notify_send: which("notify-send"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,23 +69,43 @@ impl Terminal {
|
|||||||
self.set_title = set_title
|
self.set_title = set_title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn notify_desktop<P: AsRef<str>>(&self, message: P, timeout: Option<Duration>) {
|
||||||
|
debug!("Desktop notification: {}", message.as_ref());
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(target_os = "macos")] {
|
||||||
|
let mut notification = Notification::new();
|
||||||
|
notification.summary("Topgrade")
|
||||||
|
.body(message.as_ref())
|
||||||
|
.appname("topgrade");
|
||||||
|
|
||||||
|
if let Some(timeout) = timeout {
|
||||||
|
notification.timeout(Timeout::Milliseconds(timeout.as_millis() as u32));
|
||||||
|
}
|
||||||
|
notification.show().ok();
|
||||||
|
} else if #[cfg(target_os = "linux")] {
|
||||||
|
if let Some(ns) = self.notify_send.as_ref() {
|
||||||
|
let mut command = Command::new(ns);
|
||||||
|
if let Some(timeout) = timeout {
|
||||||
|
command.arg("-t");
|
||||||
|
command.arg(format!("{}", timeout.as_millis()));
|
||||||
|
command.args(&["-a", "Topgrade"]);
|
||||||
|
command.arg(message.as_ref());
|
||||||
|
}
|
||||||
|
command.output().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn print_separator<P: AsRef<str>>(&mut self, message: P) {
|
fn print_separator<P: AsRef<str>>(&mut self, message: P) {
|
||||||
if self.set_title {
|
if self.set_title {
|
||||||
self.term
|
self.term
|
||||||
.set_title(format!("{}Topgrade - {}", self.prefix, message.as_ref()));
|
.set_title(format!("{}Topgrade - {}", self.prefix, message.as_ref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
{
|
|
||||||
if self.desktop_notification {
|
if self.desktop_notification {
|
||||||
Notification::new()
|
self.notify_desktop(message.as_ref(), Some(Duration::from_secs(5)));
|
||||||
.summary("Topgrade")
|
|
||||||
.body(message.as_ref())
|
|
||||||
.appname("topgrade")
|
|
||||||
.timeout(5)
|
|
||||||
.show()
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let now = Local::now();
|
let now = Local::now();
|
||||||
@@ -156,14 +186,7 @@ impl Terminal {
|
|||||||
self.term.set_title("Topgrade - Awaiting user");
|
self.term.set_title("Topgrade - Awaiting user");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
self.notify_desktop(&format!("{} failed", step_name), None);
|
||||||
Notification::new()
|
|
||||||
.summary("Topgrade")
|
|
||||||
.body(&format!("{} failed", step_name))
|
|
||||||
.appname("topgrade")
|
|
||||||
.timeout(0)
|
|
||||||
.show()
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
self.term
|
self.term
|
||||||
.write_fmt(format_args!(
|
.write_fmt(format_args!(
|
||||||
|
|||||||
Reference in New Issue
Block a user