Skip to content

Commit

Permalink
Add Compression levels
Browse files Browse the repository at this point in the history
Compression levels
  • Loading branch information
andrew121410 authored Sep 29, 2023
2 parents da162af + b040791 commit 5eab239
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ By default, it will use tar.gz, unless specified otherwise.

### Optional Backup Arguments
1. --format `The format to use (tar.gz, tar.zst, zip)`
2. --level `The compression level to use (tar.gz 0-9) (tar.zst 1-22) (zip 0-9)`
2. --exclude `Excludes files from the backup`
3. --sftp `Uploads the backup to a SFTP server. Example 1: --sftp user@host:22 /remote/path Example 2: --sftp "user@host:22 path/to/key /remote/path"` (**Password Authentication is not supported.**)
4. --delete-after-upload `Deletes the backup after uploading it to the SFTP server.`
Expand Down
55 changes: 51 additions & 4 deletions src/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,32 @@ pub struct Backup {
backup_directory: PathBuf,
backup_format: BackupFormat,
exclude: Option<String>,
compression_level: Option<i64>,
}

impl Backup {
pub fn new(name: String, directory_to_backup: String, backup_directory: PathBuf, backup_format: BackupFormat, exclude: Option<String>) -> Self {
pub fn new(name: String, directory_to_backup: String, backup_directory: PathBuf, backup_format: BackupFormat, exclude: Option<String>, compression_level: Option<i64>) -> Self {
Backup {
name,
directory_to_backup,
backup_directory,
backup_format,
exclude,
compression_level,
}
}

pub fn backup(&self) -> Result<Backup_Result, Error> {
let timestamp = chrono::Local::now().format("%-m-%-d-%Y");

// The extension of the backup archive
let extension = match self.backup_format {
BackupFormat::TarGz => "tar.gz",
BackupFormat::TarZst => "tar.zst",
BackupFormat::Zip => "zip",
};

// Check if the compression format is installed
match self.backup_format {
BackupFormat::TarGz => {
if !self.does_tar_command_exist() {
Expand Down Expand Up @@ -80,7 +84,7 @@ impl Backup {
println!("{}", format!("Please wait while the backup is being created...").yellow());

// Create compressed tar or zip archive of the Minecraft server files
let mut cmd: Command = Command::new("tar");
let mut cmd = Command::new("tar");
match self.backup_format {
BackupFormat::TarGz | BackupFormat::TarZst => {
// You may exclude files and folders by splitting them with a : (colon)
Expand All @@ -94,9 +98,39 @@ impl Backup {
}

if self.backup_format == BackupFormat::TarZst {
cmd.arg("--zstd").arg("-cf"); // c = create, f = file
// If we have a compression level, use it
if self.compression_level.is_some() {
let compression_level = self.compression_level.unwrap();

// Check if the compression level is between 1 and 22
if compression_level < 1 || compression_level > 22 {
return Err(Error::new(ErrorKind::Other, "The compression level must be between 1 and 22"));
}

// Compression level 20 to 22 uses --ultra
if compression_level >= 20 {
cmd.args(&["-I", &format!("zstd --ultra -{}", compression_level)]);
} else {
cmd.args(&["-I", &format!("zstd -{}", compression_level)]);
}
} else { // If we don't have a compression level, use the default
cmd.arg("--zstd");
}
cmd.arg("-cf"); // c = create, f = file
} else {
cmd.arg("-czf"); // c = create, z = gzip, f = file
// If we have a compression level, use it
if self.compression_level.is_some() {
let compression_level = self.compression_level.unwrap();

// Check if the compression level is between 1 and 9
if compression_level < 1 || compression_level > 9 {
return Err(Error::new(ErrorKind::Other, "The compression level must be between 1 and 9"));
}

cmd.args(&["-I", &format!("gzip -{}", compression_level), "-cf"]);
} else { // If we don't have a compression level, use the default
cmd.arg("-czf"); // c = create, z = gzip, f = file
}
}
cmd.arg(&backup_path);

Expand All @@ -110,6 +144,19 @@ impl Backup {
}
BackupFormat::Zip => {
cmd = Command::new("zip");

// If we have a compression level, use it
if self.compression_level.is_some() {
let compression_level = self.compression_level.unwrap();

// Check if the compression level is between 1 and 9
if compression_level < 1 || compression_level > 9 {
return Err(Error::new(ErrorKind::Other, "The compression level must be between 1 and 9"));
}

cmd.arg(format!("-{}", compression_level));
}

cmd.arg("-r").arg(&backup_path);

// You may backup multiple folders by splitting them with a : (colon)
Expand Down
22 changes: 18 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,13 @@ async fn main() {
.action(ArgAction::Set)
.required(false)
.default_value("tar.gz")
.value_parser(["zip", "tar.gz"]))
.value_parser(["tar.gz", "tar.zst", "zip"]))
.arg(clap::Arg::new("level")
.help("The compression level to use")
.long("level")
.action(ArgAction::Set)
.required(false)
.value_parser(clap::value_parser!(i64)))
.arg(clap::Arg::new("sftp")
.help("The SFTP server to backup to")
.long("sftp")
Expand Down Expand Up @@ -328,9 +334,8 @@ async fn handle_backup(backup_matches: &ArgMatches) {
let to_backup = backup_matches.get_one::<String>("to_backup").unwrap();
let backup_folder = backup_matches.get_one::<String>("backup_folder").unwrap();
let format = backup_matches.get_one::<String>("format").unwrap();
let exclude: Option<&String> = backup_matches.get_one::<String>("exclude");

// Lazy to mess with lifetimes so I'm just going to do this Lol..
let exclude: Option<&String> = backup_matches.get_one::<String>("exclude");
let mut exclude_ours: Option<String> = None;
match exclude {
Some(string) => {
Expand All @@ -339,6 +344,15 @@ async fn handle_backup(backup_matches: &ArgMatches) {
_ => {}
}

let compression_level: Option<&i64> = backup_matches.get_one::<i64>("level");
let mut compression_level_ours: Option<i64> = None;
match compression_level {
Some(level) => {
compression_level_ours = Some(level.to_owned());
}
_ => {}
}

let mut backup_format: BackupFormat = BackupFormat::TarGz;
if format.eq("tar.zst") {
backup_format = BackupFormat::TarZst;
Expand All @@ -347,7 +361,7 @@ async fn handle_backup(backup_matches: &ArgMatches) {
}

let backup_folder_pathbuf = current_path.join(backup_folder);
let backup = backup::Backup::new(name.to_string(), to_backup.to_string(), backup_folder_pathbuf, backup_format, exclude_ours);
let backup = backup::Backup::new(name.to_string(), to_backup.to_string(), backup_folder_pathbuf, backup_format, exclude_ours, compression_level_ours);

let time = Instant::now();

Expand Down

0 comments on commit 5eab239

Please sign in to comment.