use std::process; use anyhow::{bail, Context, Result}; use log::{error, info}; use crate::{cli::OpenCommand, rofi, task}; pub fn handle(command: OpenCommand) -> Result<()> { match command { OpenCommand::Review => { for project in task::Project::all()? { if project.is_touched() { info!("Reviewing project: '{}'", project.to_project_display()); open_in_browser(project).with_context(|| { format!( "Failed to open project ('{}') in Firefox", project.to_project_display() ) })?; project.untouch().with_context(|| { format!( "Failed to untouch project ('{}')", project.to_project_display() ) })?; } } } OpenCommand::Project { project } => { let project = if let Some(p) = project { p } else if let Some(p) = task::Project::get_current()? { p } else { bail!("You need to either supply a project or have a project active!"); }; project.touch().context("Failed to touch project")?; open_in_browser(&project).context("Failed to open project")?; } OpenCommand::Select => { let selected_project: task::Project = task::Project::from_project_string( &rofi::select( task::Project::all() .context("Failed to get all registered projects")? .iter() .map(task::Project::to_project_display) .collect::>() .as_slice(), ) .context("Failed to get selected project")?, ) .expect("This should work, as we send only projects in"); selected_project .touch() .context("Failed to touch project")?; open_in_browser(&selected_project).context("Failed to open project")?; } } Ok(()) } fn open_in_browser(selected_project: &task::Project) -> Result<()> { let old_project: Option = task::Project::get_current().context("Failed to get currently active project")?; // We have ensured that only one task may be active let old_task: Option = task::Id::get_current().context("Failed to get currently active task")?; selected_project.activate().with_context(|| { format!( "Failed to active project: '{}'", selected_project.to_project_display() ) })?; let tracking_task = { let all_tasks = selected_project.get_tasks().with_context(|| { format!( "Failed to get assoctiated tasks for project: '{}'", selected_project.to_project_display() ) })?; let tracking_task = all_tasks.into_iter().find(|t| { let maybe_desc = t.description(); if let Ok(desc) = maybe_desc { desc == "tracking" } else { error!( "Getting task description returned error: {}", maybe_desc.expect_err("We already check for Ok") ); false } }); if let Some(task) = tracking_task { info!( "Starting task {} -> tracking", selected_project.to_project_display() ); task.start()?; } tracking_task }; let status = process::Command::new("firefox") .args([ "-P", selected_project.to_project_display().as_str(), "about:newtab", ]) .status() .context("Failed to start firefox")?; if !status.success() { error!("Firefox run exited with error."); } if let Some(task) = tracking_task { task.stop()?; } if let Some(task) = old_task { task.start()?; } if let Some(project) = old_project { project.activate()?; } else { task::Project::clear()?; } Ok(()) }