mirror of
https://git.alemi.dev/memo-cli.git
synced 2024-11-25 13:04:49 +01:00
added state and auth storage with traits, show last run time on cli
This commit is contained in:
parent
32eb53ba2b
commit
9f01ac7d4e
2 changed files with 97 additions and 3 deletions
13
src/main.rs
13
src/main.rs
|
@ -8,7 +8,7 @@ use colored::Colorize;
|
||||||
use const_format::concatcp;
|
use const_format::concatcp;
|
||||||
use git_version::git_version;
|
use git_version::git_version;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use storage::{open_sqlite_storage, Memo, MemoStorage, SQLiteStorage};
|
use storage::{open_sqlite_storage, Memo, MemoStorage, AuthStorage, StateStorage, SQLiteStorage};
|
||||||
use utils::{find_by_regex, parse_human_duration, HumanDisplay};
|
use utils::{find_by_regex, parse_human_duration, HumanDisplay};
|
||||||
use remote::RemoteSync;
|
use remote::RemoteSync;
|
||||||
|
|
||||||
|
@ -150,6 +150,10 @@ fn main() {
|
||||||
None => {
|
None => {
|
||||||
let all = storage.all(args.old).unwrap();
|
let all = storage.all(args.old).unwrap();
|
||||||
let mut builder = String::new();
|
let mut builder = String::new();
|
||||||
|
let timing = if let Some(state) = storage.get_state().ok() {
|
||||||
|
let now = Local::now();
|
||||||
|
format!("last run: {}", state.last_run.with_timezone(&now.timezone()).format("%a %d/%m %H:%M"))
|
||||||
|
} else { Local::now().format("%a %d/%m, %H:%M").to_string() };
|
||||||
if args.old {
|
if args.old {
|
||||||
builder.push_str("Archived memos:\n");
|
builder.push_str("Archived memos:\n");
|
||||||
}
|
}
|
||||||
|
@ -164,14 +168,14 @@ fn main() {
|
||||||
if args.notify {
|
if args.notify {
|
||||||
libnotify::init("memo-cli").unwrap();
|
libnotify::init("memo-cli").unwrap();
|
||||||
let n = libnotify::Notification::new(
|
let n = libnotify::Notification::new(
|
||||||
format!("memo-cli | {}", Local::now().format("%a %d/%m, %H:%M")).as_str(),
|
format!("memo-cli | {}", timing).as_str(),
|
||||||
Some(builder.as_str()),
|
Some(builder.as_str()),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
n.show().unwrap();
|
n.show().unwrap();
|
||||||
libnotify::uninit();
|
libnotify::uninit();
|
||||||
} else {
|
} else {
|
||||||
println!("{} | {}", "memo-cli".bold(), Local::now().format("%a %d/%m, %H:%M"));
|
println!("{} | {}", "memo-cli".bold(), timing);
|
||||||
print!("{}", builder);
|
print!("{}", builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,8 +185,11 @@ fn main() {
|
||||||
let res = SQLiteStorage::store("asdasd", "http://127.0.0.1:8443");
|
let res = SQLiteStorage::store("asdasd", "http://127.0.0.1:8443");
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
println!("[^] uploaded local db");
|
println!("[^] uploaded local db");
|
||||||
|
storage.set_sync_time(Utc::now()).unwrap();
|
||||||
} else {
|
} else {
|
||||||
println!("[!] could not upload db : {}", res.err().unwrap().to_string());
|
println!("[!] could not upload db : {}", res.err().unwrap().to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage.set_run_time(Utc::now()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,11 @@ pub struct Memo {
|
||||||
pub due: Option<DateTime<Utc>>,
|
pub due: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct State {
|
||||||
|
pub last_run: DateTime<Utc>,
|
||||||
|
pub last_sync: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Memo {
|
impl fmt::Display for Memo {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut due_str = "null".to_string();
|
let mut due_str = "null".to_string();
|
||||||
|
@ -32,6 +37,30 @@ pub trait MemoStorage {
|
||||||
fn get(&self, id: u32) -> Result<Memo, Error>;
|
fn get(&self, id: u32) -> Result<Memo, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait AuthStorage {
|
||||||
|
fn get_key(&self) -> Result<String, Error>;
|
||||||
|
fn set_key(&self, key:&str) -> Result<Option<String>, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait StateStorage {
|
||||||
|
fn set_state(&self, state:State) -> Result<Option<State>, Error>;
|
||||||
|
fn get_state(&self) -> Result<State, Error>;
|
||||||
|
|
||||||
|
fn set_run_time(&self, time:DateTime<Utc>) -> Result<(), Error> {
|
||||||
|
let mut state = self.get_state().unwrap_or(State{last_run:time, last_sync:None}); // TODO jank way to not fail on 1st use
|
||||||
|
state.last_run = time;
|
||||||
|
self.set_state(state)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_sync_time(&self, time:DateTime<Utc>) -> Result<(), Error> {
|
||||||
|
let mut state = self.get_state()?;
|
||||||
|
state.last_sync = Some(time);
|
||||||
|
self.set_state(state)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SQLiteStorage
|
// SQLiteStorage
|
||||||
|
|
||||||
pub struct SQLiteStorage {
|
pub struct SQLiteStorage {
|
||||||
|
@ -50,9 +79,67 @@ pub fn open_sqlite_storage(path: &str) -> Result<SQLiteStorage, Error> {
|
||||||
);",
|
);",
|
||||||
[],
|
[],
|
||||||
)?;
|
)?;
|
||||||
|
connection.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS state (
|
||||||
|
last_run DATETIME DEFAULT NULL,
|
||||||
|
last_sync DATETIME DEFAULT NULL
|
||||||
|
);",
|
||||||
|
[],
|
||||||
|
)?;
|
||||||
|
connection.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS auth (
|
||||||
|
key TEXT PRIMARY KEY
|
||||||
|
);",
|
||||||
|
[],
|
||||||
|
)?;
|
||||||
return Ok(SQLiteStorage { conn: connection });
|
return Ok(SQLiteStorage { conn: connection });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AuthStorage for SQLiteStorage {
|
||||||
|
fn get_key(&self) -> Result<String, Error> {
|
||||||
|
return Ok(self.conn.query_row(
|
||||||
|
"SELECT * FROM auth", [],
|
||||||
|
|row| {
|
||||||
|
return Ok(row.get(0)?);
|
||||||
|
},
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_key(&self, key: &str) -> Result<Option<String>, Error> {
|
||||||
|
let old_key = self.get_key().ok();
|
||||||
|
self.conn.execute("DELETE FROM auth;", [])?;
|
||||||
|
self.conn.execute(
|
||||||
|
"INSERT INTO auth VALUES (?);",
|
||||||
|
params![key]
|
||||||
|
)?;
|
||||||
|
return Ok(old_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StateStorage for SQLiteStorage {
|
||||||
|
fn get_state(&self) -> Result<State, Error> {
|
||||||
|
return Ok(self.conn.query_row(
|
||||||
|
"SELECT * FROM state", [],
|
||||||
|
|row| {
|
||||||
|
return Ok(State{
|
||||||
|
last_run:row.get(0)?,
|
||||||
|
last_sync:row.get(1).ok()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_state(&self, state:State) -> Result<Option<State>, Error> {
|
||||||
|
let old_state = self.get_state().ok();
|
||||||
|
self.conn.execute("DELETE FROM state;", [])?;
|
||||||
|
self.conn.execute(
|
||||||
|
"INSERT INTO state (last_run, last_sync) VALUES (?, ?);",
|
||||||
|
params![state.last_run, state.last_sync]
|
||||||
|
)?;
|
||||||
|
return Ok(old_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MemoStorage for SQLiteStorage {
|
impl MemoStorage for SQLiteStorage {
|
||||||
fn all(&self, done: bool) -> Result<Vec<Memo>, Error> {
|
fn all(&self, done: bool) -> Result<Vec<Memo>, Error> {
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
|
|
Loading…
Reference in a new issue