use crate::database::db::PdfDatabase;
use crate::types::PdfEntry;
use chrono::{DateTime, Utc};
use indicatif::{ProgressBar, ProgressStyle};
use std::path::Path;
use walkdir::WalkDir;
pub fn scan_directory(
path: &Path,
database: &PdfDatabase,
) -> Result<(), Box<dyn std::error::Error>> {
let count_pb = ProgressBar::new_spinner();
count_pb.set_style(
ProgressStyle::default_spinner()
.template("{spinner:.green} {msg} {pos}")
.unwrap()
.progress_chars("⣿⣷⣯⣟⡿⢿⠿⠟⠛⠋ "),
);
count_pb.set_message("Counting files...");
let mut total_files = 0;
for entry in WalkDir::new(path) {
if entry.is_ok() {
total_files += 1;
if total_files % 100 == 0 {
count_pb.set_position(total_files);
}
}
}
count_pb.finish_and_clear();
let pb = ProgressBar::new(total_files);
pb.set_style(
ProgressStyle::default_bar()
.template("🔍 {msg} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos}/{len} files | {per_sec} | ETA: {eta}")
.unwrap()
.progress_chars("⣿⣷⣯⣟⡿⢿⠿⠟⠛⠋ ")
);
pb.set_message("Scanning for PDFs...");
let mut files_processed = 0;
let mut pdfs_found = 0;
let mut dirs_skipped = 0;
for entry in WalkDir::new(path) {
let entry = match entry {
Ok(entry) => entry,
Err(_) => {
dirs_skipped += 1;
continue;
}
};
files_processed += 1;
pb.set_position(files_processed);
let file_path = entry.path();
if let Some(extension) = file_path.extension() {
if extension == "pdf" {
let metadata = file_path.metadata()?;
let pdf_entry = PdfEntry {
id: None,
path: file_path.to_string_lossy().to_string(),
filename: file_path.file_name().unwrap().to_string_lossy().to_string(),
size: metadata.len(),
modified: DateTime::from(metadata.modified()?),
indexed_at: Some(Utc::now()),
};
database.insert_pdf(&pdf_entry)?;
pdfs_found += 1;
}
}
}
pb.finish_with_message(format!(
"✅ Scan complete! {} PDFs found | {} files processed | {} directories skipped\n",
pdfs_found, files_processed, dirs_skipped
));
Ok(())
}