From 19ef64f8ed6abd19ad731ba710150968ec432de8 Mon Sep 17 00:00:00 2001 From: Anas Elgarhy Date: Mon, 20 Feb 2023 05:34:03 +0200 Subject: [PATCH] Just create the notifications handler --- src/bin/cmus-notify.rs | 14 +-- src/notification.rs | 239 +++++++++++++++++++++-------------------- 2 files changed, 128 insertions(+), 125 deletions(-) diff --git a/src/bin/cmus-notify.rs b/src/bin/cmus-notify.rs index 274d103..e659547 100644 --- a/src/bin/cmus-notify.rs +++ b/src/bin/cmus-notify.rs @@ -50,7 +50,10 @@ fn main() { #[cfg(feature = "debug")] info!("Query command built: {:?}", query_command); - let mut notification = notify_rust::Notification::new(); + let interval = settings.interval; + let link = settings.link; + + let mut notifications_handler = notification::NotificationsHandler::new(settings); // Initialize the buffer to store the response from cmus, to compare it with the next one. let mut previous_response = CmusQueryResponse::default(); @@ -58,11 +61,11 @@ fn main() { loop { // Get the response from cmus. let Ok(response) = cmus::ping_cmus(&mut query_command) else { - if settings.link { + if link { std::process::exit(0) } else { // If the track info is the same as the previous one, just sleep for a while and try again. - sleep!(settings.interval); + sleep!(interval); continue; } }; @@ -74,8 +77,7 @@ fn main() { // Update the previous response. previous_response = response; - - match notification::show_notification(events, &settings, &mut notification, &previous_response) { + match notifications_handler.show_notification(events, &previous_response) { Ok(_) => {} Err(e) => { eprintln!("Error: {}", e); @@ -83,6 +85,6 @@ fn main() { } } } - sleep!(settings.interval); + sleep!(interval); } } diff --git a/src/notification.rs b/src/notification.rs index 64e8da3..e8f0430 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -7,133 +7,134 @@ use log::{debug, info}; use notify_rust::Notification; use crate::cmus::query::CmusQueryResponse; -#[inline(always)] -pub fn show_notification( - events: Vec, - settings: &Settings, - notification: &mut Notification, - response: &CmusQueryResponse, -) -> Result<(), notify_rust::error::Error> { - if events.is_empty() { - #[cfg(feature = "debug")] - info!("no events to process"); - return Ok(()); // No events to process. +pub struct NotificationsHandler { + cover_set: bool, + notification: Notification, + handlers: Vec, + settings: Settings, +} + +impl NotificationsHandler { + pub fn new(settings: Settings) -> Self { + Self { + cover_set: false, + notification: Notification::new(), + handlers: Vec::new(), + settings, + } } - //FIXME: Should check if the user has enabled the cover feature or use a static cover. - update_cover(&events[0], response, settings, notification); + pub fn show_notification( + &mut self, + events: Vec, + response: &CmusQueryResponse, + ) -> Result<(), notify_rust::error::Error> { + if events.is_empty() { + #[cfg(feature = "debug")] + info!("no events to process"); + return Ok(()); // No events to process. + } - for event in events { - #[cfg(feature = "debug")] - info!("event: {:?}", event); + //FIXME: Should check if the user has enabled the cover feature or use a static cover. + self.update_cover(&events[0], response); - match event { - CmusEvent::StatusChanged(track) => { - #[cfg(feature = "debug")] - debug!("Status changed: {:?}", track.status); - build_status_notification(track, settings, notification); - notification.show()?; + for event in events { + #[cfg(feature = "debug")] + info!("event: {:?}", event); + + match event { + CmusEvent::StatusChanged(track) => { + #[cfg(feature = "debug")] + debug!("Status changed: {:?}", track.status); + self.build_status_notification(track); + self.notification.show()?; + } + CmusEvent::TrackChanged(track) => { + #[cfg(feature = "debug")] + debug!("Track changed: {:?}", track); + self.build_track_notification(track)? + } + /* + CmusEvent::VolumeChanged { left, right } if settings.show_player_notifications => { + build_volume_notification(left, right, settings, notification)? + } + CmusEvent::PositionChanged(position) => todo!(), + CmusEvent::ShuffleChanged(shuffle) if settings.show_player_notifications => { + build_shuffle_notification(shuffle, settings, notification)? + } + CmusEvent::RepeatChanged(repeat) if settings.show_player_notifications => { + build_repeat_notification(repeat, settings, notification)? + } + CmusEvent::AAAMode(aaa_mode) if settings.show_player_notifications => { + build_aaa_mode_notification(aaa_mode, settings, notification)? + } + */ + _ => {} } + } + Ok(()) + } + + #[inline(always)] + fn build_status_notification(&mut self, track: Track) { + // Set the summary and body of the notification. + self.notification + .summary( + process_template_placeholders(&self.settings.status_notification_summary, &track).as_str(), + ) + .body(process_template_placeholders(&self.settings.status_notification_body, &track).as_str()) + .timeout(self.settings.status_notification_timeout as i32 * 1000); + } + + #[inline(always)] + fn build_track_notification(&mut self, track: Track) -> Result<(), notify_rust::error::Error> { + // Set the summary and body of the notification. + self.notification + .summary(process_template_placeholders(&self.settings.summary, &track).as_str()) + .body(process_template_placeholders(&self.settings.body, &track).as_str()); + + let n = self.notification.show()?; + + Ok(()) + } + + #[inline(always)] + fn update_cover(&mut self, first_event: &CmusEvent, response: &CmusQueryResponse) { + // If the track is changed, we need to update the cover. + match first_event { CmusEvent::TrackChanged(track) => { - #[cfg(feature = "debug")] - debug!("Track changed: {:?}", track); - build_track_notification(track, settings, notification)? + self.set_cover(track); } - /* - CmusEvent::VolumeChanged { left, right } if settings.show_player_notifications => { - build_volume_notification(left, right, settings, notification)? - } - CmusEvent::PositionChanged(position) => todo!(), - CmusEvent::ShuffleChanged(shuffle) if settings.show_player_notifications => { - build_shuffle_notification(shuffle, settings, notification)? - } - CmusEvent::RepeatChanged(repeat) if settings.show_player_notifications => { - build_repeat_notification(repeat, settings, notification)? - } - CmusEvent::AAAMode(aaa_mode) if settings.show_player_notifications => { - build_aaa_mode_notification(aaa_mode, settings, notification)? - } - */ - _ => {} - } - } - Ok(()) -} - -#[inline(always)] -fn build_status_notification( - track: Track, - settings: &Settings, - notification: &mut Notification, -) { - // Set the summary and body of the notification. - notification - .summary( - process_template_placeholders(&settings.status_notification_summary, &track).as_str(), - ) - .body(process_template_placeholders(&settings.status_notification_body, &track).as_str()) - .timeout(settings.status_notification_timeout as i32 * 1000); -} - -#[inline(always)] -fn build_track_notification( - track: Track, - settings: &Settings, - notification: &mut Notification, -) -> Result<(), notify_rust::error::Error> { - // Set the summary and body of the notification. - notification - .summary(process_template_placeholders(&settings.summary, &track).as_str()) - .body(process_template_placeholders(&settings.body, &track).as_str()); - - let n = notification.show()?; - - Ok(()) -} - -macro_rules! setup_notification { - ($notification: expr, $settings: expr) => { - $notification - .appname("cmus-notify") - .timeout($settings.timeout as i32 * 1000) - .hint(notify_rust::Hint::Category("music".to_string())) - .hint(notify_rust::Hint::DesktopEntry("cmus-notify.desktop".to_string())) - .hint(notify_rust::Hint::Resident(true)); - }; -} - -#[inline(always)] -fn update_cover(first_event: &CmusEvent, response: &CmusQueryResponse, settings: &Settings, notification: &mut Notification) { - let mut cover = TrackCover::None; - // If the track is changed, we need to update the cover. - match first_event { - CmusEvent::TrackChanged(track) => { - cover = track_cover( - &track.path, - settings.depth, - settings.force_use_external_cover, - settings.no_use_external_cover, - ); - } - _ => { - if cover == TrackCover::None { - // If the cover is not found, we need to update it. - if let Ok(track) = &response.track() { - cover = track_cover( - &track.path, - settings.depth, - settings.force_use_external_cover, - settings.no_use_external_cover, - ); + _ => { + if !self.cover_set { + // If the cover is not found, we need to update it. + if let Ok(track) = response.track() { + self.set_cover(&track); + } } } - } - }; - // Set the notification cover. - if cover != TrackCover::None { - *notification = Notification::new(); - // Reset the notification. - setup_notification!(&mut *notification, &settings); - cover.set_notification_image(&mut *notification); + }; + + } + + fn set_cover(&mut self, track: &Track) { + // Reset the notification + self.notification = Notification::new(); + self.notification.appname("cmus-notify") + .timeout(self.settings.timeout as i32 * 1000) + .hint(notify_rust::Hint::Category("music".to_string())) + .hint(notify_rust::Hint::DesktopEntry("cmus.desktop".to_string())) + .hint(notify_rust::Hint::Resident(true)); + + // Get the track cover and set it to notification + track_cover( + &track.path, + self.settings.depth, + self.settings.force_use_external_cover, + self.settings.no_use_external_cover, + ).set_notification_image(&mut self.notification); + // Flip the change flag + self.cover_set = true; } } +