feat: implement search command

This commit is contained in:
Pyxels 2024-05-07 16:07:36 +02:00 committed by Nikolas Schmidt-Voigt
parent 8bbcbfdde0
commit d248292920
4 changed files with 82 additions and 31 deletions

View file

@ -282,6 +282,8 @@ bartib list --date 2021-09-03 # list activities on a given day
bartib list --from 2021-09-01 --to 2021-09-05 # list activities in a given time range
bartib list --project "The most exciting project" # list activities for a given project
bartib list --round 15m # rounds the start and end time to the nearest duration. Durations can be in minutes or hours. E.g. 15m or 4h
bartib search # search all descriptions and projects for a specific term
```
### Edit activities

View file

@ -197,3 +197,26 @@ pub fn list_last_activities(file_name: &str, number: usize) -> Result<()> {
Ok(())
}
// searches for the term in descriptions and projects
pub fn search(file_name: &str, search_term: Option<&str>) -> Result<()> {
let search_term = search_term.unwrap_or("");
let file_content = bartib_file::get_file_content(file_name)?;
let descriptions_and_projects: Vec<(&String, &String)> =
getter::get_descriptions_and_projects(&file_content);
let matches: Vec<(usize, &(&String, &String))> = descriptions_and_projects
.iter()
.rev()
.enumerate()
.rev()
.filter(|(_index, (desc, proj))| {
desc.to_lowercase().contains(&search_term.to_lowercase())
|| proj.to_lowercase().contains(&search_term.to_lowercase())
})
.collect();
list::list_descriptions_and_projects_with_index(&matches, "No matching activities found");
Ok(())
}

View file

@ -260,6 +260,16 @@ To get started, view the `start` help with `bartib start --help`")
)
.subcommand(SubCommand::with_name("check").about("checks file and reports parsing errors"))
.subcommand(SubCommand::with_name("sanity").about("checks sanity of bartib log"))
.subcommand(SubCommand::with_name("search").about("search for existing descriptions and projects")
.arg(
Arg::with_name("search_term")
.value_name("SEARCH_TERM")
.help("the search term")
.required(false)
.takes_value(true)
.default_value("''"),
),
)
.subcommand(
SubCommand::with_name("status")
.about("shows current status and time reports for today, current week, and current month")
@ -360,6 +370,10 @@ fn run_subcommand(matches: &ArgMatches, file_name: &str) -> Result<()> {
}
("check", Some(_)) => bartib::controller::list::check(file_name),
("sanity", Some(_)) => bartib::controller::list::sanity_check(file_name),
("search", Some(sub_m)) => {
let search_term = sub_m.value_of("search_term");
bartib::controller::list::search(file_name, search_term)
}
("status", Some(sub_m)) => {
let filter = create_filter_for_arguments(sub_m);
let processors = create_processors_for_arguments(sub_m);

View file

@ -116,40 +116,52 @@ pub fn list_running_activities(activities: &[&activity::Activity]) {
}
}
// display a list of projects and descriptions with index number
// display a list of projects and descriptions with generated index number
pub fn list_descriptions_and_projects(descriptions_and_projects: &[(&String, &String)]) {
list_descriptions_and_projects_with_index(
&descriptions_and_projects
.iter()
.rev()
.enumerate()
.rev()
.collect::<Vec<_>>(),
"No activities have been tracked yet",
)
}
// display a list of projects ands descriptions with custom indexes
pub fn list_descriptions_and_projects_with_index(
descriptions_and_projects: &[(usize, &(&String, &String))],
zero_length_error: &str,
) {
if descriptions_and_projects.is_empty() {
println!("No activities have been tracked yet");
} else {
let mut descriptions_and_projects_table = table::Table::new(vec![
table::Column {
label: " # ".to_string(),
wrap: table::Wrap::NoWrap,
},
table::Column {
label: "Description".to_string(),
wrap: table::Wrap::Wrap,
},
table::Column {
label: "Project".to_string(),
wrap: table::Wrap::Wrap,
},
]);
let mut i = descriptions_and_projects.len();
for (description, project) in descriptions_and_projects {
i = i.saturating_sub(1);
descriptions_and_projects_table.add_row(table::Row::new(vec![
format!("[{}]", i),
(*description).to_string(),
(*project).to_string(),
]));
}
println!("\n{descriptions_and_projects_table}");
println!("{zero_length_error}");
return;
}
let mut descriptions_and_projects_table = table::Table::new(vec![
table::Column {
label: " # ".to_string(),
wrap: table::Wrap::NoWrap,
},
table::Column {
label: "Description".to_string(),
wrap: table::Wrap::Wrap,
},
table::Column {
label: "Project".to_string(),
wrap: table::Wrap::Wrap,
},
]);
for (index, (description, project)) in descriptions_and_projects {
descriptions_and_projects_table.add_row(table::Row::new(vec![
format!("[{}]", index),
(*description).to_string(),
(*project).to_string(),
]));
}
println!("\n{descriptions_and_projects_table}");
}
// create a row for a activity