commit 800291aa0fbd8c496da676b174626918a1e9678d
parent 3ce30bf68cb808f58f20359c9c6b95a2a5966c4d
Author: lash <dev@holbrook.no>
Date:   Sat, 25 Jun 2022 17:09:59 +0000
Calculate digest from file in from xattr
Diffstat:
2 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/src/meta.rs b/src/meta.rs
@@ -9,9 +9,15 @@ use sha2::{
     Sha512,
     Digest,
 };
+use std::fs::{
+    File,
+    metadata,
+};
+use std::io::Read;
 use unic_langid_impl::LanguageIdentifier;
 use biblatex::EntryType;
 use std::str::FromStr;
+use std::os::linux::fs::MetadataExt;
 
 use crate::dc::DCMetaData;
 
@@ -104,6 +110,22 @@ impl MetaData {
         hex::encode(&self.digest)
     }
 
+    fn digest_from_path(filepath: &path::Path) -> Vec<u8> {
+        let mut h = Sha512::new();
+        let st = metadata(filepath).unwrap();
+        let bs: u64 = st.st_blksize();
+        let sz: u64 = st.st_size();
+        let mut b: Vec<u8> = vec!(0; bs as usize);
+        let mut f = File::open(filepath).unwrap();
+        let mut i: usize = 0;
+        while i < sz as usize {
+            let c = f.read(&mut b).unwrap();
+            h.update(&b[..c]);
+            i += c;
+        }
+        h.finalize().to_vec()
+    }
+
     pub fn from_xattr(filepath: &path::Path) -> MetaData {
 
         let mut title: String = String::new();
@@ -111,6 +133,14 @@ impl MetaData {
         let mut typ: EntryType = EntryType::Unknown(String::new());
         let filename: FileName; 
 
+        let digest = MetaData::digest_from_path(filepath);
+
+        filename = filepath.file_name()
+            .unwrap()
+            .to_os_string()
+            .into_string()
+            .unwrap();
+
         let title_src = xattr::get(filepath, "user.dcterms:title").unwrap();
         match title_src {
             Some(v) => {
@@ -129,11 +159,6 @@ impl MetaData {
             None => {},
         }
 
-        filename = filepath.file_name()
-            .unwrap()
-            .to_os_string()
-            .into_string()
-            .unwrap();
 
         let typ_src = xattr::get(filepath, "user.dcterms:type").unwrap();
         match typ_src {
@@ -144,7 +169,7 @@ impl MetaData {
             None => {},
         }
 
-        let mut metadata = MetaData::new(title.as_str(), author.as_str(), typ, vec!(), Some(filename));
+        let mut metadata = MetaData::new(title.as_str(), author.as_str(), typ, digest, Some(filename));
 
         match xattr::get(filepath, "user.dcterms:subject") {
             Ok(v) => {
@@ -187,5 +212,6 @@ mod tests {
         let meta = MetaData::from_xattr(s);
         assert_eq!(meta.dc.title, "Bitcoin: A Peer-to-Peer Electronic Cash System");
         assert_eq!(meta.dc.author, "Satoshi Nakamoto");
+        assert_eq!(meta.fingerprint(), String::from("2ac531ee521cf93f8419c2018f770fbb42c65396178e079a416e7038d3f9ab9fc2c35c4d838bc8b5dd68f4c13759fe9cdf90a46528412fefe1294cb26beabf4e"));
     }
 }
diff --git a/src/rdf.rs b/src/rdf.rs
@@ -16,7 +16,7 @@ use rio_api::formatter::TriplesFormatter;
 use crate::meta::MetaData;
 
 
-pub fn write_rdf(entry: &MetaData, w: impl Write) -> Result<usize, std::io::Error> {
+pub fn write(entry: &MetaData, w: impl Write) -> Result<usize, std::io::Error> {
     let mut tfmt = TurtleFormatter::new(w);
     
     let urn_str = format!("URN:sha512:{}", entry.fingerprint());
@@ -83,7 +83,7 @@ pub fn write_rdf(entry: &MetaData, w: impl Write) -> Result<usize, std::io::Erro
 
 #[cfg(test)]
 mod tests {
-    use super::write_rdf;
+    use super::write;
     use super::MetaData;
     use std::io::stdout;
     use std::default::Default;
@@ -97,8 +97,7 @@ mod tests {
         m.set_subject("baz");
         m.set_mime_str("foo/bar");
         m.set_language("en-US");
-        //let v =  Vec::default();
         let v = stdout();
-        let r = write_rdf(&m, v);
+        let r = write(&m, v);
     }
 }