Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
},
"discord": {
"webhook_url": "your-webhook-url"
}
}
},
"work_time_default_value": 30,
"break_time_default_value": 10
}
24 changes: 16 additions & 8 deletions src/command/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn get_start_and_uds_client_command() -> Command {
.args_conflicts_with_subcommands(true)
.arg(
Arg::new("config")
.help("read credential json file from this path")
.help("Read configuration json file from this path")
.num_args(1)
.short('c')
.long("config"),
Expand Down Expand Up @@ -115,21 +115,29 @@ pub(crate) fn add_args_for_create_subcommand(command: Command) -> Command {
command
.arg(
Arg::new("work")
.help("The focus time. Unit is minutes")
.long_help("The focus time in minutes.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice description!

If no value is passed, the work time is obtained from `work_time_default_value` in the given configuration file.
And if no configuration file is passed or `work_time_default_value` is not present, then 25 is used as the work time.
")
.num_args(1)
.short('w')
.default_value("0"),
.short('w'),
)
.arg(
Arg::new("break")
.help("The break time, Unit is minutes")
.long_help("The break time in minutes.
If no value is passed, the break time is obtained from `break_time_default_value` in the given configuration file.
And if no configuration file is passed or `break_time_default_value` is not present, then 5 is used as the break time.
")
.num_args(1)
.short('b')
.default_value("0"),
.short('b'),
)
.arg(
Arg::new("default")
.help("The flag to create default notification, 25 mins work and 5 min break")
.long_help(
"The flag to create default notification.
The values are obtained from `work_time_default_value` and `break_time_default_value` in the given configuration file.
If no configuration file is passed or the keys are not present, then 25 minutes for work and 5 minutes for break is considered.
")
.conflicts_with("work")
.conflicts_with("break")
.short('d')
Expand Down
105 changes: 44 additions & 61 deletions src/command/handler/user_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,42 +100,30 @@ async fn handle_create(
id_manager: &mut u16,
output_accumulator: &mut OutputAccumulater,
) -> HandleUserInputResult {
let notification = get_new_notification(matches, id_manager, Utc::now())
let notification = get_new_notification(matches, id_manager, Utc::now(), configuration.clone())
.map_err(UserInputHandlerError::NotificationError)?;

match notification {
Some(notification) => {
let id = notification.get_id();
db::create_notification(glue.clone(), &notification).await;

let handle = spawn_notification(
configuration.clone(),
notification_task_map.clone(),
glue.clone(),
notification,
);

notification_task_map.lock().unwrap().insert(id, handle);
output_accumulator.push(
OutputType::Println,
format!(
"[{}] Notification (id: {}) created",
chrono::offset::Local::now(),
id
),
);

Ok(())
}
None => {
output_accumulator.push(
OutputType::Println,
String::from("work_time and break_time both can not be zero both"),
);
let id = notification.get_id();
db::create_notification(glue.clone(), &notification).await;

Ok(())
}
}
let handle = spawn_notification(
configuration.clone(),
notification_task_map.clone(),
glue.clone(),
notification,
);

notification_task_map.lock().unwrap().insert(id, handle);
output_accumulator.push(
OutputType::Println,
format!(
"[{}] Notification (id: {}) created",
chrono::offset::Local::now(),
id
),
);

Ok(())
}

async fn handle_queue(
Expand All @@ -156,35 +144,30 @@ async fn handle_queue(
None => Utc::now(),
};

let notification = get_new_notification(matches, id_manager, created_at)
let notification = get_new_notification(matches, id_manager, created_at, configuration.clone())
.map_err(UserInputHandlerError::NotificationError)?;
match notification {
Some(notification) => {
let id = notification.get_id();
db::create_notification(glue.clone(), &notification).await;

notification_task_map.lock().unwrap().insert(
id,
spawn_notification(
configuration.clone(),
notification_task_map.clone(),
glue.clone(),
notification,
),
);
output_accumulator.push(
OutputType::Println,
format!(
"[{}] Notification (id: {}) created and queued",
chrono::offset::Local::now(),
id
),
);

Ok(())
}
None => Ok(()),
}
let id = notification.get_id();
db::create_notification(glue.clone(), &notification).await;

notification_task_map.lock().unwrap().insert(
id,
spawn_notification(
configuration.clone(),
notification_task_map.clone(),
glue.clone(),
notification,
),
);
output_accumulator.push(
OutputType::Println,
format!(
"[{}] Notification (id: {}) created and queued",
chrono::offset::Local::now(),
id
),
);

Ok(())
}

async fn handle_delete(
Expand Down
40 changes: 32 additions & 8 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@ use crate::report::generate_configuration_report;

pub const SLACK_API_URL: &str = "https://slack.com/api/chat.postMessage";

#[derive(Deserialize, Debug, Default)]
#[derive(Deserialize, Debug, Default, Clone)]
pub struct Configuration {
#[serde(rename(deserialize = "slack"))]
slack_configuration: Option<SlackConfiguration>,
#[serde(rename(deserialize = "discord"))]
discord_configuration: Option<DiscordConfiguration>,
work_time_default_value: Option<u16>,
break_time_default_value: Option<u16>,
}

#[derive(Deserialize, Debug, Default)]
#[derive(Deserialize, Debug, Default, Clone)]
struct SlackConfiguration {
token: Option<String>,
channel: Option<String>,
}

#[derive(Deserialize, Debug, Default)]
#[derive(Deserialize, Debug, Default, Clone)]
struct DiscordConfiguration {
webhook_url: Option<String>,
}
Expand All @@ -52,22 +54,30 @@ impl Configuration {
None => &None,
}
}

pub fn get_work_time(&self) -> Option<u16> {
return self.work_time_default_value;
}

pub fn get_break_time(&self) -> Option<u16> {
return self.break_time_default_value;
}
}

pub fn get_configuration(matches: &ArgMatches) -> Result<Arc<Configuration>, ConfigurationError> {
let credential_file_path = matches.get_one::<String>("config").map(|s| s.as_str());
let configuration_file_path = matches.get_one::<String>("config").map(|s| s.as_str());

let (configuration, config_error) = load_configuration(credential_file_path)?;
let (configuration, config_error) = load_configuration(configuration_file_path)?;
let report = generate_configuration_report(&configuration, config_error);
info!("\nconfig flag result!\n{}", report);

Ok(Arc::new(configuration))
}

pub fn load_configuration(
credential_file: Option<&str>,
configuration_file: Option<&str>,
) -> Result<(Configuration, Option<ConfigurationError>), ConfigurationError> {
let (configuration, error) = match credential_file {
let (configuration, error) = match configuration_file {
Some(f) => {
let path = env::current_dir()
.map_err(ConfigurationError::LoadFail)?
Expand Down Expand Up @@ -108,7 +118,7 @@ mod tests {

#[test]
fn test_initialize_configuration_some() {
let file = PathBuf::from("resources/test/mock_credential.json");
let file = PathBuf::from("resources/test/mock_configuration.json");
let file = file.to_str();

let result = load_configuration(file);
Expand All @@ -126,6 +136,14 @@ mod tests {
let discord_webhook_url = config.get_discord_webhook_url();
assert_eq!(true, discord_webhook_url.is_some());
assert!(discord_webhook_url.as_ref().unwrap().eq("your-webhook-url"));

let work_time = config.get_work_time();
assert_eq!(true, work_time.is_some());
assert_eq!(work_time.unwrap(), 30);

let break_time = config.get_break_time();
assert_eq!(true, break_time.is_some());
assert_eq!(break_time.unwrap(), 10);
}

#[test]
Expand All @@ -145,6 +163,12 @@ mod tests {

let discord_webhook_url = config.get_discord_webhook_url();
assert_eq!(true, discord_webhook_url.is_none());

let work_time = config.get_work_time();
assert_eq!(true, work_time.is_none());

let break_time = config.get_break_time();
assert_eq!(true, break_time.is_none());
});
}
}
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum NotificationError {
EmptyConfiguration,
NewNotification(ParseError),
DeletionFail(String),
EmptyTimeValues,
}

impl fmt::Display for NotificationError {
Expand All @@ -38,6 +39,10 @@ impl fmt::Display for NotificationError {
write!(f, "failed to get new notification: {}", e)
}
NotificationError::DeletionFail(msg) => write!(f, "{}", msg),
NotificationError::EmptyTimeValues => write!(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice.

f,
"Cannot create a notification with 0 work time and 0 break time"
),
}
}
}
Expand All @@ -51,6 +56,7 @@ impl std::error::Error for NotificationError {
NotificationError::EmptyConfiguration => None,
NotificationError::NewNotification(ref e) => Some(e),
NotificationError::DeletionFail(_) => None,
NotificationError::EmptyTimeValues => None,
}
}
}
Expand Down
Loading