#[cfg(feature = "message-box")]
use crate::alert_service::AlertService;
#[cfg(feature = "message-box")]
use crate::settings::ARGS;
#[cfg(feature = "message-box")]
use crate::settings::RUNS_ON_CONSOLE;
use crate::CONFIG_PATH;
#[cfg(feature = "message-box")]
use crate::VERSION;
use lazy_static::lazy_static;
use log::LevelFilter;
use log::{Level, Metadata, Record};
#[cfg(not(all(unix, not(target_os = "macos"))))]
#[cfg(feature = "message-box")]
use msgbox::IconType;
#[cfg(all(unix, not(target_os = "macos")))]
#[cfg(feature = "message-box")]
use notify_rust::{Hint, Notification, Timeout};
use std::env;
use std::path::PathBuf;
use std::sync::RwLock;
#[cfg(feature = "message-box")]
const ALERT_DIALOG_TITLE: &str = "Tp-Note";
#[cfg(feature = "message-box")]
lazy_static! {
pub static ref ALERT_DIALOG_TITLE_LINE: String = format!(
"{} (v{})",
&ALERT_DIALOG_TITLE,
VERSION.unwrap_or("unknown")
);
}
#[cfg(all(unix, not(target_os = "macos")))]
#[cfg(feature = "message-box")]
fn popup_alert(msg: &str) {
if log::max_level() == Level::Trace {
return;
}
if let Ok(handle) = Notification::new()
.summary(&ALERT_DIALOG_TITLE_LINE)
.body(msg)
.icon("tpnote")
.appname("tpnote")
.hint(Hint::Resident(true)) .timeout(Timeout::Never) .show()
{
handle.wait_for_action(|_action| { })
};
}
#[cfg(not(all(unix, not(target_os = "macos"))))]
#[cfg(feature = "message-box")]
fn popup_alert(msg: &str) {
let _ = msgbox::create(&ALERT_DIALOG_TITLE_LINE, msg, IconType::Info);
}
lazy_static! {
pub static ref ERR_MSG_TAIL: String = {
let mut args_str = String::new();
for argument in env::args() {
args_str.push_str(argument.as_str());
args_str.push(' ');
};
format!(
"\n\
__________\n\
Additional technical details:\n\
* Command line parameters:\n\
{}\n\
* Configuration file:\n\
{}",
args_str,
CONFIG_PATH
.as_ref()
.unwrap_or(&PathBuf::from("no path found"))
.to_str()
.unwrap_or_default()
)
};
}
static APP_LOGGER_ENABLE_POPUP: RwLock<bool> = RwLock::new(false);
pub struct AppLogger;
static APP_LOGGER: AppLogger = AppLogger;
impl AppLogger {
#[inline]
pub fn init() {
#[cfg(feature = "message-box")]
if !*RUNS_ON_CONSOLE && !ARGS.batch {
AlertService::init(popup_alert);
};
log::set_logger(&APP_LOGGER).unwrap();
log::set_max_level(LevelFilter::Error);
}
#[allow(dead_code)]
pub fn set_max_level(level: LevelFilter) {
log::set_max_level(level);
}
#[allow(dead_code)]
pub fn set_popup_always_enabled(popup: bool) {
*APP_LOGGER_ENABLE_POPUP.write().unwrap() = popup;
}
pub fn flush() {
#[cfg(feature = "message-box")]
if !*RUNS_ON_CONSOLE && !ARGS.batch {
AlertService::flush();
log::set_max_level(LevelFilter::Off);
}
}
}
impl log::Log for AppLogger {
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
metadata.level() <= Level::Trace
}
fn log(&self, record: &Record<'_>) {
if self.enabled(record.metadata()) {
let mut msg = format!("{}:\n{}", record.level(), &record.args().to_string());
if record.metadata().level() == Level::Error {
msg.push_str(&ERR_MSG_TAIL);
};
eprintln!("*** {}", msg);
#[cfg(feature = "message-box")]
if !*RUNS_ON_CONSOLE
&& !ARGS.batch
&& ((record.metadata().level() == LevelFilter::Error)
|| *APP_LOGGER_ENABLE_POPUP.read().unwrap())
{
let _ = AlertService::push_str(msg);
};
}
}
fn flush(&self) {
Self::flush();
}
}