Removed submodule classification in git

This commit is contained in:
brotoskyj
2025-11-04 09:04:39 -05:00
parent b59f2689f4
commit 14f8d4c420
9 changed files with 3643 additions and 1 deletions
+170
View File
@@ -0,0 +1,170 @@
use chrono::{Datelike, Duration, NaiveDate, Utc};
use indicatif::{ProgressBar, ProgressStyle};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
// Example API response type
#[derive(Debug, Serialize, Deserialize, Clone)]
struct HistoryItem {
checkpoint: Option<String>,
datetime: String,
sha256: Option<String>,
filename: Option<String>,
hostname: Option<String>,
// other fields...
}
// JSON file structure
#[derive(Debug, Serialize, Deserialize)]
struct JsonFile {
error: String,
response: ResponseData,
}
#[derive(Debug, Serialize, Deserialize)]
struct ResponseData {
exechistories: Vec<HistoryItem>,
}
// Mock API function
fn history_logging(_type: &str, checkpoint: &str, _policy: &[&str]) -> Vec<HistoryItem> {
// Replace with actual API call
vec![]
}
fn main() {
let file_path = Path::new("data/example.json");
let mut checkpoint = "initial_checkpoint".to_string();
let policy_name = "policy1".to_string();
let days = 7;
// Initialize JSON output
let mut json_output = JsonFile {
error: "Success".to_string(),
response: ResponseData {
exechistories: vec![],
},
};
// Outer progress bar (filebar)
let filebar = ProgressBar::new(10_000);
filebar.set_style(
ProgressStyle::default_bar()
.template("Checkpoint Progress: {msg} [{bar:40.cyan/blue}] {pos}/{len}")
.unwrap(),
);
filebar.set_message(&checkpoint);
// Inner progress bar (total progress)
let pbar = ProgressBar::new(100);
pbar.set_style(
ProgressStyle::default_bar()
.template("Total of {msg} Complete: [{bar:40.cyan/blue}] {pos}/{len}")
.unwrap(),
);
pbar.set_message(&policy_name);
loop {
let histories = history_logging("type", &checkpoint, &[&policy_name]);
if !histories.iter().all(|h| h.datetime.len() > 0) {
eprintln!("Unexpected response format from API.");
break;
}
filebar.set_length(histories.len() as u64);
if histories.is_empty() {
break;
}
for (index, history_item) in histories.iter().enumerate() {
if history_item.checkpoint.is_none() || history_item.datetime.is_empty() {
continue;
}
if index == histories.len() - 1 {
checkpoint = history_item.checkpoint.clone().unwrap();
filebar.set_message(&checkpoint);
break;
}
// Parse date
let history_date = match NaiveDate::parse_from_str(
&history_item.datetime.replace(" +0000 UTC", ""),
"%Y-%m-%dT%H:%M:%SZ",
) {
Ok(date) => date,
Err(_) => continue,
};
let cutoff = Utc::today().naive_utc() - Duration::days(days);
if history_date >= cutoff {
json_output.response.exechistories.push(history_item.clone());
}
filebar.inc(1);
filebar.tick();
}
// Deduplicate
let mut seen: HashMap<(Option<String>, Option<String>, Option<String>), HistoryItem> =
HashMap::new();
let combined = if file_path.exists() {
let mut f = File::open(file_path).unwrap();
let mut contents = String::new();
f.read_to_string(&mut contents).unwrap();
let existing_data: JsonFile = serde_json::from_str(&contents).unwrap_or(JsonFile {
error: "Success".to_string(),
response: ResponseData {
exechistories: vec![],
},
});
[existing_data.response.exechistories, json_output.response.exechistories.clone()]
.concat()
} else {
json_output.response.exechistories.clone()
};
for entry in combined {
let key = (entry.sha256.clone(), entry.filename.clone(), entry.hostname.clone());
seen.insert(key, entry);
}
let deduplicated: Vec<HistoryItem> = seen.into_values().collect();
// Write to file
let output_file = File::create(file_path).unwrap();
serde_json::to_writer_pretty(&output_file, &json!({
"error": "Success",
"response": { "exechistories": deduplicated }
}))
.unwrap();
json_output.response.exechistories.clear();
// Update inner progress bar (percentage based on last valid item)
if let Some(last_item) = histories.last() {
if let Ok(last_date) = NaiveDate::parse_from_str(
&last_item.datetime.replace(" +0000 UTC", ""),
"%Y-%m-%dT%H:%M:%SZ",
) {
let date_diff = Utc::today().naive_utc() - last_date;
let percentage_diff = ((days + 10) - date_diff.num_days()) as f64 / (days + 10) as f64 * 100.0;
pbar.set_position(percentage_diff.round() as u64);
pbar.set_message(&policy_name);
pbar.tick();
}
}
filebar.set_position(1);
}
filebar.finish();
pbar.finish();
}