]> OzVa Git service - ozva-cloud/commitdiff
feat: add timestamp metadata to generated zip file (#204)
authorsigoden <sigoden@gmail.com>
Fri, 31 Mar 2023 15:48:23 +0000 (23:48 +0800)
committerGitHub <noreply@github.com>
Fri, 31 Mar 2023 15:48:23 +0000 (23:48 +0800)
Cargo.lock
Cargo.toml
src/server.rs
src/utils.rs

index 42fe37cd1c1af05ea24bea6b2b8487c07ddfb749..b71b5b8f8a41d9261047f4ee6f899a745629a050 100644 (file)
@@ -127,6 +127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2105142db9c6203b9dadc83b0553394589a6cb31b1449a3b46b42f47c3434d0"
 dependencies = [
  "async-compression",
+ "chrono",
  "crc32fast",
  "log",
  "pin-project",
index 6a3de36fbe32f555c26058939134330d18e3f59a..1839bfd814c574549caacae84533a6c8c13d0674 100644 (file)
@@ -22,7 +22,7 @@ serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 futures = "0.3"
 base64 = "0.21"
-async_zip = { version = "0.0.12", default-features = false, features = ["deflate"] }
+async_zip = { version = "0.0.12", default-features = false, features = ["deflate", "chrono"] }
 headers = "0.3"
 mime_guess = "2.0"
 if-addrs = "0.10.1"
index d43b4503e58cd73f6af5b4b95ea67039933400d6..f6e712a05041648a3537ac6ec61f10be7957d0a1 100644 (file)
@@ -1,12 +1,14 @@
 use crate::streamer::Streamer;
-use crate::utils::{decode_uri, encode_uri, get_file_name, glob, try_get_file_name};
+use crate::utils::{
+    decode_uri, encode_uri, get_file_mtime_and_mode, get_file_name, glob, try_get_file_name,
+};
 use crate::Args;
 use anyhow::{anyhow, Result};
 use walkdir::WalkDir;
 use xml::escape::escape_str_pcdata;
 
 use async_zip::write::ZipFileWriter;
-use async_zip::{Compression, ZipEntryBuilder};
+use async_zip::{Compression, ZipDateTime, ZipEntryBuilder};
 use chrono::{LocalResult, TimeZone, Utc};
 use futures::TryStreamExt;
 use headers::{
@@ -1286,8 +1288,10 @@ async fn zip_dir<W: AsyncWrite + Unpin>(
             Some(v) => v,
             None => continue,
         };
-        let builder =
-            ZipEntryBuilder::new(filename.into(), Compression::Deflate).unix_permissions(0o644);
+        let (datetime, mode) = get_file_mtime_and_mode(&zip_path).await?;
+        let builder = ZipEntryBuilder::new(filename.into(), Compression::Deflate)
+            .unix_permissions(mode)
+            .last_modification_date(ZipDateTime::from_chrono(&datetime));
         let mut file = File::open(&zip_path).await?;
         let mut file_writer = writer.write_entry_stream(builder).await?;
         io::copy(&mut file, &mut file_writer).await?;
index bfede94f6c624237e4f7a0f4e7665fb9205f2ae3..294867924d1b43f17f12930b4e60b9322eb36390 100644 (file)
@@ -1,4 +1,5 @@
 use anyhow::{anyhow, Context, Result};
+use chrono::{DateTime, Utc};
 use std::{
     borrow::Cow,
     path::Path,
@@ -28,6 +29,21 @@ pub fn get_file_name(path: &Path) -> &str {
         .unwrap_or_default()
 }
 
+#[cfg(unix)]
+pub async fn get_file_mtime_and_mode(path: &Path) -> Result<(DateTime<Utc>, u16)> {
+    use std::os::unix::prelude::MetadataExt;
+    let meta = tokio::fs::metadata(path).await?;
+    let datetime: DateTime<Utc> = meta.modified()?.into();
+    Ok((datetime, meta.mode() as u16))
+}
+
+#[cfg(not(unix))]
+pub async fn get_file_mtime_and_mode(path: &Path) -> Result<(DateTime<Utc>, u16)> {
+    let meta = tokio::fs::metadata(&path).await?;
+    let datetime: DateTime<Utc> = meta.modified()?.into();
+    Ok((datetime, 0o644))
+}
+
 pub fn try_get_file_name(path: &Path) -> Result<&str> {
     path.file_name()
         .and_then(|v| v.to_str())