use std::fs; use std::path::Path; use log::{error, info}; use filetime; use filetime::FileTime; pub struct Repository { pub base_dir: String, pub ingest_dir: String, pub archive_dir: String, pub output_dir: String, } impl Repository { pub fn new(base_path: &str) -> Repository { let ingest_path = Path::new(base_path).join("ingest"); let archive_path = Path::new(base_path).join("archive"); let output_path = Path::new(base_path).join("output"); return Repository { base_dir: String::from(base_path), ingest_dir: String::from(ingest_path.to_str().unwrap()), archive_dir: String::from(archive_path.to_str().unwrap()), output_dir: String::from(output_path.to_str().unwrap()), }; } pub fn initialize(&self) { // create the base directory path create_directory(&self.base_dir); // create the needed sub-directories create_directory(&self.ingest_dir.as_str()); create_directory(&self.archive_dir.as_str()); create_directory(&self.output_dir.as_str()); } pub fn search_ingest(&self) -> Vec { // read file entries from ingest let files = fs::read_dir(&self.ingest_dir).unwrap(); // create vec object and loop through entries to find what we want let mut ingest_files: Vec = vec![]; for f in files { let f = f.unwrap(); let path = f.path(); if path.is_file() { let file_path = path.file_name().unwrap().to_str(); ingest_files.push(String::from(file_path.unwrap())); } } return ingest_files; } pub fn archive_file(&self, file: &str) { let ingest_file = Path::new(&self.ingest_dir).join(file); let archive_file = Path::new(&self.archive_dir).join(file); match fs::copy(&ingest_file, &archive_file) { Ok(_) => { info!("Archiving video file {}.", ingest_file.to_str().unwrap()); copy_file_metadata(ingest_file.to_str().unwrap(), archive_file.to_str().unwrap()); }, Err(e) => { error!("Error archiving file {}: {}", ingest_file.to_str().unwrap(), e); std::process::exit(1); } } } pub fn cleanup_file(&self, file: &str) { let ingest_file = Path::new(&self.ingest_dir).join(file); fs::remove_file(&ingest_file) .expect("File deletion failed."); } } fn create_directory(path: &str) { let d = Path::new(path); if d.is_dir() { info!("Directory {} already exists.", path); } else { match fs::create_dir(path) { Ok(_) => { info!("Creating directory {}.", path); }, Err(e) => { error!("Error creating {}: {}", path, e); std::process::exit(1); } } } } fn copy_file_metadata(old_file: &str, new_file: &str) { // grab old file metadata let old_metadata = fs::metadata(old_file).unwrap(); let old_permissions = old_metadata.permissions(); let mtime = FileTime::from_last_modification_time(&old_metadata); let atime = FileTime::from_last_access_time(&old_metadata); // set metadata on the new file let new_path = Path::new(new_file); fs::set_permissions(new_file, old_permissions).expect("Failed to set new file permissions."); filetime::set_file_times(new_path, atime, mtime).expect("Failed to set atime and mtime."); }