Fix the sttings

This commit is contained in:
Anas Elgarhy 2023-02-21 21:48:31 +02:00
parent a867ee5fe2
commit 4484495776
No known key found for this signature in database
GPG key ID: 0501802A1D496528
7 changed files with 352 additions and 292 deletions

View file

@ -1,6 +1,6 @@
use cmus_notify::{
cmus::{self, events::CmusEvent, query::CmusQueryResponse},
notification,
notification, settings,
settings::Settings,
track_cover, TrackCover,
};
@ -38,19 +38,15 @@ fn main() {
}
// Build the command, or use the default. (to speed up the main loop, because we don't need to build it every time)
let remote_bin_path = settings
.cmus_remote_bin_path
.clone()
.unwrap_or("cmus-remote".to_string());
let mut query_command = cmus::build_query_command(
remote_bin_path.as_str(),
settings.remote_bin_path().as_str(),
&settings.cmus_socket_address,
&settings.cmus_socket_password,
);
#[cfg(feature = "debug")]
info!("Query command built: {:?}", query_command);
let interval = settings.interval;
let interval = settings.interval();
let link = settings.link;
let mut notifications_handler = notification::NotificationsHandler::new(settings);

View file

@ -1,8 +1,8 @@
use crate::cmus::player_settings::{AAAMode, PlayerSettings, Shuffle};
use crate::cmus::{Track, TrackStatus};
use crate::notification::Action;
use crate::process_template_placeholders;
use crate::settings::Settings;
use crate::{process_template_placeholders, settings};
#[derive(Debug, PartialEq)]
pub enum CmusEvent {
@ -51,19 +51,19 @@ impl CmusEvent {
match self {
StatusChanged(track, player_settings) => (
process_template_placeholders(
&settings.status_notification_body,
settings.status_notification_body(),
track,
player_settings,
),
Action::Show,
),
TrackChanged(track, player_settings) => (
process_template_placeholders(&settings.body, track, player_settings),
process_template_placeholders(settings.body(), track, player_settings),
Action::Show,
),
VolumeChanged(track, player_settings) => (
process_template_placeholders(
&settings.volume_notification_body,
settings.volume_notification_body(),
track,
player_settings,
),
@ -74,7 +74,7 @@ impl CmusEvent {
}
ShuffleChanged(track, player_settings) => (
process_template_placeholders(
&settings.shuffle_notification_body,
settings.shuffle_notification_body(),
track,
player_settings,
),
@ -82,7 +82,7 @@ impl CmusEvent {
),
RepeatChanged(track, player_settings) => (
process_template_placeholders(
&settings.repeat_notification_body,
settings.repeat_notification_body(),
track,
player_settings,
),
@ -90,7 +90,7 @@ impl CmusEvent {
),
AAAMode(track, player_settings) => (
process_template_placeholders(
&settings.aaa_mode_notification_body,
settings.aaa_mode_notification_body(),
track,
player_settings,
),
@ -105,19 +105,19 @@ impl CmusEvent {
match self {
StatusChanged(track, player_settings) => (
process_template_placeholders(
&settings.status_notification_summary,
settings.status_notification_summary(),
track,
player_settings,
),
Action::Show,
),
TrackChanged(track, player_settings) => (
process_template_placeholders(&settings.summary, track, player_settings),
process_template_placeholders(settings.summary(), track, player_settings),
Action::Show,
),
VolumeChanged(track, player_settings) => (
process_template_placeholders(
&settings.volume_notification_summary,
settings.volume_notification_summary(),
track,
player_settings,
),
@ -128,7 +128,7 @@ impl CmusEvent {
}
ShuffleChanged(track, player_settings) => (
process_template_placeholders(
&settings.shuffle_notification_summary,
settings.shuffle_notification_summary(),
track,
player_settings,
),
@ -136,7 +136,7 @@ impl CmusEvent {
),
RepeatChanged(track, player_settings) => (
process_template_placeholders(
&settings.repeat_notification_summary,
settings.repeat_notification_summary(),
track,
player_settings,
),
@ -144,7 +144,7 @@ impl CmusEvent {
),
AAAMode(track, player_settings) => (
process_template_placeholders(
&settings.aaa_mode_notification_summary,
settings.aaa_mode_notification_summary(),
track,
player_settings,
),

View file

@ -14,11 +14,11 @@ use thiserror::Error;
use typed_builder::TypedBuilder;
pub trait TemplateProcessor {
fn process(&self, template: &String) -> String;
fn process(&self, template: String) -> String;
/// Returns a vector of keys found in the template.
/// The keys are the strings between curly braces.
fn get_keys(template: &String) -> Vec<String> {
fn get_keys(template: &str) -> Vec<String> {
let mut keys = Vec::new(); // Just a buffer to store the keys.
let mut key = String::new(); // Just a buffer to build the key.
@ -92,16 +92,16 @@ impl TemplateProcessor for Track {
/// The template is a string with placeholders that will be replaced with the track metadata.
/// The unknown placeholders will be skipped (don't replaced with anything, because they are maybe placeholders for player settings).
#[inline(always)]
fn process(&self, template: &String) -> String {
fn process(&self, template: String) -> String {
#[cfg(feature = "debug")]
{
info!("Processing the template placeholders.");
debug!("Template: {template}");
debug!("Track: {self:?}");
}
let mut processed = template.clone();
let mut processed = template.to_string();
Self::get_keys(template).iter().for_each(|key| {
Self::get_keys(template.as_str()).iter().for_each(|key| {
#[cfg(feature = "debug")]
debug!("Replacing the placeholder {{{key}}} with its matching value.");
// Replace the key with their matching value if exists, if not replace with the empty string.

View file

@ -42,7 +42,7 @@ impl TemplateProcessor for PlayerSettings {
/// If the key is unknown, it will be replaced with an empty string.
/// This function should be used after the track metadata placeholders have been replaced.
#[inline(always)]
fn process(&self, template: &String) -> String {
fn process(&self, template: String) -> String {
#[cfg(feature = "debug")]
{
info!("Processing template: {}", template);
@ -50,7 +50,7 @@ impl TemplateProcessor for PlayerSettings {
}
let mut processed = template.clone();
Self::get_keys(template).iter().for_each(|key| {
Self::get_keys(template.as_str()).iter().for_each(|key| {
let value = match key.as_str() {
"repeat" => self.repeat.to_string(),
"repeat_current" => self.repeat_current.to_string(),

View file

@ -212,12 +212,12 @@ fn search(search_directory: &str, matcher: &regex::Regex) -> std::io::Result<Opt
/// Replace all the placeholders in the template with their matching value.
#[inline(always)]
pub fn process_template_placeholders(
template: &String,
template: String,
track: &cmus::Track,
player_settings: &cmus::player_settings::PlayerSettings,
) -> String {
let res = track.process(template);
player_settings.process(&res)
player_settings.process(res)
}
#[cfg(test)]

View file

@ -3,7 +3,7 @@ use crate::cmus::player_settings::PlayerSettings;
use crate::cmus::query::CmusQueryResponse;
use crate::cmus::{Track, TrackStatus};
use crate::settings::Settings;
use crate::{process_template_placeholders, track_cover, TrackCover};
use crate::{process_template_placeholders, settings, track_cover, TrackCover};
#[cfg(feature = "debug")]
use log::{debug, info};
use notify_rust::Notification;
@ -94,8 +94,7 @@ impl NotificationsHandler {
// Reset the notification
self.notification = Notification::new();
self.notification
.appname("cmus-notify")
.timeout(self.settings.timeout as i32 * 1000)
.appname(self.settings.app_name().as_str())
.hint(notify_rust::Hint::Category("music".to_string()))
.hint(notify_rust::Hint::DesktopEntry("cmus.desktop".to_string()))
.hint(notify_rust::Hint::Resident(true));
@ -103,7 +102,7 @@ impl NotificationsHandler {
// Get the track cover and set it to notification
track_cover(
&track.path,
self.settings.depth,
self.settings.depth(),
self.settings.force_use_external_cover,
self.settings.no_use_external_cover,
)

View file

@ -3,28 +3,29 @@ use clap::Parser;
use log::{debug, info};
use serde::{Deserialize, Serialize};
const NOTIFICATION_TIMEOUT: u8 = 5;
const NOTIFICATION_BODY: &str =
pub const NOTIFICATION_TIMEOUT: u8 = 5;
pub const NOTIFICATION_BODY: &str =
"<b>Playing:</b> {title} \n <b>album:</b> {album} \n <b>Artist:</b> {artist} - {year}";
const NOTIFICATION_SUMMARY: &str = "{title}";
const NOTIFICATION_APP_NAME: &str = "C* Music Player";
const DEFAULT_MAX_DEPTH: u8 = 3;
const DEFAULT_INTERVAL_TIME: u64 = 1000; // 1000 ms
const DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY: &str = "<b>{status}</b>";
const DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY: &str = "Status changed";
const DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT: u8 = 1;
const DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY: &str = "Volume changed to {volume}%";
const DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY: &str = "Volume changed";
const DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT: u8 = 1;
const DEFAULT_SHUFFLE_NOTIFICATION_BODY: &str = "Shuffle mode changed to {shuffle}";
const DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY: &str = "Shuffle mode changed";
const DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT: u8 = 1;
const DEFAULT_REPEAT_NOTIFICATION_BODY: &str = "Repeat mode changed to {repeat}";
const DEFAULT_REPEAT_NOTIFICATION_SUMMARY: &str = "Repeat mode changed";
const DEFAULT_REPEAT_NOTIFICATION_TIMEOUT: u8 = 1;
const DEFAULT_AAAMODE_NOTIFICATION_BODY: &str = "AAA mode changed to {aaa_mode}";
const DEFAULT_AAAMODE_NOTIFICATION_SUMMARY: &str = "AAA mode changed";
const DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT: u8 = 1;
pub const NOTIFICATION_SUMMARY: &str = "{title}";
pub const NOTIFICATION_APP_NAME: &str = "C* Music Player";
pub const DEFAULT_REMOTE_COMMAND: &str = "cmus-remote";
pub const DEFAULT_MAX_DEPTH: u8 = 3;
pub const DEFAULT_INTERVAL_TIME: u64 = 1000; // 1000 ms
pub const DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY: &str = "<b>{status}</b>";
pub const DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY: &str = "Status changed";
pub const DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT: u8 = 1;
pub const DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY: &str = "Volume changed to {volume}%";
pub const DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY: &str = "Volume changed";
pub const DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT: u8 = 1;
pub const DEFAULT_SHUFFLE_NOTIFICATION_BODY: &str = "Shuffle mode changed to {shuffle}";
pub const DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY: &str = "Shuffle mode changed";
pub const DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT: u8 = 1;
pub const DEFAULT_REPEAT_NOTIFICATION_BODY: &str = "Repeat mode changed to {repeat}";
pub const DEFAULT_REPEAT_NOTIFICATION_SUMMARY: &str = "Repeat mode changed";
pub const DEFAULT_REPEAT_NOTIFICATION_TIMEOUT: u8 = 1;
pub const DEFAULT_AAAMODE_NOTIFICATION_BODY: &str = "AAA mode changed to {aaa_mode}";
pub const DEFAULT_AAAMODE_NOTIFICATION_SUMMARY: &str = "AAA mode changed";
pub const DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT: u8 = 1;
#[cfg(feature = "lyrics")]
const DEFAULT_LYRICS_NOTIFICATION_BODY: &str = "{lyrics}";
#[cfg(feature = "lyrics")]
@ -34,8 +35,8 @@ const DEFAULT_LYRICS_NOTIFICATION_SUMMARY: &str = "Lyrics";
#[command(author, about, version, long_about = None)]
pub struct Settings {
/// The notification timeout, in seconds
#[arg(short, long, default_value_t = NOTIFICATION_TIMEOUT)]
pub timeout: u8,
#[arg(short, long)]
timeout: Option<u8>,
/// Make the notification persistent, i.e. not disappear after a timeout (you can dismiss it manually)
#[arg(short, long)]
pub persistent: bool,
@ -48,7 +49,7 @@ pub struct Settings {
/// you can give it the full path to an image file or a name of an icon from the current icon theme
/// (e.g. "audio-x-generic" or "spotify-client")
#[arg(short = 'i', long = "icon", default_value = None)]
pub notification_static_icon: Option<String>,
notification_static_icon: Option<String>,
/// The path to look for the cover image, if not given, the cover will be searched in the track's directory
/// for an image file with the name "cover".
///
@ -60,7 +61,7 @@ pub struct Settings {
///
/// If you not specify the full path, the cover will be started from the track's directory.
#[arg(short = 'w', long = "cover-path", default_value = None)]
pub cover_path: Option<String>,
cover_path: Option<String>,
#[cfg(feature = "lyrics")]
/// The lyrics file path, if not given, the lyrics will be searched in the track's directory
/// for a text file with the name "lyrics", or with the same name as the track.
@ -73,24 +74,24 @@ pub struct Settings {
///
/// If you not specify the full path, the lyrics will be started from the track's directory.
#[arg(short = 'y', long, default_value = None)]
pub lyrics_path: Option<String>,
lyrics_path: Option<String>,
/// The maximum path depth to search for the cover and lyrics files,
/// if the files are not found in the track's directory, or the directory specified by the `--cover-path`
/// or `--lyrics-path`* options, the program will search in the parent directory,
/// and so on, until the maximum depth is reached.
#[arg(short, long, default_value_t = DEFAULT_MAX_DEPTH)]
pub depth: u8,
#[arg(short, long, default_value = None)]
depth: Option<u8>,
/// The name of the app to use for the notification.
#[arg(short, long, default_value = NOTIFICATION_APP_NAME)]
pub app_name: String,
#[arg(short, long, default_value = None)]
pub app_name: Option<String>,
/// The summary of the notification.
///
/// you can use the placeholder "{artist}" and "{album}" and "{title}" and "{track_number}" and
/// "{disc_number}" and "{year}" and "{genre}" in the summary, they will be replaced with the corresponding metadata.
/// but if the metadata is not available, the placeholder will be replaced with an empty string.
/// e.g. "{artist} - {title}"
#[arg(short, long, default_value = NOTIFICATION_SUMMARY)]
pub summary: String,
#[arg(short, long, default_value = None)]
summary: Option<String>,
#[cfg(feature = "lyrics")]
/// The body of the notification.
///
@ -109,8 +110,8 @@ pub struct Settings {
/// the notification will be persistent, and you need to dismiss it manually tow times.
///
/// Also you can use the simple html markup, if your notification server supports it.
#[arg(default_value = NOTIFICATION_BODY)]
pub body: String,
#[arg(default_value = None)]
body: Option<String>,
#[cfg(not(feature = "lyrics"))]
/// The body of the notification.
///
@ -125,14 +126,14 @@ pub struct Settings {
/// the notification will be persistent, and you need to dismiss it manually tow times.
///
/// Also you can use the simple html markup, if your notification server supports it.
#[arg(default_value = NOTIFICATION_BODY)]
pub body: String,
#[arg(default_value = None)]
body: Option<String>,
/// The cmus-remote binary path, if not given, the program will search for it in the PATH environment variable.
///
/// if you're using a custom package format like flatpak, or snap, you can give it the full run command (without any arguments),
/// e.g. "flatpak run io.github.cmus.cmus", "snap run cmus"
#[arg(short = 'b', long = "cmus-remote-bin", default_value = None)]
pub cmus_remote_bin_path: Option<String>,
cmus_remote_bin_path: Option<String>,
/// The cmus socket address, if not given, the program will use the default socket address, which is "$XDG_RUNTIME_DIR/cmus-socket".
#[arg(short = 'k', long = "cmus-socket", default_value = None)]
pub cmus_socket_address: Option<String>,
@ -149,8 +150,8 @@ pub struct Settings {
/// but it will make the notification a little bit stupid, if you change the track manually, the notification will not update until the track duration time is reached.
///
/// but I recommend 1s, it's not too fast, and not too slow, and it will not waste your CPU and battery.
#[arg(short = 'r', long, default_value_t = DEFAULT_INTERVAL_TIME)]
pub interval: u64,
#[arg(short = 'r', long, default_value = None)]
interval: Option<u64>,
/// Link the program with cmus, if the cmus are not running, the program will exit.
#[arg(short = 'l', long)]
pub link: bool,
@ -176,98 +177,98 @@ pub struct Settings {
/// you can use the placeholders like "{volume}" in the body, it will be replaced with the shuffle mode.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'B', long, default_value = DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY)]
pub volume_notification_body: String,
#[arg(short = 'B', long, default_value = None)]
volume_notification_body: Option<String>,
/// The volume change notification summary.
#[arg(short = 'E', long, default_value = DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY)]
pub volume_notification_summary: String,
#[arg(short = 'E', long, default_value = None)]
volume_notification_summary: Option<String>,
/// The time out of the volume change notification, in seconds.
#[arg(short = 'T', long, default_value_t = DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT)]
pub volume_notification_timeout: u8,
#[arg(short = 'T', long, default_value = None)]
volume_notification_timeout: Option<u8>,
/// The shuffle mode change notification body.
/// you can use the placeholders like "{shuffle}" in the body, it will be replaced with the shuffle mode.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'S', long, default_value = DEFAULT_SHUFFLE_NOTIFICATION_BODY)]
pub shuffle_notification_body: String,
#[arg(short = 'S', long)]
shuffle_notification_body: Option<String>,
/// The shuffle mode change notification summary.
/// you can use the placeholders like "{shuffle}" in the summary, it will be replaced with the shuffle mode.
#[arg(short = 'U', long, default_value = DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY)]
pub shuffle_notification_summary: String,
#[arg(short = 'U', long)]
shuffle_notification_summary: Option<String>,
/// The time out of the shuffle mode change notification, in seconds.
#[arg(short = 'Y', long, default_value_t = DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT)]
pub shuffle_notification_timeout: u8,
#[arg(short = 'Y', long)]
shuffle_notification_timeout: Option<u8>,
/// The repeat mode change notification body.
/// you can use the placeholders like "{repeat}" in the body, it will be replaced with the repeat mode.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'R', long, default_value = DEFAULT_REPEAT_NOTIFICATION_BODY)]
pub repeat_notification_body: String,
#[arg(short = 'R', long)]
repeat_notification_body: Option<String>,
/// The repeat mode change notification summary.
/// you can use the placeholders like "{repeat}" in the summary, it will be replaced with the repeat mode.
#[arg(short = 'G', long, default_value = DEFAULT_REPEAT_NOTIFICATION_SUMMARY)]
pub repeat_notification_summary: String,
#[arg(short = 'G', long)]
repeat_notification_summary: Option<String>,
/// The time out of the repeat mode change notification, in seconds.
#[arg(short = 'H', long, default_value_t = DEFAULT_REPEAT_NOTIFICATION_TIMEOUT)]
pub repeat_notification_timeout: u8,
#[arg(short = 'H', long)]
repeat_notification_timeout: Option<u8>,
/// The aaa mode change notification body.
/// you can use the placeholders like "{aaa_mode}" in the body, it will be replaced with the aaa mode.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'A', long, default_value = DEFAULT_AAAMODE_NOTIFICATION_BODY)]
pub aaa_mode_notification_body: String,
#[arg(short = 'A', long)]
aaa_mode_notification_body: Option<String>,
/// The aaa mode change notification summary.
/// you can use the placeholders like "{aaa_mode}" in the summary, it will be replaced with the aaa mode.
#[arg(short = 'D', long, default_value = DEFAULT_AAAMODE_NOTIFICATION_SUMMARY)]
pub aaa_mode_notification_summary: String,
#[arg(short = 'D', long)]
aaa_mode_notification_summary: Option<String>,
/// The time out of the aaa mode change notification, in seconds.
#[arg(short = 'F', long, default_value_t = DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT)]
pub aaa_mode_notification_timeout: u8,
#[arg(short = 'F', long)]
aaa_mode_notification_timeout: Option<u8>,
#[cfg(feature = "lyrics")]
/// The lyrics notification body, if you want to show the lyrics separate notification.
/// you can use the placeholders like "{lyrics}" in the body, it will be replaced with the lyrics.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'L', long, default_value = DEFAULT_LYRICS_NOTIFICATION_BODY)]
pub lyrics_notification_body: String,
#[arg(short = 'L', long)]
lyrics_notification_body: Option<String>,
#[cfg(feature = "lyrics")]
/// The lyrics notification summary, if you want to show the lyrics separate notification.
/// you can use the placeholders like "{lyrics}" in the summary, it will be replaced with the lyrics.
#[arg(short = 'M', long, default_value = DEFAULT_LYRICS_NOTIFICATION_SUMMARY)]
pub lyrics_notification_summary: String,
#[arg(short = 'M', long)]
lyrics_notification_summary: Option<String>,
/// The status change notification body.
/// you can use the placeholders like "{status}" in the body, it will be replaced with the aaa mode.
///
/// If you leave it empty, the notification will not be shown.
#[arg(short = 'O', long, default_value = DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY)]
pub status_notification_body: String,
#[arg(short = 'O', long)]
status_notification_body: Option<String>,
/// The status change notification summary.
/// you can use the placeholders like "{status}" in the summary, it will be replaced with the aaa mode.
#[arg(short = 'P', long, default_value = DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY)]
pub status_notification_summary: String,
#[arg(short = 'P', long)]
status_notification_summary: Option<String>,
/// The time out of the status change notification, in seconds.
#[arg(short = 'Q', long, default_value_t = DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT)]
pub status_notification_timeout: u8,
#[arg(short = 'Q', long)]
status_notification_timeout: Option<u8>,
}
impl Default for Settings {
fn default() -> Self {
Self {
timeout: NOTIFICATION_TIMEOUT,
timeout: Some(NOTIFICATION_TIMEOUT),
persistent: false,
show_track_cover: true,
notification_static_icon: None,
cover_path: None,
#[cfg(feature = "lyrics")]
lyrics_path: None,
depth: DEFAULT_MAX_DEPTH,
app_name: NOTIFICATION_APP_NAME.to_string(),
summary: NOTIFICATION_SUMMARY.to_string(),
body: NOTIFICATION_BODY.to_string(),
cmus_remote_bin_path: None,
depth: Some(DEFAULT_MAX_DEPTH),
app_name: Some(NOTIFICATION_APP_NAME.to_string()),
summary: Some(NOTIFICATION_SUMMARY.to_string()),
body: Some(NOTIFICATION_BODY.to_string()),
cmus_remote_bin_path: Some(DEFAULT_REMOTE_COMMAND.to_string()),
cmus_socket_address: None,
cmus_socket_password: None,
interval: DEFAULT_INTERVAL_TIME,
interval: Some(DEFAULT_INTERVAL_TIME),
link: false,
force_use_external_cover: false,
#[cfg(feature = "lyrics")]
@ -276,25 +277,29 @@ impl Default for Settings {
#[cfg(feature = "lyrics")]
no_use_external_lyrics: false,
show_player_notifications: false,
volume_notification_body: DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY.to_string(),
volume_notification_summary: DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY.to_string(),
volume_notification_timeout: DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT,
shuffle_notification_body: DEFAULT_SHUFFLE_NOTIFICATION_BODY.to_string(),
shuffle_notification_summary: DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY.to_string(),
shuffle_notification_timeout: DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT,
repeat_notification_body: DEFAULT_REPEAT_NOTIFICATION_BODY.to_string(),
repeat_notification_summary: DEFAULT_REPEAT_NOTIFICATION_SUMMARY.to_string(),
repeat_notification_timeout: DEFAULT_REPEAT_NOTIFICATION_TIMEOUT,
aaa_mode_notification_body: DEFAULT_AAAMODE_NOTIFICATION_BODY.to_string(),
aaa_mode_notification_summary: DEFAULT_AAAMODE_NOTIFICATION_SUMMARY.to_string(),
aaa_mode_notification_timeout: DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT,
volume_notification_body: Some(DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY.to_string()),
volume_notification_summary: Some(
DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY.to_string(),
),
volume_notification_timeout: Some(DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT),
shuffle_notification_body: Some(DEFAULT_SHUFFLE_NOTIFICATION_BODY.to_string()),
shuffle_notification_summary: Some(DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY.to_string()),
shuffle_notification_timeout: Some(DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT),
repeat_notification_body: Some(DEFAULT_REPEAT_NOTIFICATION_BODY.to_string()),
repeat_notification_summary: Some(DEFAULT_REPEAT_NOTIFICATION_SUMMARY.to_string()),
repeat_notification_timeout: Some(DEFAULT_REPEAT_NOTIFICATION_TIMEOUT),
aaa_mode_notification_body: Some(DEFAULT_AAAMODE_NOTIFICATION_BODY.to_string()),
aaa_mode_notification_summary: Some(DEFAULT_AAAMODE_NOTIFICATION_SUMMARY.to_string()),
aaa_mode_notification_timeout: Some(DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT),
#[cfg(feature = "lyrics")]
lyrics_notification_body: DEFAULT_LYRICS_NOTIFICATION_BODY.to_string(),
lyrics_notification_body: Some(DEFAULT_LYRICS_NOTIFICATION_BODY.to_string()),
#[cfg(feature = "lyrics")]
lyrics_notification_summary: DEFAULT_LYRICS_NOTIFICATION_SUMMARY.to_string(),
status_notification_body: DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY.to_string(),
status_notification_summary: DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY.to_string(),
status_notification_timeout: DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT,
lyrics_notification_summary: Some(DEFAULT_LYRICS_NOTIFICATION_SUMMARY.to_string()),
status_notification_body: Some(DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY.to_string()),
status_notification_summary: Some(
DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY.to_string(),
),
status_notification_timeout: Some(DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT),
}
}
}
@ -310,7 +315,7 @@ impl Settings {
#[cfg(feature = "debug")]
info!("Loading config and parsing args...");
// load config file
let cfg: Self = match confy::load("cmus-notify", "config") {
let mut cfg: Self = match confy::load("cmus-notify", "config") {
Ok(cfg) => cfg,
Err(err) => {
eprintln!("Failed to load config: {}", err);
@ -325,7 +330,7 @@ impl Settings {
}
// parse the args
let mut args = Settings::parse();
let args = Settings::parse();
#[cfg(feature = "debug")]
{
@ -334,178 +339,238 @@ impl Settings {
}
// Combine the config and args(the args will override the config)
if args.timeout == NOTIFICATION_TIMEOUT {
#[cfg(feature = "debug")]
debug!(
"The user not override the timeout, using the config's timeout. timeout: {}",
cfg.timeout
);
args.timeout = cfg.timeout;
}
if args.persistent == false {
#[cfg(feature = "debug")]
debug!("The user not override the persistent, using the config's persistent. persistent: {}", cfg.persistent);
args.persistent = cfg.persistent;
}
if args.show_track_cover == true {
#[cfg(feature = "debug")]
debug!("The user not override the show_track_cover, using the config's show_track_cover. show_track_cover: {}", cfg.show_track_cover);
args.show_track_cover = cfg.show_track_cover;
}
args.notification_static_icon = args
cfg.timeout = args.timeout.or(cfg.timeout);
cfg.persistent = args.persistent || cfg.persistent;
cfg.show_track_cover = args.show_track_cover || cfg.show_track_cover;
cfg.notification_static_icon = args
.notification_static_icon
.or(cfg.notification_static_icon);
args.cover_path = args.cover_path.or(cfg.cover_path);
cfg.cover_path = args.cover_path.or(cfg.cover_path);
#[cfg(feature = "lyrics")]
if args.lyrics_path == None {
if args.lyrics_path != None {
#[cfg(feature = "debug")]
debug!("The user not override the lyrics_path, using the config's lyrics_path. lyrics_path: {:?}", cfg.lyrics_path);
args.lyrics_path = cfg.lyrics_path;
cfg.lyrics_path = args.lyrics_path;
}
if args.depth == DEFAULT_MAX_DEPTH {
#[cfg(feature = "debug")]
debug!(
"The user not override the depth, using the config's depth. depth: {}",
cfg.depth
);
args.depth = cfg.depth;
}
if args.app_name == NOTIFICATION_APP_NAME {
#[cfg(feature = "debug")]
debug!(
"The user not override the app_name, using the config's app_name. app_name: {}",
cfg.app_name
);
args.app_name = cfg.app_name;
}
if args.summary == NOTIFICATION_SUMMARY {
#[cfg(feature = "debug")]
debug!(
"The user not override the summary, using the config's summary. summary: {}",
cfg.summary
);
args.summary = cfg.summary;
}
if args.body == NOTIFICATION_BODY {
#[cfg(feature = "debug")]
debug!(
"The user not override the body, using the config's body. body: {}",
cfg.body
);
args.body = cfg.body;
}
args.cmus_remote_bin_path = args.cmus_remote_bin_path.or(cfg.cmus_remote_bin_path);
args.cmus_socket_address = args.cmus_socket_address.or(cfg.cmus_socket_address);
args.cmus_socket_password = args.cmus_socket_password.or(cfg.cmus_socket_password);
if args.interval == DEFAULT_INTERVAL_TIME {
#[cfg(feature = "debug")]
debug!(
"The user not override the interval, using the config's interval. interval: {}",
cfg.interval
);
args.interval = cfg.interval;
}
if args.link == false {
#[cfg(feature = "debug")]
debug!(
"The user not override the link, using the config's link. link: {}",
cfg.link
);
args.link = cfg.link;
}
if args.force_use_external_cover == false {
#[cfg(feature = "debug")]
debug!("The user not override the force_use_external_cover, using the config's force_use_external_cover. force_use_external_cover: {}", cfg.force_use_external_cover);
args.force_use_external_cover = cfg.force_use_external_cover;
}
cfg.depth = args.depth.or(cfg.depth);
cfg.app_name = args.app_name.or(cfg.app_name);
cfg.summary = args.summary.or(cfg.summary);
cfg.body = args.body.or(cfg.body);
cfg.cmus_remote_bin_path = args.cmus_remote_bin_path.or(cfg.cmus_remote_bin_path);
cfg.cmus_socket_address = args.cmus_socket_address.or(cfg.cmus_socket_address);
cfg.cmus_socket_password = args.cmus_socket_password.or(cfg.cmus_socket_password);
cfg.interval = args.interval.or(cfg.interval);
cfg.link = args.link || cfg.link;
cfg.force_use_external_cover =
args.force_use_external_cover || cfg.force_use_external_cover;
#[cfg(feature = "lyrics")]
if args.force_use_external_lyrics == false {
#[cfg(feature = "debug")]
debug!("The user not override the force_use_external_lyrics, using the config's force_use_external_lyrics. force_use_external_lyrics: {}", cfg.force_use_external_lyrics);
args.force_use_external_lyrics = cfg.force_use_external_lyrics;
}
if args.no_use_external_cover == false {
#[cfg(feature = "debug")]
debug!("The user not override the no_use_external_cover, using the config's no_use_external_cover. no_use_external_cover: {}", cfg.no_use_external_cover);
args.no_use_external_cover = cfg.no_use_external_cover;
}
#[cfg(feature = "lyrics")]
if args.no_use_external_lyrics == false {
#[cfg(feature = "debug")]
debug!("The user not override the no_use_external_lyrics, using the config's no_use_external_lyrics. no_use_external_lyrics: {}", cfg.no_use_external_lyrics);
args.no_use_external_lyrics = cfg.no_use_external_lyrics;
}
if args.show_player_notifications == false {
#[cfg(feature = "debug")]
debug!("The user not override the show_player_notifications, using the config's show_player_notifications. show_player_notifications: {}", cfg.show_player_notifications);
args.show_player_notifications = cfg.show_player_notifications;
}
if args.volume_notification_body == DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY {
#[cfg(feature = "debug")]
debug!("The user not override the volume_notification_body, using the config's volume_notification_body. volume_notification_body: {}", cfg.volume_notification_body);
args.volume_notification_body = cfg.volume_notification_body;
}
if args.volume_notification_summary == DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY {
#[cfg(feature = "debug")]
debug!("The user not override the volume_notification_summary, using the config's volume_notification_summary. volume_notification_summary: {}", cfg.volume_notification_summary);
args.volume_notification_summary = cfg.volume_notification_summary;
}
if args.volume_notification_timeout == DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT {
#[cfg(feature = "debug")]
debug!("The user not override the volume_notification_timeout, using the config's volume_notification_timeout. volume_notification_timeout: {}", cfg.volume_notification_timeout);
args.volume_notification_timeout = cfg.volume_notification_timeout;
}
if args.shuffle_notification_body == DEFAULT_SHUFFLE_NOTIFICATION_BODY {
#[cfg(feature = "debug")]
debug!("The user not override the shuffle_notification_body, using the config's shuffle_notification_body. shuffle_notification_body: {}", cfg.shuffle_notification_body);
args.shuffle_notification_body = cfg.shuffle_notification_body;
}
if args.shuffle_notification_summary == DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY {
#[cfg(feature = "debug")]
debug!("The user not override the shuffle_notification_summary, using the config's shuffle_notification_summary. shuffle_notification_summary: {}", cfg.shuffle_notification_summary);
args.shuffle_notification_summary = cfg.shuffle_notification_summary;
}
if args.shuffle_notification_timeout == DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT {
#[cfg(feature = "debug")]
debug!("The user not override the shuffle_notification_timeout, using the config's shuffle_notification_timeout. shuffle_notification_timeout: {}", cfg.shuffle_notification_timeout);
args.shuffle_notification_timeout = cfg.shuffle_notification_timeout;
}
if args.repeat_notification_body == DEFAULT_REPEAT_NOTIFICATION_BODY {
#[cfg(feature = "debug")]
debug!("The user not override the repeat_notification_body, using the config's repeat_notification_body. repeat_notification_body: {}", cfg.repeat_notification_body);
args.repeat_notification_body = cfg.repeat_notification_body;
}
if args.repeat_notification_summary == DEFAULT_REPEAT_NOTIFICATION_SUMMARY {
#[cfg(feature = "debug")]
debug!("The user not override the repeat_notification_summary, using the config's repeat_notification_summary. repeat_notification_summary: {}", cfg.repeat_notification_summary);
args.repeat_notification_summary = cfg.repeat_notification_summary;
}
if args.repeat_notification_timeout == DEFAULT_REPEAT_NOTIFICATION_TIMEOUT {
#[cfg(feature = "debug")]
debug!("The user not override the repeat_notification_timeout, using the config's repeat_notification_timeout. repeat_notification_timeout: {}", cfg.repeat_notification_timeout);
args.repeat_notification_timeout = cfg.repeat_notification_timeout;
}
if args.aaa_mode_notification_body == DEFAULT_AAAMODE_NOTIFICATION_BODY {
#[cfg(feature = "debug")]
debug!("The user not override the aaa_mode_notification_body, using the config's aaa_mode_notification_body. aaa_mode_notification_body: {}", cfg.aaa_mode_notification_body);
args.aaa_mode_notification_body = cfg.aaa_mode_notification_body;
}
if args.aaa_mode_notification_summary == DEFAULT_AAAMODE_NOTIFICATION_SUMMARY {
#[cfg(feature = "debug")]
debug!("The user not override the aaa_mode_notification_summary, using the config's aaa_mode_notification_summary. aaa_mode_notification_summary: {}", cfg.aaa_mode_notification_summary);
args.aaa_mode_notification_summary = cfg.aaa_mode_notification_summary;
}
if args.aaa_mode_notification_timeout == DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT {
#[cfg(feature = "debug")]
debug!("The user not override the aaa_mode_notification_timeout, using the config's aaa_mode_notification_timeout. aaa_mode_notification_timeout: {}", cfg.aaa_mode_notification_timeout);
args.aaa_mode_notification_timeout = cfg.aaa_mode_notification_timeout;
{
cfg.force_use_external_lyrics =
args.force_use_external_lyrics || cfg.force_use_external_lyrics;
cfg.no_use_external_lyrics = args.no_use_external_lyrics || cfg.no_use_external_lyrics;
}
cfg.no_use_external_cover = args.no_use_external_cover || cfg.no_use_external_cover;
cfg.show_player_notifications =
args.show_player_notifications || cfg.show_player_notifications;
cfg.volume_notification_body = args
.volume_notification_body
.or(cfg.volume_notification_body);
cfg.volume_notification_summary = args
.volume_notification_summary
.or(cfg.volume_notification_summary);
cfg.volume_notification_timeout = args
.volume_notification_timeout
.or(cfg.volume_notification_timeout);
cfg.shuffle_notification_body = args
.shuffle_notification_body
.or(cfg.shuffle_notification_body);
cfg.shuffle_notification_summary = args
.shuffle_notification_summary
.or(cfg.shuffle_notification_summary);
cfg.shuffle_notification_timeout = args
.shuffle_notification_timeout
.or(cfg.shuffle_notification_timeout);
cfg.repeat_notification_body = args
.repeat_notification_body
.or(cfg.repeat_notification_body);
cfg.repeat_notification_summary = args
.repeat_notification_summary
.or(cfg.repeat_notification_summary);
cfg.repeat_notification_timeout = args
.repeat_notification_timeout
.or(cfg.repeat_notification_timeout);
cfg.aaa_mode_notification_body = args
.aaa_mode_notification_body
.or(cfg.aaa_mode_notification_body);
cfg.aaa_mode_notification_summary = args
.aaa_mode_notification_summary
.or(cfg.aaa_mode_notification_summary);
cfg.aaa_mode_notification_timeout = args
.aaa_mode_notification_timeout
.or(cfg.aaa_mode_notification_timeout);
#[cfg(feature = "debug")]
info!("The final settings: {:?}", args);
info!("The final settings: {:?}", cfg);
args
cfg
}
#[inline(always)]
pub fn timeout(&self) -> u8 {
self.timeout.unwrap_or(NOTIFICATION_TIMEOUT)
}
#[inline(always)]
pub fn app_name(&self) -> String {
self.app_name
.as_ref()
.unwrap_or(&NOTIFICATION_APP_NAME.to_string())
.to_string()
}
#[inline(always)]
pub fn interval(&self) -> u64 {
self.interval.unwrap_or(DEFAULT_INTERVAL_TIME)
}
#[inline(always)]
pub fn depth(&self) -> u8 {
self.depth.unwrap_or(DEFAULT_MAX_DEPTH)
}
#[inline(always)]
pub fn remote_bin_path(&self) -> String {
self.cmus_remote_bin_path
.as_ref()
.unwrap_or(&DEFAULT_REMOTE_COMMAND.to_string())
.to_string()
}
#[inline(always)]
pub fn status_notification_summary(&self) -> String {
self.status_notification_summary
.as_ref()
.unwrap_or(&DEFAULT_STATUS_CHANGE_NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn status_notification_body(&self) -> String {
self.status_notification_body
.as_ref()
.unwrap_or(&DEFAULT_STATUS_CHANGE_NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn status_notification_timeout(&self) -> u8 {
self.status_notification_timeout
.unwrap_or(DEFAULT_STATUS_CHANGE_NOTIFICATION_TIMEOUT)
}
#[inline(always)]
pub fn summary(&self) -> String {
self.summary
.as_ref()
.unwrap_or(&NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn body(&self) -> String {
self.body
.as_ref()
.unwrap_or(&NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn volume_notification_summary(&self) -> String {
self.volume_notification_summary
.as_ref()
.unwrap_or(&DEFAULT_VOLUME_CHANGE_NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn volume_notification_body(&self) -> String {
self.volume_notification_body
.as_ref()
.unwrap_or(&DEFAULT_VOLUME_CHANGE_NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn volume_notification_timeout(&self) -> u8 {
self.volume_notification_timeout
.unwrap_or(DEFAULT_VOLUME_CHANGE_NOTIFICATION_TIMEOUT)
}
#[inline(always)]
pub fn shuffle_notification_summary(&self) -> String {
self.shuffle_notification_summary
.as_ref()
.unwrap_or(&DEFAULT_SHUFFLE_NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn shuffle_notification_body(&self) -> String {
self.shuffle_notification_body
.as_ref()
.unwrap_or(&DEFAULT_SHUFFLE_NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn shuffle_notification_timeout(&self) -> u8 {
self.shuffle_notification_timeout
.unwrap_or(DEFAULT_SHUFFLE_NOTIFICATION_TIMEOUT)
}
#[inline(always)]
pub fn repeat_notification_summary(&self) -> String {
self.repeat_notification_summary
.as_ref()
.unwrap_or(&DEFAULT_REPEAT_NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn repeat_notification_body(&self) -> String {
self.repeat_notification_body
.as_ref()
.unwrap_or(&DEFAULT_REPEAT_NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn repeat_notification_timeout(&self) -> u8 {
self.repeat_notification_timeout
.unwrap_or(DEFAULT_REPEAT_NOTIFICATION_TIMEOUT)
}
#[inline(always)]
pub fn aaa_mode_notification_summary(&self) -> String {
self.aaa_mode_notification_summary
.as_ref()
.unwrap_or(&DEFAULT_AAAMODE_NOTIFICATION_SUMMARY.to_string())
.to_string()
}
#[inline(always)]
pub fn aaa_mode_notification_body(&self) -> String {
self.aaa_mode_notification_body
.as_ref()
.unwrap_or(&DEFAULT_AAAMODE_NOTIFICATION_BODY.to_string())
.to_string()
}
#[inline(always)]
pub fn aaa_mode_notification_timeout(&self) -> u8 {
self.aaa_mode_notification_timeout
.unwrap_or(DEFAULT_AAAMODE_NOTIFICATION_TIMEOUT)
}
}