Albatross/src/remote/ftp.rs

74 lines
2.0 KiB
Rust

use ftp::FtpStream;
use std::path::PathBuf;
use crate::config::RemoteBackupConfig;
use crate::error;
use crate::error::AlbatrossError;
use crate::remote::{PathLocation, RemoteBackupSite};
/// FTP Remote Site
pub struct FTPBackup {
/// FTP command stream
stream: FtpStream,
/// Remote target directory
target_dir: PathBuf,
/// Number of backups to keep
backups_to_keep: usize,
}
impl FTPBackup {
/// New FTPBackup
pub fn new(config: &RemoteBackupConfig) -> error::Result<Self> {
let ftp_config = config
.ftp
.as_ref()
.ok_or_else(|| AlbatrossError::RemoteConfigError("FTP".to_string()))?;
let mut ftp_stream = FtpStream::connect(&ftp_config.server_addr)?;
ftp_stream.login(&ftp_config.username, &ftp_config.password)?;
Ok(Self {
stream: ftp_stream,
target_dir: ftp_config.remote_dir.clone(),
backups_to_keep: config.backups_to_keep as usize,
})
}
}
impl Drop for FTPBackup {
fn drop(&mut self) {
self.stream.quit().ok();
}
}
impl RemoteBackupSite for FTPBackup {
type FileType = PathLocation;
fn backup_to_remote(&mut self, file: PathBuf) -> error::Result<()> {
let mut local_file = std::fs::File::open(&file)?;
let location = self.target_dir.join(file.file_name().unwrap());
self.stream
.put(location.to_str().unwrap(), &mut local_file)?;
Ok(())
}
fn get_backups(&mut self) -> error::Result<Vec<Self::FileType>> {
let files = self.stream.nlst(Some(self.target_dir.to_str().unwrap()))?;
Ok(files
.into_iter()
.filter_map(|file| Self::FileType::new(PathBuf::from(file)))
.collect())
}
fn remove_backup(&mut self, backup: Self::FileType) -> error::Result<()> {
Ok(self.stream.rm(backup.location.to_str().unwrap())?)
}
fn backups_to_keep(&self) -> usize {
self.backups_to_keep
}
}