From a8d1be9536bce6d6be2cf1586c8bac049e820d31 Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Sun, 8 Sep 2024 17:21:27 +0200 Subject: save files, real last modified check (doesn't work correctly) --- src/backup.rs | 126 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 50 deletions(-) (limited to 'src/backup.rs') diff --git a/src/backup.rs b/src/backup.rs index 8cc94f1..a643cb2 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -5,7 +5,6 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use gethostname::gethostname; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -20,10 +19,11 @@ pub type BackupId = String; #[derive(Debug, Serialize, Deserialize)] pub struct Backup { - id: String, + pub id: String, timestamp: u64, packages: Vec, - files: Vec, + pub files: Vec, + device: String, } impl Backup { @@ -33,63 +33,82 @@ impl Backup { files.push(PathInfo::from_path(config, dir)?); } Ok(Self { - // UUID not really needed, maybe a shorter hash + // TODO: UUID not really needed, maybe a shorter hash id: Uuid::new_v4().to_string(), timestamp: Self::get_timestamp(), packages, files, + device: config.device.clone(), }) } pub fn save(&self, config: &Config) -> Result<()> { - let rel_location = format!( - "{}_{}", - gethostname() - .into_string() - .map_err(|_| Error::InvalidOsString)?, - Self::get_timestamp() - ); - - let bl = BackupLocation { - id: self.id.to_string(), - rel_location, - }; - - Self::append_to_root_index(config, bl.clone())?; + println!("Save Backup {:?}", self.get_location(config)); + // println!("{self:#?}"); + self.get_location(config).append_to_root(config)?; - let backup_root = format!("{}/{}", config.root, bl.rel_location); + let backup_root = self.get_location(config).get_absolute_dir(config); create_dir_all(&backup_root).unwrap(); let path = format!("{}/index.json", backup_root); let mut f = File::create(path).unwrap(); f.write_all(&serde_json::to_vec(self).unwrap()).unwrap(); + for path in &self.files { + path.save(&backup_root)?; + } + Ok(()) } - pub fn get_index(config: &Config, id: Option) -> Result { + pub fn get_last(config: &Config) -> Result> { let backup_index_root = format!("{}/index.json", config.root); - let list: Vec = Self::get_json_content(&backup_index_root)?; - println!("{list:#?}"); - - let index_loc = if let Some(id) = id { - list.iter() - .find(|bl| bl.id == id) - .ok_or(Error::BackupNotFound)? - .rel_location - .clone() - } else { - list.last() - .ok_or(Error::BackupNotFound)? - .rel_location - .clone() + let list: Vec = match Self::get_json_content(&backup_index_root) { + Ok(list) => list, + Err(err) => { + if err.to_string() == "io: No such file or directory (os error 2)" { + return Ok(None); + }; + return Err(err); + } }; + Ok(Some(Self::from_index( + config, + list.last().ok_or(Error::BackupNotFound)?.id.clone(), + )?)) + } + + pub fn from_index(config: &Config, id: BackupId) -> Result { + let backup_index_root = format!("{}/index.json", config.root); + let list: Vec = Self::get_json_content(&backup_index_root)?; + let index_loc = list + .iter() + .find(|bl| bl.id == id) + .ok_or(Error::BackupNotFound)? + .rel_location + .clone(); + let path = format!("{}/{index_loc}/index.json", config.root); let index_file: Self = Self::get_json_content(&path)?; Ok(index_file) } + pub fn get_location(&self, config: &Config) -> BackupLocation { + let rel_location = format!("{}_{}", config.device, self.timestamp); + + BackupLocation { + id: self.id.to_string(), + rel_location, + } + } + + pub fn get_absolute_file_location(&self, config: &Config, rel_location: &str) -> String { + let loc = self.get_location(config).get_absolute_dir(config); + + format!("{}/{}", loc, rel_location) + } + fn get_json_content Deserialize<'a>>(path: &str) -> Result { let mut file = File::open(path)?; let mut content = String::new(); @@ -97,7 +116,26 @@ impl Backup { Ok(serde_json::from_str(&content)?) } - fn append_to_root_index(config: &Config, new_backup: BackupLocation) -> Result<()> { + fn get_timestamp() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BackupLocation { + id: BackupId, + rel_location: String, +} + +impl BackupLocation { + pub fn get_absolute_dir(&self, config: &Config) -> String { + format!("{}/{}", config.root, self.rel_location) + } + + pub fn append_to_root(&self, config: &Config) -> Result<()> { let backup_index_root = format!("{}/index.json", config.root); let path = PathBuf::from(&backup_index_root); if path.exists() { @@ -107,27 +145,15 @@ impl Backup { let mut loc: Vec = serde_json::from_str(&content)?; let mut f = File::create(path)?; - loc.push(new_backup); + loc.push(self.clone()); f.write_all(&serde_json::to_vec(&loc)?)?; } else { + create_dir_all(&config.root).unwrap(); let mut f = File::create(backup_index_root)?; - f.write_all(&serde_json::to_vec(&vec![new_backup])?)?; + f.write_all(&serde_json::to_vec(&vec![self])?)?; }; Ok(()) } - - fn get_timestamp() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -struct BackupLocation { - id: BackupId, - rel_location: String, } -- cgit v1.2.3