144 lines
4.3 KiB
Rust
144 lines
4.3 KiB
Rust
use std::path::PathBuf;
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use clap::Parser;
|
|
|
|
use image_api::cleanup::{
|
|
CleanupConfig, DatabaseUpdater, resolve_missing_files, validate_file_types,
|
|
};
|
|
use image_api::database::{SqliteExifDao, SqliteFavoriteDao};
|
|
use image_api::tags::SqliteTagDao;
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(name = "cleanup_files")]
|
|
#[command(about = "File cleanup and fix utility for ImageApi", long_about = None)]
|
|
struct Args {
|
|
#[arg(long, help = "Preview changes without making them")]
|
|
dry_run: bool,
|
|
|
|
#[arg(long, help = "Auto-fix all issues without prompting")]
|
|
auto_fix: bool,
|
|
|
|
#[arg(long, help = "Skip phase 1 (missing file resolution)")]
|
|
skip_phase1: bool,
|
|
|
|
#[arg(long, help = "Skip phase 2 (file type validation)")]
|
|
skip_phase2: bool,
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
// Initialize logging
|
|
env_logger::init();
|
|
|
|
// Load environment variables
|
|
dotenv::dotenv()?;
|
|
|
|
// Parse CLI arguments
|
|
let args = Args::parse();
|
|
|
|
// Get base path from environment
|
|
let base_path = dotenv::var("BASE_PATH")?;
|
|
let base = PathBuf::from(&base_path);
|
|
|
|
println!("File Cleanup and Fix Utility");
|
|
println!("============================");
|
|
println!("Base path: {}", base.display());
|
|
println!("Dry run: {}", args.dry_run);
|
|
println!("Auto fix: {}", args.auto_fix);
|
|
println!();
|
|
|
|
// Pre-flight checks
|
|
if !base.exists() {
|
|
eprintln!("Error: Base path does not exist: {}", base.display());
|
|
std::process::exit(1);
|
|
}
|
|
|
|
if !base.is_dir() {
|
|
eprintln!("Error: Base path is not a directory: {}", base.display());
|
|
std::process::exit(1);
|
|
}
|
|
|
|
// Create configuration
|
|
let config = CleanupConfig {
|
|
base_path: base,
|
|
dry_run: args.dry_run,
|
|
auto_fix: args.auto_fix,
|
|
};
|
|
|
|
// Create DAOs
|
|
println!("Connecting to database...");
|
|
let tag_dao: Arc<Mutex<dyn image_api::tags::TagDao>> =
|
|
Arc::new(Mutex::new(SqliteTagDao::default()));
|
|
let exif_dao: Arc<Mutex<dyn image_api::database::ExifDao>> =
|
|
Arc::new(Mutex::new(SqliteExifDao::new()));
|
|
let favorites_dao: Arc<Mutex<dyn image_api::database::FavoriteDao>> =
|
|
Arc::new(Mutex::new(SqliteFavoriteDao::new()));
|
|
|
|
// Create database updater
|
|
let mut db_updater = DatabaseUpdater::new(tag_dao, exif_dao, favorites_dao);
|
|
|
|
println!("✓ Database connected\n");
|
|
|
|
// Track overall statistics
|
|
let mut total_issues_found = 0;
|
|
let mut total_issues_fixed = 0;
|
|
let mut total_errors = Vec::new();
|
|
|
|
// Phase 1: Missing file resolution
|
|
if !args.skip_phase1 {
|
|
match resolve_missing_files(&config, &mut db_updater) {
|
|
Ok(stats) => {
|
|
total_issues_found += stats.issues_found;
|
|
total_issues_fixed += stats.issues_fixed;
|
|
total_errors.extend(stats.errors);
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Phase 1 failed: {:?}", e);
|
|
total_errors.push(format!("Phase 1 error: {}", e));
|
|
}
|
|
}
|
|
} else {
|
|
println!("Phase 1: Skipped (--skip-phase1)");
|
|
}
|
|
|
|
// Phase 2: File type validation
|
|
if !args.skip_phase2 {
|
|
match validate_file_types(&config, &mut db_updater) {
|
|
Ok(stats) => {
|
|
total_issues_found += stats.issues_found;
|
|
total_issues_fixed += stats.issues_fixed;
|
|
total_errors.extend(stats.errors);
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Phase 2 failed: {:?}", e);
|
|
total_errors.push(format!("Phase 2 error: {}", e));
|
|
}
|
|
}
|
|
} else {
|
|
println!("\nPhase 2: Skipped (--skip-phase2)");
|
|
}
|
|
|
|
// Final summary
|
|
println!("\n============================");
|
|
println!("Cleanup Complete!");
|
|
println!("============================");
|
|
println!("Total issues found: {}", total_issues_found);
|
|
if config.dry_run {
|
|
println!("Total issues that would be fixed: {}", total_issues_found);
|
|
} else {
|
|
println!("Total issues fixed: {}", total_issues_fixed);
|
|
}
|
|
|
|
if !total_errors.is_empty() {
|
|
println!("\nErrors encountered:");
|
|
for (i, error) in total_errors.iter().enumerate() {
|
|
println!(" {}. {}", i + 1, error);
|
|
}
|
|
println!("\nSome operations failed. Review errors above.");
|
|
} else {
|
|
println!("\n✓ No errors encountered");
|
|
}
|
|
|
|
Ok(())
|
|
}
|