mirror of
https://github.com/nikolassv/bartib
synced 2025-02-26 03:47:09 +00:00
feat: implement search command
This commit is contained in:
parent
8bbcbfdde0
commit
d248292920
4 changed files with 82 additions and 31 deletions
|
@ -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
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue