Update the day reporter to use lists instead of report types
This commit is contained in:
parent
154793ccbe
commit
9d62d4d555
4 changed files with 19 additions and 81 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -173,7 +173,7 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "day-reporter"
|
name = "day-reporter"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
||||||
50
src/main.rs
50
src/main.rs
|
|
@ -5,32 +5,31 @@ mod names;
|
||||||
|
|
||||||
use reporter::{MarkdownReporter, Reporter, Resolution, ReportOptions};
|
use reporter::{MarkdownReporter, Reporter, Resolution, ReportOptions};
|
||||||
|
|
||||||
use things::task::{Task, Status};
|
use things::task::Task;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
|
|
||||||
#[derive(ValueEnum, Copy, Clone, Eq, PartialEq)]
|
#[derive(ValueEnum, Copy, Clone, Eq, PartialEq)]
|
||||||
enum ReportTypes {
|
enum ListType {
|
||||||
/// report projected work for the day and a morning message
|
/// Generate a report from the Things today list
|
||||||
Morning,
|
Today,
|
||||||
/// report what major tasks were completed in the last cycle.
|
/// Generate a report from the Things logbook
|
||||||
Cycle,
|
Logbook,
|
||||||
/// report what was actually done today and a signoff message
|
|
||||||
Signoff,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReportTypes {
|
impl ListType {
|
||||||
fn format_tasks(&self, tasks: Vec<Task>, tags: &Vec<String>, sanitize_names: bool) -> String {
|
fn format_tasks(&self, tasks: Vec<Task>, tags: &Vec<String>, sanitize_names: bool) -> String {
|
||||||
match self {
|
match self {
|
||||||
ReportTypes::Morning => {
|
ListType::Today => {
|
||||||
let task_report = MarkdownReporter.report(tasks, &ReportOptions {
|
let task_report = MarkdownReporter.report(tasks, &ReportOptions {
|
||||||
resolution: Resolution::FullTask,
|
resolution: Resolution::FullTask,
|
||||||
tags: tags.to_vec(),
|
tags: tags.to_vec(),
|
||||||
sanitize_names,
|
sanitize_names,
|
||||||
});
|
});
|
||||||
|
// TODO: Use a cli flag to determine if the emoji should be included.
|
||||||
format!("{}\n\n{}", emoji::pick(3).join(" "), task_report)
|
format!("{}\n\n{}", emoji::pick(3).join(" "), task_report)
|
||||||
},
|
},
|
||||||
ReportTypes::Signoff => {
|
ListType::Logbook => {
|
||||||
let task_report = MarkdownReporter.report(tasks, &ReportOptions {
|
let task_report = MarkdownReporter.report(tasks, &ReportOptions {
|
||||||
resolution: Resolution::FullTask,
|
resolution: Resolution::FullTask,
|
||||||
tags: tags.to_vec(),
|
tags: tags.to_vec(),
|
||||||
|
|
@ -38,27 +37,13 @@ impl ReportTypes {
|
||||||
});
|
});
|
||||||
format!("Stopping now\n\n{}", task_report)
|
format!("Stopping now\n\n{}", task_report)
|
||||||
},
|
},
|
||||||
ReportTypes::Cycle => {
|
|
||||||
let further_filtered = tasks.into_iter().filter(|t| {
|
|
||||||
if let Some(p) = &t.project {
|
|
||||||
return p.status == Status::Completed;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}).collect::<Vec<Task>>();
|
|
||||||
let task_report = MarkdownReporter.report(further_filtered, &ReportOptions {
|
|
||||||
resolution: Resolution::Project,
|
|
||||||
tags: tags.to_vec(),
|
|
||||||
sanitize_names,
|
|
||||||
});
|
|
||||||
format!("*Cycle Report*\n\n{}", task_report)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ReportTypes {
|
impl Default for ListType {
|
||||||
fn default() -> ReportTypes {
|
fn default() -> ListType {
|
||||||
ReportTypes::Morning
|
ListType::Today
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,9 +61,9 @@ struct CliArgs {
|
||||||
omit: Vec<String>,
|
omit: Vec<String>,
|
||||||
|
|
||||||
/// Select the type of report to generate
|
/// Select the type of report to generate
|
||||||
#[arg(short, long, default_value_t = ReportTypes::default())]
|
#[arg(short, long, default_value_t = ListType::default())]
|
||||||
#[clap(value_enum)]
|
#[clap(value_enum)]
|
||||||
report: ReportTypes,
|
report: ListType,
|
||||||
|
|
||||||
/// By default, any @<name> style tags will be sanitized in the output to avoid @-mentions in
|
/// By default, any @<name> style tags will be sanitized in the output to avoid @-mentions in
|
||||||
/// Slack. This is done by replacing vowel characters with unicode lookalikes. If this
|
/// Slack. This is done by replacing vowel characters with unicode lookalikes. If this
|
||||||
|
|
@ -90,9 +75,8 @@ struct CliArgs {
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let args = CliArgs::parse();
|
let args = CliArgs::parse();
|
||||||
let tasks = match args.report {
|
let tasks = match args.report {
|
||||||
ReportTypes::Morning => Task::today(),
|
ListType::Today => Task::today(),
|
||||||
ReportTypes::Signoff => Task::logbook_today(),
|
ListType::Logbook => Task::logbook(),
|
||||||
ReportTypes::Cycle => Task::logbook_this_cycle(),
|
|
||||||
}?;
|
}?;
|
||||||
let mut reported: Vec<Task> = tasks.into_iter().filter(|task| {
|
let mut reported: Vec<Task> = tasks.into_iter().filter(|task| {
|
||||||
// Filter down to tasks with all selected tags and without any of the omitted tags
|
// Filter down to tasks with all selected tags and without any of the omitted tags
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
var things = Application("Things");
|
|
||||||
var logbook = things.lists.byName("Logbook").toDos();
|
|
||||||
var objs = [];
|
|
||||||
|
|
||||||
// From 6 weeks ago
|
|
||||||
var from = new Date(new Date().getTime() - (6 * 7 * 24 * 60 * 60 * 1000));
|
|
||||||
from.setHours(0);
|
|
||||||
from.setMinutes(0);
|
|
||||||
from.setSeconds(0);
|
|
||||||
var to = new Date();
|
|
||||||
to.setHours(23);
|
|
||||||
to.setMinutes(59);
|
|
||||||
to.setSeconds(59);
|
|
||||||
|
|
||||||
logbook.filter(task => {
|
|
||||||
return task.completionDate() >= from && task.completionDate() < to;
|
|
||||||
}).forEach(todo => {
|
|
||||||
var proj = todo.project();
|
|
||||||
var tags = [];
|
|
||||||
if (proj) {
|
|
||||||
tags.push(...proj.tagNames().split(', '));
|
|
||||||
}
|
|
||||||
var area = todo.area() || proj && proj.area();
|
|
||||||
objs.push({
|
|
||||||
id: todo.id(),
|
|
||||||
title: todo.name(),
|
|
||||||
notes: todo.notes() || null,
|
|
||||||
status: todo.status(),
|
|
||||||
completion_date: todo.completionDate(),
|
|
||||||
project: proj && {
|
|
||||||
id: proj.id(),
|
|
||||||
title: proj.name(),
|
|
||||||
status: proj.status(),
|
|
||||||
notes: proj.notes(),
|
|
||||||
tags: proj.tagNames().split(', '),
|
|
||||||
},
|
|
||||||
area: area && { id: area.id(), title: area.name() },
|
|
||||||
tags: [...tags, ...todo.tagNames().split(', ')].filter(t => t),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return JSON.stringify(objs, undefined, 2);
|
|
||||||
|
|
@ -59,14 +59,10 @@ impl Task {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all tasks in the logbook list from Things
|
/// Get all tasks in the logbook list from Things
|
||||||
pub fn logbook_today() -> Result<Vec<Task>> {
|
pub fn logbook() -> Result<Vec<Task>> {
|
||||||
Task::from_script(include_bytes!("logbook.js"))
|
Task::from_script(include_bytes!("logbook.js"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logbook_this_cycle() -> Result<Vec<Task>> {
|
|
||||||
Task::from_script(include_bytes!("logbook_cycle.js"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_tag(&self, tag: &str) -> bool {
|
pub fn has_tag(&self, tag: &str) -> bool {
|
||||||
self.tags.contains(&String::from(tag))
|
self.tags.contains(&String::from(tag))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue