// // imag - the personal information management suite for the commandline // Copyright (C) 2015-2019 Matthias Beyer and contributors // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; version // 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // use std::env; use std::process::Command; use filters::filter::Filter; use failure::Fallible as Result; use failure::err_msg; use failure::Error; use resiter::Filter as RFilter; use resiter::AndThen; use libimagrt::runtime::Runtime; use libimagtimetrack::iter::filter::has_one_of_tags; use libimagtimetrack::store::TimeTrackStore; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetracking::TimeTracking; pub fn shell(rt: &Runtime) -> Result<()> { let (_, cmd) = rt.cli().subcommand(); let cmd = cmd.unwrap(); // checked in main() let start = ::chrono::offset::Local::now().naive_local(); let tags = cmd.values_of("tags") .unwrap() // enforced by clap .map(String::from) .map(TimeTrackingTag::from) .collect::>(); let mut shellcmd = { let mkshell = |s: String| { let mut cmd = Command::new(s); cmd.stdin(::std::process::Stdio::inherit()); cmd.stdout(::std::process::Stdio::inherit()); cmd.stderr(::std::process::Stdio::inherit()); cmd }; if let Some(s) = cmd.value_of("shell") { Ok(mkshell(s.to_owned())) } else { env::var("SHELL") .map(mkshell) .map_err(|e| match e { env::VarError::NotPresent => { err_msg("No $SHELL variable in environment, cannot work!") }, env::VarError::NotUnicode(_) => { err_msg("SHELL variable is not unicode, cannot work!") } }) } }?; for tag in tags.iter() { let entry = rt.store().create_timetracking_at(&start, tag)?; rt.report_touched(entry.get_location())?; } if !shellcmd.status()?.success() { return Err(format_err!("Failed to execute {:?}", shellcmd)) } let stop = ::chrono::offset::Local::now().naive_local(); let filter = has_one_of_tags(&tags); rt.store() .get_timetrackings()? .filter_ok(|e| filter.filter(e)) .and_then_ok(|mut elem| { let _ = elem.set_end_datetime(stop.clone())?; debug!("Setting end time worked: {:?}", elem); rt.report_touched(elem.get_location()).map_err(Error::from) }) .collect::>>() .map(|_| ()) }