|
|
|
@ -1,55 +1,59 @@
|
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
use chrono::{DateTime, Local};
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use std::fs;
|
|
|
|
|
|
|
|
|
|
use crate::{ai::Params, config::CONFIG};
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
|
|
|
pub struct HistoryEntry {
|
|
|
|
|
pub date: DateTime<Local>,
|
|
|
|
|
pub selected_ai: String,
|
|
|
|
|
pub params: Params,
|
|
|
|
|
pub result: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn write_history(entry: HistoryEntry) -> Result<()> {
|
|
|
|
|
// should be safe to unwrap as this function will never be called without it
|
|
|
|
|
let history_dir = CONFIG.app.history_dir.as_ref().unwrap();
|
|
|
|
|
|
|
|
|
|
fs::create_dir_all(history_dir)?;
|
|
|
|
|
|
|
|
|
|
let json = serde_json::to_string(&entry)?;
|
|
|
|
|
|
|
|
|
|
fs::write(
|
|
|
|
|
format!("{}/{}.json", history_dir, entry.date.timestamp()),
|
|
|
|
|
json,
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
this should probably be async all things considered however losing out on proper error handling with ? is
|
|
|
|
|
not worth it. so here's hoping that rust fs (and serde_json (meaning serde too)) is fast enough to read like 10000 files
|
|
|
|
|
*/
|
|
|
|
|
pub fn read_all_history() -> Result<Vec<HistoryEntry>> {
|
|
|
|
|
// should be safe to unwrap as this function will never be called without it
|
|
|
|
|
let history_dir = CONFIG.app.history_dir.as_ref().unwrap();
|
|
|
|
|
let mut entries = vec![];
|
|
|
|
|
|
|
|
|
|
for dir_entry in fs::read_dir(history_dir).context("Failed to read history_dir!")? {
|
|
|
|
|
let dir_entry = dir_entry?;
|
|
|
|
|
|
|
|
|
|
if dir_entry.file_type()?.is_file() {
|
|
|
|
|
let json = fs::read_to_string(dir_entry.path())?;
|
|
|
|
|
let entry: HistoryEntry = serde_json::from_str(&json)?;
|
|
|
|
|
|
|
|
|
|
entries.push(entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entries.sort_by(|a, b| b.date.cmp(&a.date));
|
|
|
|
|
|
|
|
|
|
Ok(entries)
|
|
|
|
|
}
|
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
use chrono::{DateTime, Local};
|
|
|
|
|
use rayon::prelude::*;
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use std::fs;
|
|
|
|
|
|
|
|
|
|
use crate::{ai::Params, config::CONFIG};
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
|
|
|
pub struct HistoryEntry {
|
|
|
|
|
pub date: DateTime<Local>,
|
|
|
|
|
pub selected_ai: String,
|
|
|
|
|
pub params: Params,
|
|
|
|
|
pub result: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn write_history(entry: HistoryEntry) -> Result<()> {
|
|
|
|
|
// should be safe to unwrap as this function will never be called without it
|
|
|
|
|
let history_dir = CONFIG.app.history_dir.as_ref().unwrap();
|
|
|
|
|
|
|
|
|
|
fs::create_dir_all(history_dir)?;
|
|
|
|
|
|
|
|
|
|
let json = serde_json::to_string(&entry)?;
|
|
|
|
|
|
|
|
|
|
fs::write(
|
|
|
|
|
format!("{}/{}.json", history_dir, entry.date.timestamp()),
|
|
|
|
|
json,
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn read_all_history() -> Result<Vec<HistoryEntry>> {
|
|
|
|
|
// should be safe to unwrap as this function will never be called without it
|
|
|
|
|
let history_dir = CONFIG.app.history_dir.as_ref().unwrap();
|
|
|
|
|
let (tx, rx) = flume::unbounded();
|
|
|
|
|
|
|
|
|
|
fs::read_dir(history_dir)
|
|
|
|
|
.context("Failed to read history_dir!")?
|
|
|
|
|
.par_bridge()
|
|
|
|
|
.try_for_each_with(tx, |tx, dir_entry| -> Result<()> {
|
|
|
|
|
let dir_entry = dir_entry?;
|
|
|
|
|
|
|
|
|
|
if dir_entry.file_type()?.is_file() {
|
|
|
|
|
let json = fs::read_to_string(dir_entry.path())?;
|
|
|
|
|
let entry: HistoryEntry = serde_json::from_str(&json)?;
|
|
|
|
|
|
|
|
|
|
tx.send(entry)?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
let mut entries: Vec<HistoryEntry> = rx.iter().collect();
|
|
|
|
|
|
|
|
|
|
entries.sort_by(|a, b| b.date.cmp(&a.date));
|
|
|
|
|
|
|
|
|
|
Ok(entries)
|
|
|
|
|
}
|
|
|
|
|