use crate::database::db::PdfDatabase;
use crate::helpers::help::{calculate_search_duration, human_readable_size, hyperlink, truncate, get_downloads_path}; use crate::indexer::scanner::scan_directory;
use crate::export::exporter::Exporters;
use dirs;
use std::path::Path;
use std::time::Instant;
pub fn init_command(dir_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
let db_path = PdfDatabase::get_database_path()?;
let db = PdfDatabase::new(&db_path)?;
scan_directory(dir_path, &db)?;
println!(
"\x1b[1;92m✅ Successfully indexed\x1b[0m \x1b[1;92m{}\x1b[0m \x1b[34mPDFs in\x1b[0m \x1b[1;92m{}\x1b[0m\n",
db.count_pdfs()?,
db_path.display()
);
Ok(())
}
pub fn search_command(query: &str) -> Result<(), Box<dyn std::error::Error>> {
let db_path = PdfDatabase::get_database_path()?;
if !db_path.exists() {
return Err("Database with indexed PDFs not found".into());
} else {
let start_time = Instant::now();
let db = PdfDatabase::open(&db_path)?;
let results = db.simple_search(query)?;
if results.is_empty() {
println!("❌ No results found for '{}'.", query);
} else {
println!(
"\n\n\x1b[34m🔎 Search results for:\x1b[0m \x1b[1;92m{}\x1b[0m\n",
query
);
println!(
"\x1b[34m⏱️ Search time:\x1b[0m \x1b[1;92m{}ms\x1b[0m\n",
calculate_search_duration(start_time)
);
println!(
"\x1b[1;92m Σ\x1b[0m\x1b[34m Total results:\x1b[0m \x1b[1;92m{}\x1b[0m",
results.len()
);
println!("\n");
for (i, r) in results.iter().enumerate() {
println!("📄 {}. {}", i + 1, truncate(&r.filename, 40));
println!(" Size: {}", human_readable_size(r.size));
println!(
" Path: {}",
hyperlink(&r.path, &r.path) );
println!("\x1b[34m───────────────────────────────────────────────\x1b[0m"); println!(); }
}
}
Ok(())
}
pub fn list_command() -> Result<(), Box<dyn std::error::Error>> {
let db_path = PdfDatabase::get_database_path()?;
if !db_path.exists() {
return Err("Database with indexed PDFs not found. Run 'pdfx init' first.".into());
}
let db = PdfDatabase::open(&db_path)?;
let results = db.get_all_pdfs()?;
println!("\n📋 All Indexed PDFs");
println!("📊 Total: {} PDFs\n", results.len());
for (i, r) in results.iter().enumerate() {
println!(
"\x1b[1;94m📄 {}. {}\x1b[0m",
i + 1,
truncate(&r.filename, 50)
); println!(" \x1b[34mSize:\x1b[0m {}", human_readable_size(r.size)); println!(" \x1b[36mPath:\x1b[0m {}", hyperlink(&r.path, &r.path)); println!(
" \x1b[38;5;75mModified:\x1b[0m {}",
r.modified.format("%Y-%m-%d %H:%M:%S")
); println!("\x1b[34m───────────────────────────────────────────────\x1b[0m");
println!();
}
Ok(())
}
pub fn export_command(format: Option<&str>) -> Result<(), Box<dyn std::error::Error>> {
let db_path = PdfDatabase::get_database_path()?;
if !db_path.exists() {
return Err("Database with indexed PDFs not found. Run 'pdfx init' first.".into());
}
let db = PdfDatabase::open(&db_path)?;
let export_path = get_downloads_path()?;
let export_content = db.get_all_pdfs()?;
if export_content.is_empty() {
println!("📋 No PDFs found to export.");
return Ok(());
}
let formats_to_export = match format {
Some(f) => f.split(",").map(|s| s.trim()).collect(),
None => vec!["json", "csv", "markdown", "yaml", "html"],
};
println!("Exporting {} PDFs to {}", export_content.len(), export_path.display());
for fmt in formats_to_export {
match fmt {
"json" => {
Exporters::export_to_json(&export_content, &export_path)?;
println!(" ✅ Generated pdfs.json");
}
"csv" => {
Exporters::export_to_csv(&export_content, &export_path)?;
println!(" ✅ Generated pdfs.csv");
}
"markdown" => {
Exporters::export_to_markdown(&export_content, &export_path)?;
println!(" ✅ Generated pdfs.md");
}
"yaml" => {
Exporters::export_to_yaml(&export_content, &export_path)?;
println!(" ✅ Generated pdfs.yaml");
}
"html" => {
Exporters::export_to_html(&export_content, &export_path)?;
println!(" ✅ Generated pdfs.html");
}
_ => {
println!(" ❌ Unsupported format: {}", fmt);
}
}
}
println!("🎉 Export complete!");
Ok(())
}
pub fn cleanup_command() -> Result<(), Box<dyn std::error::Error>> {
let data_dir = dirs::data_dir().expect("Failed to get data directory");
let pdfx_dir = data_dir.join("pdfx");
if pdfx_dir.exists() {
std::fs::remove_dir_all(&pdfx_dir)?;
println!(
"\n✅ Cleaned up pdfx data directory: {}\n",
pdfx_dir.display()
);
println!("🗑️ Removed database and all indexed data\n");
} else {
println!("\nℹ️ No pdfx data found to clean up\n");
}
Ok(())
}