108 lines
2.9 KiB
Rust
108 lines
2.9 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use chrono::NaiveDateTime;
|
|
|
|
use crate::error::Result;
|
|
|
|
pub mod file;
|
|
pub mod ftps;
|
|
pub mod sftp;
|
|
|
|
pub trait RemoteBackupFile {
|
|
/// Type containing the location of the remote backup
|
|
type LocationType;
|
|
|
|
/// Get the underlying location type
|
|
fn location(&self) -> Self::LocationType;
|
|
|
|
/// Get the time the remote file was created
|
|
fn time_created(&self) -> chrono::NaiveDateTime;
|
|
|
|
/// Parse the time created from the file name
|
|
fn parse_file_name(file_name: &str) -> Option<chrono::NaiveDateTime> {
|
|
let time: Vec<&str> = file_name.split("_backup.tar.gz").collect();
|
|
|
|
if let Some(time_str) = time.get(0) {
|
|
chrono::NaiveDateTime::parse_from_str(time_str, "%d-%m-%y_%H.%M.%S").ok()
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait RemoteBackupSite {
|
|
/// Struct representing the location of a backup on the site
|
|
type FileType: RemoteBackupFile;
|
|
|
|
/// Backup a file to the the remote site
|
|
fn backup_to_remote(&mut self, file: PathBuf) -> Result<()>;
|
|
|
|
/// Get the locations backups contained on the remote site
|
|
fn get_backups(&mut self) -> Result<Vec<Self::FileType>>;
|
|
|
|
/// Remove a backup from the side
|
|
fn remove_backup(&mut self, backup: Self::FileType) -> Result<()>;
|
|
|
|
/// Number of backups to keep on the site
|
|
fn backups_to_keep(&self) -> usize;
|
|
|
|
/// Cleanup old backups on the remote site
|
|
fn cleanup(&mut self) -> Result<usize> {
|
|
let mut backups = self.get_backups()?;
|
|
|
|
backups.sort_by_key(|backup| backup.time_created());
|
|
|
|
let mut backups: Vec<Self::FileType> = backups.into_iter().rev().collect();
|
|
|
|
let mut removed_count: usize = 0;
|
|
if backups.len() > self.backups_to_keep() {
|
|
for _ in 0..(backups.len() - self.backups_to_keep()) {
|
|
if let Some(backup) = backups.pop() {
|
|
self.remove_backup(backup)?;
|
|
removed_count += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(removed_count)
|
|
}
|
|
}
|
|
|
|
/// Backup location that can be represented by a path
|
|
pub struct PathLocation {
|
|
location: PathBuf,
|
|
time_created: NaiveDateTime,
|
|
}
|
|
|
|
impl PathLocation {
|
|
/// New PathLocation
|
|
fn new(path: PathBuf) -> Option<Self> {
|
|
if let Some(file_name) = path.file_name() {
|
|
let file_name = file_name.to_str().unwrap();
|
|
|
|
if let Some(time) = Self::parse_file_name(file_name) {
|
|
Some(Self {
|
|
location: path,
|
|
time_created: time,
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RemoteBackupFile for PathLocation {
|
|
type LocationType = PathBuf;
|
|
|
|
fn location(&self) -> Self::LocationType {
|
|
self.location.to_path_buf()
|
|
}
|
|
|
|
fn time_created(&self) -> NaiveDateTime {
|
|
self.time_created
|
|
}
|
|
}
|