2024-02-22 01:34:11 -05:00
|
|
|
mod cli;
|
2023-06-22 13:44:06 -04:00
|
|
|
mod config;
|
2024-03-04 14:58:30 -05:00
|
|
|
mod file;
|
2023-06-23 09:41:27 -04:00
|
|
|
mod todo;
|
2023-06-15 08:57:19 -04:00
|
|
|
|
2024-02-22 01:34:11 -05:00
|
|
|
use crate::cli::Args;
|
2024-02-28 17:20:55 -05:00
|
|
|
use crate::config::Config;
|
2024-03-18 20:17:38 -04:00
|
|
|
use crate::todo::{File as TodoFile, TaskGroup};
|
2023-06-12 23:46:40 -04:00
|
|
|
use chrono::naive::NaiveDate;
|
2024-03-18 20:17:38 -04:00
|
|
|
use chrono::{Datelike, Local, TimeDelta};
|
2024-03-04 14:58:30 -05:00
|
|
|
use clap::Parser;
|
|
|
|
|
use comrak::Arena;
|
2024-02-28 17:20:55 -05:00
|
|
|
use resolve_path::PathResolveExt;
|
2024-03-04 14:58:30 -05:00
|
|
|
use std::fs;
|
|
|
|
|
use std::path::Path;
|
2023-06-13 08:10:18 -04:00
|
|
|
use std::process::Command;
|
2023-06-12 23:46:40 -04:00
|
|
|
|
2024-02-28 17:20:55 -05:00
|
|
|
fn main() {
|
2024-02-22 02:16:58 -05:00
|
|
|
let args = Args::parse();
|
2024-03-06 14:31:53 -05:00
|
|
|
println!("previous = {}", args.previous);
|
2024-02-22 02:16:58 -05:00
|
|
|
|
2024-02-28 15:12:19 -05:00
|
|
|
let expected_cfg_files = match Config::expected_locations() {
|
|
|
|
|
Ok(cfg_files) => cfg_files,
|
2024-02-28 17:20:55 -05:00
|
|
|
Err(e) => panic!("{:?}", e),
|
2024-02-28 15:12:19 -05:00
|
|
|
};
|
|
|
|
|
|
2023-06-22 13:44:06 -04:00
|
|
|
let cfg_files: Vec<&Path> = expected_cfg_files
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|file| Path::new(file))
|
|
|
|
|
.filter(|file| file.exists())
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
if cfg_files.len() <= 0 {
|
2024-02-28 17:20:55 -05:00
|
|
|
if let Err(e) = Config::write_default(match expected_cfg_files[0].to_str() {
|
|
|
|
|
Some(s) => s,
|
|
|
|
|
None => panic!("Could not resolve expected cfg file paths"),
|
|
|
|
|
}) {
|
|
|
|
|
panic!("Could not write config: {:?}", e);
|
2023-06-22 13:44:06 -04:00
|
|
|
}
|
|
|
|
|
}
|
2023-10-06 11:46:21 -04:00
|
|
|
|
2024-02-22 02:16:58 -05:00
|
|
|
let cfg_file = match args.config {
|
|
|
|
|
Some(file) => file,
|
|
|
|
|
None => match cfg_files.last() {
|
|
|
|
|
None => expected_cfg_files[0].to_string_lossy().to_string(),
|
|
|
|
|
Some(file) => file.to_string_lossy().to_string(),
|
|
|
|
|
},
|
2023-10-06 11:46:21 -04:00
|
|
|
};
|
|
|
|
|
|
2024-02-22 02:16:58 -05:00
|
|
|
if args.current_config {
|
|
|
|
|
println!("{}", &cfg_file);
|
2024-02-28 17:20:55 -05:00
|
|
|
return;
|
2024-02-22 02:16:58 -05:00
|
|
|
}
|
|
|
|
|
|
2024-02-28 17:20:55 -05:00
|
|
|
let cfg = match Config::load(&cfg_file) {
|
|
|
|
|
Ok(cfg) => cfg,
|
|
|
|
|
Err(_e) => panic!("could not load config: {}", cfg_file),
|
2024-02-22 01:49:57 -05:00
|
|
|
};
|
|
|
|
|
|
2024-02-28 17:20:55 -05:00
|
|
|
let data_dir = cfg.notes_dir.resolve().to_path_buf();
|
|
|
|
|
|
2024-03-04 14:58:30 -05:00
|
|
|
if !fs::metadata(&data_dir).is_ok() {
|
|
|
|
|
match fs::create_dir_all(&data_dir) {
|
2024-03-18 20:20:18 -04:00
|
|
|
Err(_e) => panic!("Could not create default directory: {:?}", &data_dir),
|
2024-02-22 01:49:57 -05:00
|
|
|
_ => (),
|
2023-10-06 12:20:36 -04:00
|
|
|
};
|
2023-10-06 11:46:21 -04:00
|
|
|
}
|
2023-06-13 08:41:37 -04:00
|
|
|
|
2024-03-18 20:17:38 -04:00
|
|
|
let files = fs::read_dir(&data_dir)
|
|
|
|
|
.expect(format!("Could not find notes folder: {:?}", &data_dir).as_str())
|
|
|
|
|
.filter_map(|f| f.ok())
|
|
|
|
|
.map(|file| file.path());
|
|
|
|
|
let today = Local::now().date_naive();
|
|
|
|
|
let target = today - TimeDelta::try_days(args.previous.into()).unwrap();
|
2024-03-18 20:20:18 -04:00
|
|
|
let closest_files = TodoFile::get_closest_files(files.collect(), target, 5);
|
|
|
|
|
println!("{:?}", closest_files);
|
2024-03-18 20:17:38 -04:00
|
|
|
|
2024-03-18 20:20:18 -04:00
|
|
|
let latest_file = closest_files.first().ok_or("");
|
2023-06-13 08:41:37 -04:00
|
|
|
|
2023-06-23 10:47:43 -04:00
|
|
|
let current_file = match latest_file {
|
2023-06-26 09:40:56 -04:00
|
|
|
Ok(todo_file) if todo_file.date < today => {
|
2023-06-15 12:14:36 -04:00
|
|
|
let arena = Arena::new();
|
2023-06-26 09:40:56 -04:00
|
|
|
let root = {
|
2024-03-04 14:58:30 -05:00
|
|
|
let contents = file::load_file(&todo_file);
|
|
|
|
|
let root = file::parse_todo_file(&contents, &arena);
|
2023-06-26 09:40:56 -04:00
|
|
|
root
|
|
|
|
|
};
|
2023-06-22 16:54:00 -04:00
|
|
|
|
2024-02-28 17:20:55 -05:00
|
|
|
let sections = &cfg.sections;
|
2023-06-22 16:54:00 -04:00
|
|
|
|
2024-03-04 14:58:30 -05:00
|
|
|
let groups = file::extract_secitons(root, sections);
|
2023-06-15 12:14:36 -04:00
|
|
|
|
2023-06-23 09:41:27 -04:00
|
|
|
let level = groups.values().map(|group| group.level).min().unwrap_or(2);
|
|
|
|
|
|
2023-06-24 08:44:07 -04:00
|
|
|
let data = sections
|
2023-06-23 09:41:27 -04:00
|
|
|
.iter()
|
|
|
|
|
.map(|section| match groups.get(section) {
|
|
|
|
|
Some(group) => group.clone(),
|
|
|
|
|
None => TaskGroup::empty(section.to_string(), level),
|
|
|
|
|
})
|
2023-06-24 08:44:07 -04:00
|
|
|
.collect();
|
2023-06-23 09:41:27 -04:00
|
|
|
|
2024-03-04 14:58:30 -05:00
|
|
|
let content = file::generate_file_content(&data, &today);
|
|
|
|
|
let file_path = file::get_filepath(&data_dir, &today);
|
|
|
|
|
file::write_file(&file_path, &content);
|
2023-06-26 09:40:56 -04:00
|
|
|
file_path
|
2023-06-22 16:54:00 -04:00
|
|
|
}
|
2023-06-23 10:47:43 -04:00
|
|
|
Err(_) => {
|
2024-02-28 17:20:55 -05:00
|
|
|
let sections = &cfg.sections;
|
2023-06-24 08:44:07 -04:00
|
|
|
let data = sections
|
2023-06-23 10:47:43 -04:00
|
|
|
.iter()
|
2023-06-24 08:44:07 -04:00
|
|
|
.map(|sec| TaskGroup::empty(sec.clone(), 2))
|
2024-02-28 15:12:19 -05:00
|
|
|
.collect();
|
2024-03-04 14:58:30 -05:00
|
|
|
let content = file::generate_file_content(&data, &today);
|
|
|
|
|
let file_path = file::get_filepath(&data_dir, &today);
|
|
|
|
|
file::write_file(&file_path, &content);
|
2023-06-26 09:40:56 -04:00
|
|
|
file_path
|
2023-06-24 08:44:07 -04:00
|
|
|
}
|
2024-03-18 20:17:38 -04:00
|
|
|
Ok(todo_file) => todo_file.file.clone(),
|
2023-06-22 13:44:06 -04:00
|
|
|
};
|
|
|
|
|
|
2024-03-06 14:31:53 -05:00
|
|
|
Command::new(&cfg.editor)
|
2023-06-26 09:40:56 -04:00
|
|
|
.args([current_file])
|
|
|
|
|
.status()
|
2024-03-06 14:31:53 -05:00
|
|
|
.expect(format!("failed to launch editor {}", &cfg.editor).as_str());
|
2023-06-13 07:59:09 -04:00
|
|
|
}
|