use log::{info, trace};
use regex::Regex;
use async_recursion::async_recursion;
use std::path::Path;
use tokio::fs;
use tokio::io;
const VIDEO_PATTERNS: [&str; 4] = ["mp4", "mkv", "avi", "wmv"];
pub async fn delete_files_matching_patterns<P: AsRef<Path>>(
file_path: P,
patterns: &[String],
) -> io::Result<bool> {
let path = file_path.as_ref();
let mut dir_deleted = false;
let is_file: bool = fs::metadata(&path)
.await
.map(|m| m.is_file())
.unwrap_or(false);
if is_file {
let file_name = match path.file_name() {
Some(name) => name.to_string_lossy().into_owned(),
None => return Ok(false),
};
for pattern in patterns {
let regex_pattern = format!("^{}.*$", pattern.replace("*", ".*"));
let re = Regex::new(®ex_pattern).unwrap();
if re.is_match(&file_name) {
info!("will delete file: {:?}", path);
fs::remove_file(path).await?;
dir_deleted = true;
break;
}
}
}
Ok(dir_deleted)
}
#[async_recursion]
pub async fn delete_dir_with_no_video<P: AsRef<Path> + Send + Sync + 'static>(
path: P,
) -> io::Result<bool> {
let path_ref = path.as_ref();
let mut dir_deleted = false;
let mut is_empty = true;
if path_ref.is_dir() {
let mut has_video = false;
let mut has_nfo = false;
let mut only_has_trailers_dir = true;
let mut entries = fs::read_dir(path_ref).await?;
while let Some(entry) = entries.next_entry().await? {
is_empty = false;
let path = entry.path();
if path.is_dir() {
trace!("path.is_dir: {:?}", path);
delete_dir_with_no_video(path.clone()).await?;
let dir_name = path.file_name().unwrap().to_string_lossy();
if dir_name != "trailers" {
only_has_trailers_dir = false;
}
} else {
let file_name = path.file_name().unwrap().to_string_lossy();
for pattern in VIDEO_PATTERNS.iter() {
if file_name.ends_with(pattern) {
has_video = true;
break;
}
}
if file_name.ends_with("nfo") {
has_nfo = true;
}
}
}
trace!("has_nfo: {:?}", has_nfo);
trace!("has_video: {:?}", has_video);
trace!("only_has_trailers_dir: {:?}", only_has_trailers_dir);
trace!("path: {:?}", path_ref);
if (!has_video && (has_nfo || !only_has_trailers_dir)) || is_empty {
info!("will delete dir: {:?}", path_ref);
fs::remove_dir_all(path_ref).await?;
dir_deleted = true;
}
} else {
trace!("is not dir: {:?}", path_ref);
}
Ok(dir_deleted)
}