add storing of history

This commit is contained in:
Navid Sassan 2024-02-18 21:22:55 +01:00
parent 10923f18fa
commit 9d87b1a8cd
2 changed files with 69 additions and 1 deletions

View File

@ -13,3 +13,4 @@ itertools = "0.11"
log = "0.4"
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View File

@ -1,7 +1,10 @@
use clap::{Parser, Subcommand};
use itertools::Itertools;
use log::{debug, error, info};
use serde::{Serialize, Deserialize};
use std::env;
use std::fs;
use std::io::Read;
use std::io::Write;
use std::process::Stdio;
use std::{process, collections::HashMap};
@ -29,12 +32,17 @@ struct Cli {
#[derive(Subcommand)]
enum CliCommands {
Select {
// Show the details of the item
Select {
title: Option<String>,
},
}
#[derive(Serialize, Deserialize)]
struct History {
history: Vec<String>,
}
fn main() {
env_logger::init();
@ -50,6 +58,64 @@ fn main() {
}
fn get_history() -> Vec<String> {
let file_path = "/tmp/bw-menu-history.json"; // TODO: use XDG paths
let read_file = fs::OpenOptions::new()
.read(true)
.open(file_path);
let json_str = match read_file {
Ok(mut file) => {
let mut content = String::new();
file.read_to_string(&mut content).expect("Failed to read file");
content
}
Err(_) => String::new(), // Return an empty string if the file cannot be opened
};
// Deserialize JSON string back into a Rust struct
let history: History = serde_json::from_str(&json_str).unwrap_or_else(|_| {
// Return a default Person with an empty history if deserialization fails
History {
history: Vec::new(),
}
});
history.history
}
fn save_history(entries: Vec<String>) {
let history = History {
history: entries,
};
let json_str = serde_json::to_string(&history).expect("Failed to serialize to JSON!");
let file_path = "/tmp/bw-menu-history.json"; // TODO: use XDG paths
// Write the JSON string to a file, overwriting it if it already exists
let mut file = fs::OpenOptions::new()
.write(true)
.truncate(true) // Ensure the file is truncated before writing
.create(true)
.open(file_path)
.expect("Failed to open file for writing!");
file.write_all(json_str.as_bytes()).expect("Failed to write to file!");
}
const MAX_HISTORY_LEN: usize = 5; // TODO: make configurable
fn add_history(entry: &String) {
let mut history = get_history();
history.insert(0, entry.to_string());
if history.len() > MAX_HISTORY_LEN {
history = history[0..MAX_HISTORY_LEN].to_vec();
}
save_history(history);
}
// the flow is:
// 1. bw-menu starts rofi in the script mode
// 2. rofi calls bw-menu calls bw-menu to get a list of items to display
@ -104,6 +170,7 @@ fn rofi() {
process::exit(1);
}
};
add_history(&rofi_info);
// 1: Selected an entry
if rofi_retv == 1 {
info!("copy password");