add basic command to edit memos

This commit is contained in:
əlemi 2022-03-16 02:07:02 +01:00
parent 581aca2fb1
commit 5d4c206b25
No known key found for this signature in database
GPG key ID: BBCBFE5D7244634E
3 changed files with 68 additions and 9 deletions

View file

@ -1,13 +1,14 @@
mod storage;
mod utils;
use chrono::{DateTime, Utc, Local};
use chrono::{DateTime, Local, Utc};
use clap::{Parser, Subcommand};
use colored::Colorize;
use const_format::concatcp;
use git_version::git_version;
use regex::Regex;
use storage::{open_sqlite_storage, Memo, MemoStorage};
use utils::{parse_human_duration, HumanDisplay};
use git_version::git_version;
use const_format::concatcp;
use utils::{find_by_regex, parse_human_duration, HumanDisplay};
const GIT_VERSION: &str = git_version!();
const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
@ -47,7 +48,15 @@ enum Commands {
search: String,
#[clap(long, help = "delete more than one task if matched")]
many: bool,
}
},
/// change existing memo
Edit {
search: String,
#[clap(short, long, help = "set memo message")]
body: Option<String>,
#[clap(short, long, help = "set due time relative to now")]
due: Option<String>, // TODO allow to pass date
},
}
fn main() {
@ -71,7 +80,7 @@ fn main() {
}
let txt = body.join(" ");
storage.add(txt.as_str(), due_date).unwrap();
println!("[+] new memo: {}", txt);
println!("{} new memo: {}", "[+]".bold(), txt);
}
Some(Commands::Done { search, many }) => {
let rex = Regex::new(search.as_str());
@ -101,6 +110,26 @@ fn main() {
println!("[!] invalid regex");
}
}
Some(Commands::Edit { search, body, due }) => {
let mut m = find_by_regex(
regex::Regex::new(search.as_str()).unwrap(),
storage.all(false).unwrap(),
)
.unwrap();
if let Some(b) = body {
m.body = b;
}
if let Some(d) = due {
if d == "null" || d == "none" {
m.due = None
} else {
m.due = Some(Utc::now() + parse_human_duration(d.as_str()).unwrap());
}
}
storage.set(&m).unwrap();
println!("[>] updated memo\n{}", m.human());
}
None => {
let all = storage.all(args.old).unwrap();
let mut builder = String::new();
@ -119,11 +148,12 @@ fn main() {
let n = libnotify::Notification::new(
format!("memo-cli | {}", Local::now().format("%a %d/%m, %H:%M")).as_str(),
Some(builder.as_str()),
None
None,
);
n.show().unwrap();
libnotify::uninit();
} else {
println!("{}", "memo-cli".bold());
print!("{}", builder);
}
}

View file

@ -27,6 +27,7 @@ impl fmt::Display for Memo {
pub trait MemoStorage {
fn all(&self, done: bool) -> Result<Vec<Memo>, Error>;
fn add(&self, body: &str, due: Option<DateTime<Utc>>) -> Result<(), Error>;
fn set(&self, memo: &Memo) -> Result<bool, Error>;
fn del(&self, id: u32) -> Result<bool, Error>;
fn get(&self, id: u32) -> Result<Memo, Error>;
}
@ -109,6 +110,18 @@ impl MemoStorage for SQLiteStorage {
return Ok(());
}
fn set(&self, memo: &Memo) -> Result<bool, Error> {
let count = self.conn.execute(
"UPDATE memo SET body = ?, due = ? WHERE id = ?",
params![memo.body, memo.due, memo.id],
)?;
if count > 0 {
return Ok(true);
} else {
return Ok(false);
}
}
fn del(&self, id: u32) -> Result<bool, Error> {
let count = self
.conn

View file

@ -63,8 +63,24 @@ pub fn parse_human_duration(input: &str) -> Result<Duration, Error> {
return Ok(Duration::seconds(secs));
}
pub fn find_by_regex(re: Regex, memos: Vec<Memo>) -> Option<Memo> {
let mut found = false;
let mut out: Option<Memo> = None;
for memo in memos {
if re.is_match(memo.body.as_str()) {
if found {
return None; // there's at least one duplicate
} else {
out = Some(memo);
found = true;
}
}
}
return out;
}
// TODO is it possible to make this a method?
pub fn vec_to_str<T: std::fmt::Display>(arr: &Vec<T>) -> String {
/* pub fn vec_to_str<T: std::fmt::Display>(arr: &Vec<T>) -> String {
let mut out = String::default();
let mut first = true;
out += "[";
@ -78,4 +94,4 @@ pub fn vec_to_str<T: std::fmt::Display>(arr: &Vec<T>) -> String {
}
out += " ]";
return out;
}
} */