|
@@ -1,4 +1,10 @@
|
|
|
+use std::fs::{create_dir_all, File};
|
|
|
+use std::io::{Cursor, Read, Write};
|
|
|
use std::path::PathBuf;
|
|
|
+use flate2::Compression;
|
|
|
+use flate2::read::GzDecoder;
|
|
|
+use flate2::write::GzEncoder;
|
|
|
+use tar::{Archive, Builder, Header};
|
|
|
|
|
|
// Truncate a string, adding ellpises if it's too long
|
|
|
pub fn truncate_ellipsis(s: &str, n: usize) -> String {
|
|
@@ -26,3 +32,52 @@ pub const EPOCH: mail_parser::DateTime = mail_parser::DateTime {
|
|
|
tz_hour: 0,
|
|
|
tz_minute: 0,
|
|
|
};
|
|
|
+
|
|
|
+pub fn compress_and_save_file(dir_path: PathBuf, file_name: String, content: &[u8]) -> anyhow::Result<()>{
|
|
|
+ if !dir_path.exists() { create_dir_all(dir_path.clone()).ok(); }
|
|
|
+
|
|
|
+ let archive_path = dir_path.join(file_name.clone() + ".tar.gz");
|
|
|
+ let tar_gz = File::create(archive_path)?;
|
|
|
+ let enc = GzEncoder::new(tar_gz, Compression::default());
|
|
|
+ let mut tar = Builder::new(enc);
|
|
|
+
|
|
|
+ let mut header = Header::new_gnu();
|
|
|
+ header.set_path(&file_name)?;
|
|
|
+ header.set_size(content.len() as u64);
|
|
|
+ header.set_cksum();
|
|
|
+
|
|
|
+ let cursor = Cursor::new(content);
|
|
|
+
|
|
|
+ tar.append(&header, cursor)?;
|
|
|
+
|
|
|
+ let enc = tar.into_inner()?;
|
|
|
+ enc.finish()?;
|
|
|
+ Ok(())
|
|
|
+}
|
|
|
+
|
|
|
+pub fn read_and_decompress_file(archive_path: PathBuf, file_name: String) -> anyhow::Result<Vec<u8>> {
|
|
|
+ // Open the compressed archive file
|
|
|
+ let tar_gz = File::open(&archive_path)?;
|
|
|
+
|
|
|
+ // Create a GzDecoder to decompress the archive
|
|
|
+ let dec = GzDecoder::new(tar_gz);
|
|
|
+
|
|
|
+ // Create a tar archive for reading files from the decompressed stream
|
|
|
+ let mut archive = Archive::new(dec);
|
|
|
+
|
|
|
+ // Iterate over the entries in the archive
|
|
|
+ for entry in archive.entries()? {
|
|
|
+ let mut entry = entry?;
|
|
|
+
|
|
|
+ // Check if this entry is the file we're looking for
|
|
|
+ if entry.path()?.file_name().map_or(false, |name| name.to_owned().to_str().unwrap() == file_name) {
|
|
|
+ // Read the file's content into a buffer
|
|
|
+ let mut content = Vec::new();
|
|
|
+ entry.read_to_end(&mut content)?;
|
|
|
+
|
|
|
+ return Ok(content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Err(anyhow::anyhow!("File {} not found in the archive", file_name))
|
|
|
+}
|