241 lines
7.6 KiB
Rust
241 lines
7.6 KiB
Rust
use super::element::TargetType;
|
|
use super::offscreen_renderer::{CanvasWrapper, OffscreenRenderer};
|
|
use crate::{
|
|
components::app::{Buffer, FILE_PATH_ROOT},
|
|
CONFIG,
|
|
};
|
|
use chrono::{prelude::*, Duration};
|
|
use once_cell::sync::Lazy;
|
|
use regex::Regex;
|
|
use std::{cell::Ref, collections::HashMap, path::PathBuf};
|
|
use tracing::*;
|
|
|
|
static REREMAP: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
|
|
let mut map = HashMap::new();
|
|
map.insert("%Y", r"\d{4}");
|
|
map.insert("%m", r"\d{2}");
|
|
map.insert("%d", r"\d{2}");
|
|
map.insert("%H", r"\d{2}");
|
|
map.insert("%M", r"\d{2}");
|
|
map.insert("%S", r"\d{2}");
|
|
map.insert("{prefix}", r"(.+?)");
|
|
map
|
|
});
|
|
|
|
#[derive(Debug)]
|
|
pub struct Dispatcher {
|
|
datetime: DateTime<Utc>,
|
|
fore_len: usize,
|
|
back_len: usize,
|
|
step: Duration,
|
|
}
|
|
|
|
impl Dispatcher {
|
|
pub fn new(fore_len: usize, back_len: usize, step: Duration) -> Self {
|
|
Self {
|
|
datetime: Utc::now(),
|
|
fore_len,
|
|
back_len,
|
|
step,
|
|
}
|
|
}
|
|
|
|
pub fn set_current_time(&mut self, datetime: DateTime<Utc>) {
|
|
self.datetime = datetime;
|
|
}
|
|
|
|
pub fn set_step(&mut self, step: Duration) {
|
|
self.step = step;
|
|
}
|
|
|
|
pub fn set_fore_len(&mut self, fore_len: usize) {
|
|
self.fore_len = fore_len;
|
|
}
|
|
|
|
pub fn set_back_len(&mut self, back_len: usize) {
|
|
self.back_len = back_len;
|
|
}
|
|
|
|
pub fn get_single_path(
|
|
&self,
|
|
name: &str,
|
|
current_time: DateTime<Utc>,
|
|
check_existed: bool,
|
|
) -> Option<String> {
|
|
let datetime_format: regex::Regex =
|
|
Regex::new(r"(?:%[YHMSmd](?:[-/:_]?%[YHMSmd])*)").unwrap();
|
|
let config = CONFIG.lock().unwrap();
|
|
let path_format = config
|
|
.plugins
|
|
.get("etws_loader")
|
|
.unwrap()
|
|
.path_formats
|
|
.as_ref();
|
|
if path_format.is_none() {
|
|
return None;
|
|
}
|
|
let c = path_format.unwrap().get(name).map(|s| {
|
|
let path = s.clone();
|
|
let need_formated = datetime_format.captures_iter(&path).collect::<Vec<_>>();
|
|
let mut result_path = path.clone();
|
|
|
|
for need_format in need_formated.iter() {
|
|
let fmt = need_format.get(0).unwrap().as_str();
|
|
let t = current_time.format(fmt).to_string();
|
|
result_path = result_path.replace(fmt, &t);
|
|
}
|
|
result_path
|
|
});
|
|
if let Some(c) = c {
|
|
if check_existed {
|
|
if std::path::Path::new(&c).exists() {
|
|
Some(c)
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
Some(c)
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn get_path(
|
|
&self,
|
|
name: &str,
|
|
current_time: DateTime<Utc>,
|
|
check_existed: bool,
|
|
mut max_retry_time: usize,
|
|
) -> Option<Vec<(String, DateTime<Utc>)>> {
|
|
let datetime_format: regex::Regex =
|
|
Regex::new(r"%[YHMSmd](?:[-/:_]?%[YHMSmd])*").unwrap();
|
|
let config = CONFIG.lock().unwrap();
|
|
let path_format = config
|
|
.plugins
|
|
.get("etws_loader")
|
|
.unwrap()
|
|
.path_formats
|
|
.as_ref();
|
|
if path_format.is_none() {
|
|
return None;
|
|
}
|
|
path_format.unwrap().get(name).map(|s| {
|
|
let path = s.clone();
|
|
let file_path = { FILE_PATH_ROOT.lock().unwrap().clone() };
|
|
let path = if path.starts_with("./") {
|
|
let file_root = file_root(&file_path, path.replace("./", ""));
|
|
file_root.map(|root| {
|
|
let splited = path.split_at(2);
|
|
root.join(PathBuf::from(splited.1))
|
|
})
|
|
} else {
|
|
Some(PathBuf::from(path))
|
|
};
|
|
|
|
let mut result_paths = Vec::new();
|
|
if let Some(path_uninit) = path {
|
|
let mut path_str = path_uninit.to_string_lossy().to_string();
|
|
let prefixs = get_prefix(&file_path, &path_str);
|
|
|
|
for (idx, prefix) in prefixs.iter().enumerate() {
|
|
if let Some(s) = prefix.as_ref() {
|
|
path_str = path_str.replacen("{prefix}", &s, 1);
|
|
}
|
|
}
|
|
|
|
let need_formated = datetime_format.captures_iter(&path_str).collect::<Vec<_>>();
|
|
let mut fore = self.fore_len;
|
|
let mut back = 1;
|
|
|
|
while fore > 0 {
|
|
let mut result_path = path_str.clone();
|
|
let t = current_time - self.step * fore as i32;
|
|
for need_format in need_formated.iter() {
|
|
let fmt = need_format.get(0).unwrap().as_str();
|
|
let t = t.format(fmt).to_string();
|
|
result_path = result_path.replace(fmt, &t);
|
|
}
|
|
|
|
if check_existed {
|
|
if max_retry_time == 0 {
|
|
break;
|
|
}
|
|
if !std::path::Path::new(&result_path).exists() {
|
|
max_retry_time = max_retry_time - 1;
|
|
continue;
|
|
} else {
|
|
result_paths.push((result_path.clone(), t));
|
|
}
|
|
} else {
|
|
result_paths.push((result_path.clone(), t));
|
|
}
|
|
fore = fore - 1;
|
|
}
|
|
|
|
while back < self.back_len + 1 {
|
|
let mut result_path = path_str.clone();
|
|
let t = current_time + self.step * back as i32;
|
|
for need_format in need_formated.iter() {
|
|
let fmt = need_format.get(0).unwrap().as_str();
|
|
let t = t.format(fmt).to_string();
|
|
result_path = result_path.replace(fmt, &t);
|
|
}
|
|
|
|
if check_existed {
|
|
if max_retry_time == 0 {
|
|
break;
|
|
}
|
|
if !std::path::Path::new(&result_path).exists() {
|
|
max_retry_time = max_retry_time - 1;
|
|
continue;
|
|
} else {
|
|
result_paths.push((result_path.clone(), t));
|
|
}
|
|
} else {
|
|
result_paths.push((result_path.clone(), t));
|
|
}
|
|
back = back + 1;
|
|
}
|
|
}
|
|
result_paths
|
|
})
|
|
}
|
|
}
|
|
|
|
fn file_root(path: &PathBuf, pat: String) -> Option<PathBuf> {
|
|
let new_pat = rereplace(&pat);
|
|
let path_str = path.to_string_lossy();
|
|
let re = Regex::new(&new_pat).unwrap();
|
|
let splited = re.split(&path_str);
|
|
let splited = splited.collect::<Vec<_>>();
|
|
if splited.len() == 2 {
|
|
let root = splited.first().unwrap();
|
|
Some(PathBuf::from(root))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn rereplace(pat: &str) -> String {
|
|
let mut result = pat.to_string();
|
|
for (k, v) in REREMAP.iter() {
|
|
result = result.replace(k, v);
|
|
}
|
|
result
|
|
}
|
|
|
|
fn get_prefix(path: &PathBuf, pat: &str) -> Vec<Option<String>> {
|
|
let replaced = rereplace(pat);
|
|
let path_str = path.to_string_lossy();
|
|
let re = Regex::new(&replaced).unwrap();
|
|
let prefixs = re.captures(&path_str).unwrap();
|
|
|
|
let mut prefixs = prefixs.iter().collect::<Vec<_>>();
|
|
prefixs.remove(0);
|
|
prefixs
|
|
.into_iter()
|
|
.map(|x| x.map(|v| v.as_str().to_string()))
|
|
.collect()
|
|
}
|