continue n-th last activity

This commit is contained in:
Nikolas Schmidt-Voigt 2021-09-22 17:11:05 +02:00
parent f7d7aa8114
commit 72ac747ec2
5 changed files with 94 additions and 47 deletions

View file

@ -29,12 +29,12 @@ pub fn list(file_name: &str, filter: getter::ActivityFilter, do_group_activities
if do_group_activities {
list::list_activities_grouped_by_date(
&filtered_activities[first_element..filtered_activities.len()],
&filtered_activities[first_element..],
);
} else {
let with_start_dates = !filter.date.is_some();
list::list_activities(
&filtered_activities[first_element..filtered_activities.len()],
&filtered_activities[first_element..],
with_start_dates,
);
}
@ -61,11 +61,13 @@ pub fn list_projects(file_name: &str) -> Result<()> {
}
// return last finished activity
pub fn display_last_activity(file_name: &str) -> Result<()> {
pub fn list_last_activities(file_name: &str, number: usize) -> Result<()> {
let file_content = bartib_file::get_file_content(file_name)?;
let descriptions_and_projects : Vec<(&String, &String)> = getter::get_descriptions_and_projects(&file_content).into_iter().collect();
list::list_descriptions_and_projects(&descriptions_and_projects[..]);
let descriptions_and_projects : Vec<(&String, &String)> = getter::get_descriptions_and_projects(&file_content);
let first_element = descriptions_and_projects.len().saturating_sub(number);
list::list_descriptions_and_projects(&descriptions_and_projects[first_element..]);
Ok(())
}

View file

@ -67,24 +67,33 @@ pub fn continue_last_activity(
project_name: Option<&str>,
activity_description: Option<&str>,
time: Option<NaiveDateTime>,
number: usize
) -> Result<()> {
let mut file_content = bartib_file::get_file_content(file_name)?;
let optional_last_activity =
getter::get_last_activity_by_start(&file_content).or(getter::get_last_activity_by_end(&file_content));
let descriptions_and_projects : Vec<(&String, &String)> = getter::get_descriptions_and_projects(&file_content);
if let Some(last_activity) = optional_last_activity {
if descriptions_and_projects.is_empty() {
bail!("No activity has been started before.")
}
if number > descriptions_and_projects.len() {
bail!(format!("Less than {} distinct activities have been logged yet", number));
}
let i = descriptions_and_projects.len().saturating_sub(number).saturating_sub(1);
let optional_description_and_project = descriptions_and_projects.get(i);
if let Some((description, project)) = optional_description_and_project {
let new_activity = activity::Activity::start(
project_name.unwrap_or(&last_activity.project).to_string(),
activity_description
.unwrap_or(&last_activity.description)
.to_string(),
project_name.unwrap_or(project).to_string(),
activity_description.unwrap_or(description).to_string(),
time,
);
stop_all_running_activities(&mut file_content, time);
save_new_activity(file_name, &mut file_content, new_activity)
} else {
bail!("No activity has been started before.")
bail!(format!("Less than {} distinct activities have been logged yet", number));
}
}

View file

@ -1,4 +1,4 @@
use std::collections::{HashSet, VecDeque};
use std::collections::HashSet;
use chrono::{naive, NaiveDate};
use crate::data::activity;
@ -11,17 +11,19 @@ pub struct ActivityFilter {
pub date: Option<NaiveDate>,
}
pub fn get_descriptions_and_projects(file_content: &[bartib_file::Line]) -> VecDeque<(&String, &String)> {
let mut known_descriptions_and_projects : HashSet<(&String, &String)> = HashSet::new();
let mut descriptions_and_projects : VecDeque<(&String, &String)> = VecDeque::new();
pub fn get_descriptions_and_projects(file_content: &[bartib_file::Line]) -> Vec<(&String, &String)> {
let mut activities : Vec<&activity::Activity> = get_activities(file_content).collect();
activities.sort_by_key(|activity| activity.start);
activities.reverse();
let mut known_descriptions_and_projects : HashSet<(&String, &String)> = HashSet::new();
let mut descriptions_and_projects : Vec<(&String, &String)> = Vec::new();
// TODO: sortierung nach Start-Zeit
for description_and_project in get_activities(file_content).map(|a| (&a.description, &a.project)) {
if !known_descriptions_and_projects.contains(&description_and_project) {
known_descriptions_and_projects.insert(description_and_project);
descriptions_and_projects.push_back(description_and_project);
descriptions_and_projects.push(description_and_project);
}
}
descriptions_and_projects

View file

@ -105,6 +105,16 @@ fn main() -> Result<()> {
.help("a description of the new activity")
.takes_value(true),
)
.arg(
Arg::with_name("number")
.short("n")
.long("number")
.value_name("NUMBER")
.help("maximum number of activities to display")
.required(false)
.takes_value(true)
.default_value("0")
)
.arg(&arg_time),
)
.subcommand(
@ -147,7 +157,20 @@ fn main() -> Result<()> {
.arg(&arg_today)
.arg(&arg_yesterday),
)
.subcommand(SubCommand::with_name("last").about("displays last finished acitivity"))
.subcommand(
SubCommand::with_name("last")
.about("displays last finished acitivity")
.arg(
Arg::with_name("number")
.short("n")
.long("number")
.value_name("NUMBER")
.help("maximum number of activities to display")
.required(false)
.takes_value(true)
.default_value("10")
)
)
.subcommand(SubCommand::with_name("projects").about("list all projects"))
.subcommand(
SubCommand::with_name("edit")
@ -184,8 +207,12 @@ fn run_subcommand(matches: &ArgMatches, file_name: &str) -> Result<()> {
let activity_description = sub_m.value_of("description");
let time = get_time_argument_or_ignore(sub_m.value_of("time"), "-t/--time")
.map(|t| Local::today().naive_local().and_time(t));
let number = get_number_argument_or_ignore(
sub_m.value_of("number"),
"-n/--number",
).unwrap_or(0);
bartib::controller::manipulation::continue_last_activity(file_name, project_name, activity_description, time)
bartib::controller::manipulation::continue_last_activity(file_name, project_name, activity_description, time, number)
}
("stop", Some(sub_m)) => {
let time = get_time_argument_or_ignore(sub_m.value_of("time"), "-t/--time")
@ -195,25 +222,6 @@ fn run_subcommand(matches: &ArgMatches, file_name: &str) -> Result<()> {
}
("current", Some(_)) => bartib::controller::list::list_running(file_name),
("list", Some(sub_m)) => {
let mut filter = bartib::data::getter::ActivityFilter {
number_of_activities: None,
from_date: get_date_argument_or_ignore(sub_m.value_of("from_date"), "--from"),
to_date: get_date_argument_or_ignore(sub_m.value_of("to_date"), "--to"),
date: get_date_argument_or_ignore(sub_m.value_of("date"), "-d/--date"),
};
if sub_m.is_present("today") {
filter.date = Some(Local::now().naive_local().date());
}
if sub_m.is_present("yesterday") {
filter.date = Some(Local::now().naive_local().date() - Duration::days(1));
}
let do_group_activities = !sub_m.is_present("no_grouping") && !filter.date.is_some();
bartib::controller::list::list(file_name, filter, do_group_activities)
}
("report", Some(sub_m)) => {
let mut filter = bartib::data::getter::ActivityFilter {
number_of_activities: get_number_argument_or_ignore(
sub_m.value_of("number"),
@ -232,10 +240,35 @@ fn run_subcommand(matches: &ArgMatches, file_name: &str) -> Result<()> {
filter.date = Some(Local::now().naive_local().date() - Duration::days(1));
}
let do_group_activities = !sub_m.is_present("no_grouping") && !filter.date.is_some();
bartib::controller::list::list(file_name, filter, do_group_activities)
}
("report", Some(sub_m)) => {
let mut filter = bartib::data::getter::ActivityFilter {
number_of_activities: None,
from_date: get_date_argument_or_ignore(sub_m.value_of("from_date"), "--from"),
to_date: get_date_argument_or_ignore(sub_m.value_of("to_date"), "--to"),
date: get_date_argument_or_ignore(sub_m.value_of("date"), "-d/--date"),
};
if sub_m.is_present("today") {
filter.date = Some(Local::now().naive_local().date());
}
if sub_m.is_present("yesterday") {
filter.date = Some(Local::now().naive_local().date() - Duration::days(1));
}
bartib::controller::report::show_report(file_name, filter)
}
("projects", Some(_)) => bartib::controller::list::list_projects(file_name),
("last", Some(_)) => bartib::controller::list::display_last_activity(file_name),
("projects", Some(_)) => bartib::controller::list::list_projects(file_name),
("last", Some(sub_m)) => {
let number = get_number_argument_or_ignore(
sub_m.value_of("number"),
"-n/--number",
).unwrap_or(10);
bartib::controller::list::list_last_activities(file_name, number)
}
("edit", Some(sub_m)) => {
let optional_editor_command = sub_m.value_of("editor");
bartib::controller::manipulation::start_editor(file_name, optional_editor_command)

View file

@ -97,18 +97,19 @@ pub fn list_descriptions_and_projects(descriptions_and_projects : &[(&String, &S
println!("No activities have been tracked yet");
} else {
let mut descriptions_and_projects_table = table::Table::new(vec![
"Index".to_string(),
"#".to_string(),
"Description".to_string(),
"Project".to_string()
]);
let mut i = 0;
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![i.to_string(), description.to_string(), project.to_string()])
table::Row::new(vec![format!("[{}]", i), description.to_string(), project.to_string()])
);
i += 1;
}
println!("\n{}", descriptions_and_projects_table);