This commit is contained in:
2024-07-20 07:50:41 +08:00
parent 5221e5a59f
commit 2f4ae442e1
2 changed files with 124 additions and 16 deletions

View File

@@ -66,15 +66,16 @@ impl Config {
match self.get(s) {
Some(e) => match e {
Yaml::String(s) => Some(vec![s.to_owned()]),
Yaml::Array(s) => Some(s
.iter()
.filter_map(|s| match s {
Yaml::String(s) => Some(s.to_owned()),
Yaml::Integer(i) => Some(i.to_string()),
Yaml::Real(i) => Some(i.to_owned()),
_ => None,
})
.collect()),
Yaml::Array(s) => Some(
s.iter()
.filter_map(|s| match s {
Yaml::String(s) => Some(s.to_owned()),
Yaml::Integer(i) => Some(i.to_string()),
Yaml::Real(i) => Some(i.to_owned()),
_ => None,
})
.collect(),
),
_ => None,
},
None => None,
@@ -83,7 +84,10 @@ impl Config {
pub fn game_backuper_cfg(&self) -> Option<String> {
let mut pb = crate::utils::get_exe_path_else_current();
pb.push(self.get_str("game_backuper_cfg").unwrap_or("game_backuper.yml"));
pb.push(
self.get_str("game_backuper_cfg")
.unwrap_or("game_backuper.yml"),
);
if !pb.exists() {
return None;
}
@@ -110,10 +114,33 @@ impl Config {
}
pub fn pause_at_exit(&self) -> bool {
self.get_bool("pause_at_exit").map(|s| s.to_owned()).unwrap_or(false)
self.get_bool("pause_at_exit")
.map(|s| s.to_owned())
.unwrap_or(false)
}
pub fn pause_on_backup_error(&self) -> bool {
self.get_bool("pause_on_backup_error").map(|s| s.to_owned()).unwrap_or(false)
self.get_bool("pause_on_backup_error")
.map(|s| s.to_owned())
.unwrap_or(false)
}
pub fn rclone_exe(&self) -> String {
match self.get_str("rclone_exe") {
Some(s) => s.to_owned(),
None => String::from("game-backuper"),
}
}
pub fn rclone_remote(&self) -> Option<&str> {
self.get_str("rclone_remote")
}
pub fn rclone_local(&self) -> Option<&str> {
self.get_str("rclone_local")
}
pub fn rclone_flag(&self) -> Vec<String> {
self.get_str_vec("rclone_flag").unwrap_or(vec![])
}
}

View File

@@ -23,13 +23,19 @@ enum Error {
struct Main {
_cfg: cfg::Config,
_dryrun: bool,
_rclone_enable: bool,
_skip_restore: bool,
_backup_only: bool,
}
impl Main {
fn new(cfg: cfg::Config, dryrun: bool) -> Self {
fn new(cfg: cfg::Config, dryrun: bool, skip_restore: bool, backup_only: bool) -> Self {
Self {
_rclone_enable: cfg.rclone_remote().is_some() && cfg.rclone_local().is_some(),
_cfg: cfg,
_dryrun: dryrun,
_skip_restore: skip_restore,
_backup_only: backup_only,
}
}
@@ -57,6 +63,40 @@ impl Main {
};
if !ok {
println!("Backup failed: {:?}.", e);
if self._rclone_enable {
if !utils::ask_continue() {
return Err(Error::Exited);
}
return Ok(());
}
return Err(Error::Exited);
}
Ok(())
}
}
fn backup_rclone(&self) -> Result<(), Error> {
let mut cml = vec![self._cfg.rclone_exe(), String::from("sync")];
cml.push(self._cfg.rclone_local().unwrap().to_owned());
cml.push(self._cfg.rclone_remote().unwrap().to_owned());
cml.extend_from_slice(&self._cfg.rclone_flag());
if self._dryrun {
println!("Rclone backup command line: {:?}", cml);
Ok(())
} else {
let e = Self::call(cml)?;
let ok = match &e {
ExitStatus::Exited(c) => *c == 0,
_ => false,
};
if !ok {
println!("Rclone backup failed: {:?}.", e);
if self._rclone_enable {
if !utils::ask_continue() {
return Err(Error::Exited);
}
return Ok(());
}
return Err(Error::Exited);
}
Ok(())
@@ -100,10 +140,44 @@ impl Main {
}
}
fn restore_rclone(&self) -> Result<(), Error> {
let mut cml = vec![self._cfg.rclone_exe(), String::from("sync")];
cml.push(self._cfg.rclone_remote().unwrap().to_owned());
cml.push(self._cfg.rclone_local().unwrap().to_owned());
cml.extend_from_slice(&self._cfg.rclone_flag());
if self._dryrun {
println!("Rclone restore command line: {:?}", cml);
Ok(())
} else {
let e = Self::call(cml)?;
let ok = match &e {
ExitStatus::Exited(c) => *c == 0,
_ => false,
};
if !ok {
println!("Rclone restore failed: {:?}.", e);
if !utils::ask_continue() {
return Err(Error::Exited);
}
}
Ok(())
}
}
fn run(&self) -> Result<(), Error> {
self.restore()?;
self.run_exe()?;
if !self._skip_restore && !self._backup_only {
if self._rclone_enable {
self.restore_rclone()?;
}
self.restore()?;
}
if !self._backup_only {
self.run_exe()?;
}
self.backup()?;
if self._rclone_enable {
self.backup_rclone()?;
}
Ok(())
}
@@ -135,6 +209,8 @@ fn main() -> ExitCode {
opts.optflag("h", "help", "Print help message.");
opts.optopt("c", "config", "The location of config file.", "FILE");
opts.optflag("d", "dryrun", "Run without calling any process.");
opts.optflag("r", "skip-restore", "Skip restore backup.");
opts.optflag("b", "backup-only", "Backup only.");
let result = match opts.parse(&argv[1..]) {
Ok(m) => m,
Err(err) => {
@@ -162,7 +238,12 @@ fn main() -> ExitCode {
println!("game_exe need be set.");
return ExitCode::from(1);
}
let m = Main::new(cfg, result.opt_present("d"));
let m = Main::new(
cfg,
result.opt_present("d"),
result.opt_present("r"),
result.opt_present("b"),
);
let e = match m.run() {
Ok(_) => 0,
Err(e) => {