diff options
| -rw-r--r-- | src/main.rs | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs index e51cd03..194fbb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,13 @@ use std::{ env::var, - fs::File, - io::Cursor, + fs::{File, remove_file}, + io::Read, time::{Duration, UNIX_EPOCH}, }; use anyhow::Result; use clokwerk::{AsyncScheduler, Interval}; -use log::{error, info}; +use log::{debug, error, info}; use rpgpie::{ certificate::Certificate, message::{SignatureMode, encrypt}, @@ -18,6 +18,8 @@ use teloxide::{Bot, prelude::Requester, types::InputFile}; use tokio::time::sleep; const MAX_FILE_SIZE: usize = 50000000; +const BACKUP: &str = "backup"; +const BACKUP_ENCRYPTED: &str = "backup_encrypted"; #[tokio::main] async fn main() -> Result<()> { @@ -26,9 +28,7 @@ async fn main() -> Result<()> { let interval = var("INTERVAL")?.parse::<u32>()?; scheduler.every(Interval::Hours(interval)).run(|| async { - info!("Running a backup"); backup().await.unwrap(); - info!("Backup terminated"); }); info!("Program set to backup every {} hours", interval); @@ -43,6 +43,7 @@ async fn main() -> Result<()> { } async fn backup() -> Result<()> { + info!("Running a backup"); let chat_id = var("CHAT_ID").unwrap(); let locations: Vec<String> = var("LOCATIONS") .unwrap() @@ -51,15 +52,12 @@ async fn backup() -> Result<()> { .map(|s| s.to_string()) .collect(); - let tar_data = archive(&locations)?; - let encrypted_tar = encrypt_data("pub.txt", tar_data)?; + archive(&locations)?; + encrypt_data("pub.txt")?; + remove_file(BACKUP)?; let bot = Bot::from_env(); - let documents: Vec<InputFile> = encrypted_tar - .chunks(MAX_FILE_SIZE) - .enumerate() - .map(|(part, data)| InputFile::memory(data.to_vec()).file_name(format!("part_{:06}", part))) - .collect(); + let mut data_to_send = File::open(BACKUP_ENCRYPTED)?; bot.send_message( chat_id.clone(), @@ -67,9 +65,21 @@ async fn backup() -> Result<()> { ) .await?; - for x in documents { + let mut rr; + let mut part = 0; + loop { + let mut buf = vec![0; MAX_FILE_SIZE]; + rr = data_to_send.read(&mut buf)?; + debug!("Read {} bytes", rr); + + let data = InputFile::memory(buf).file_name(format!("part_{:06}", part)); + + if rr == 0 { + break; + } + loop { - match bot.send_document(chat_id.clone(), x.clone()).await { + match bot.send_document(chat_id.clone(), data.clone()).await { Ok(_) => break, Err(teloxide::RequestError::RetryAfter(n)) => { error!("Awaiting {} seconds", n.seconds()); @@ -81,22 +91,33 @@ async fn backup() -> Result<()> { } } } + info!("Sent part {}", part); + part += 1; } + + drop(data_to_send); + remove_file(BACKUP_ENCRYPTED)?; + + info!("Backup terminated"); Ok(()) } -fn archive(location: &[String]) -> Result<Vec<u8>> { - let mut b = Builder::new(Vec::new()); +fn archive(location: &[String]) -> Result<()> { + info!("Creating archive"); + let mut b = Builder::new(File::create(BACKUP)?); for loc in location { b.append_dir_all(loc, loc)?; } - Ok(b.into_inner()?) + b.finish()?; + info!("Archive created"); + Ok(()) } -fn encrypt_data(key_file: &str, message: Vec<u8>) -> Result<Vec<u8>> { +fn encrypt_data(key_file: &str) -> Result<()> { + info!("Encrypting archive"); let rec = Certificate::load(&mut File::open(key_file)?)?; - let mut plaintext = Cursor::new(message); - let mut output = Cursor::new(Vec::new()); + let mut plaintext = File::open(BACKUP)?; + let mut output = File::create(BACKUP_ENCRYPTED)?; encrypt( Some(Seipd::SEIPD2), rec, @@ -108,5 +129,6 @@ fn encrypt_data(key_file: &str, message: Vec<u8>) -> Result<Vec<u8>> { &mut output, false, )?; - Ok(output.into_inner()) + info!("Archive encrypted"); + Ok(()) } |
