commit 6db9b48a418302ee4a70aa107dca9ca97a82f52b
parent 36222c60cb22257287cbf0ab78b766c733d18eae
Author: lash <dev@holbrook.no>
Date:   Sun, 25 Sep 2022 11:02:06 +0000
WIP set digest by arg and multiple digest add for biblatex
Diffstat:
4 files changed, 126 insertions(+), 44 deletions(-)
diff --git a/src/biblatex.rs b/src/biblatex.rs
@@ -15,29 +15,40 @@ use biblatex::{
 
 use crate::meta::MetaData;
 use crate::error::ParseError;
+use crate::digest::RecordDigest;
+use crate::digest::from_urn;
 
-fn parse_digest(entry: &Entry) -> Vec<u8> {
+fn parse_digest(entry: &Entry) -> RecordDigest {
     let note = entry.get("note").unwrap();
     let note_s = String::from_chunks(note).unwrap();
     let mut digest_val = note_s.split(":");
 
-    let mut digest = Vec::new();
+    //let mut digest = Vec::new();
+    let mut digest: RecordDigest = RecordDigest::Empty;
 
     match digest_val.next() {
         Some(v) => {
-            if v == "sha512" {
-                let digest_hex = digest_val.next().unwrap();
-                let mut digest_imported = hex::decode(digest_hex).unwrap();
-                digest.append(&mut digest_imported);
-                debug!("parsed digest {}", hex::encode(&digest));
-            }
+//            if v == "sha512" {
+//                let digest_hex = digest_val.next().unwrap();
+//                let mut digest_imported = hex::decode(digest_hex).unwrap();
+//                digest.append(&mut digest_imported);
+//                debug!("parsed digest {}", hex::encode(&digest));
+//            }
+                match from_urn(v) {
+                    Ok(r) => {
+                        digest = r;
+                    },
+                    Err(e) => {
+                        debug!("note for entry {:?} is not a digest url", &entry);
+                    },
+                }
         },
         None => {},
     };
     
-    if digest.len() == 0 {
-        digest.resize(64, 0);
-    }
+//    if digest.len() == 0 {
+//        digest.resize(64, 0);
+//    }
 
     digest
 }
@@ -49,7 +60,7 @@ fn parse_digest(entry: &Entry) -> Vec<u8> {
 /// # Arguments 
 ///
 /// * `r` - reader implementation providing the source.
-pub fn read_all(mut r: impl Read) -> Result<Vec<MetaData>, ParseError> {
+pub fn read_all(mut r: impl Read, digests: &Vec<RecordDigest>) -> Result<Vec<MetaData>, ParseError> {
     let mut s = String::new();
     let c = r.read_to_string(&mut s);
     let bib = match Bibliography::parse(&s) {
@@ -77,30 +88,57 @@ pub fn read_all(mut r: impl Read) -> Result<Vec<MetaData>, ParseError> {
             }
             format!("{}, {}", x, y)
         });
+
+        let mut use_digests: Vec<RecordDigest> = vec!();
         let digest = parse_digest(&e);
+        match digest {
+            RecordDigest::Empty => {
+            },
+            RecordDigest::Sha512(r) => {
+                use_digests.push(RecordDigest::Sha512(r));
+            },
+            RecordDigest::Sha256(r) => {
+                use_digests.push(RecordDigest::Sha256(r));
+            },
+            RecordDigest::MD5(r) => {
+                use_digests.push(RecordDigest::MD5(r));
+            },
+            RecordDigest::SwarmHash(r) => {
+                use_digests.push(RecordDigest::SwarmHash(r));
+            },
+
+//            RecordDigest::Sha512(r) => {
+//                use_digests.push(digest);
+//            },
+//            RecordDigest::MD5(r) => {
+//                use_digests.push(digest);
+//            },
+        }
 
         let title = e.title().unwrap();
         let title_s = String::from_chunks(title).unwrap();
 
-        let mut m = MetaData::new(title_s.as_str(), authors_s.as_str(), e.entry_type.clone(), digest, None);
+        for dd in use_digests.into_iter() {
+            let mut m = MetaData::new(title_s.as_str(), authors_s.as_str(), e.entry_type.clone(), dd, None);
 
-        match e.keywords() {
-            Ok(v) => {
-                let s = String::from_chunks(v).unwrap();
-                m.set_subject(s.as_str());
-            },
-            _ => {},
-        };
+            match e.keywords() {
+                Ok(v) => {
+                    let s = String::from_chunks(v).unwrap();
+                    m.set_subject(s.as_str());
+                },
+                _ => {},
+            };
 
-        match e.language() {
-            Ok(v) => {
-                m.set_language(v.as_str());
-            },
-            _ => {},
-        }
+            match e.language() {
+                Ok(v) => {
+                    m.set_language(v.as_str());
+                },
+                _ => {},
+            }
 
-        debug!("read metadata {:?}", &m);
-        rr.push(m);
+            debug!("read metadata {:?}", &m);
+            rr.push(m);
+        }
     }
     Ok(rr)
 }
diff --git a/src/digest.rs b/src/digest.rs
@@ -12,6 +12,7 @@ use log::error;
 pub enum RecordDigest {
     Sha512(Vec<u8>),
     Sha256(Vec<u8>),
+    MD5(Vec<u8>),
     SwarmHash(Vec<u8>),
     Empty,
 }
@@ -62,6 +63,16 @@ pub fn from_urn(urn: &str) -> Result<RecordDigest, ParseError> {
 
             RecordDigest::Sha256(digest)
         },
+        Some("md5") => {
+            let digest_hex = v.next().unwrap();
+            let digest = hex::decode(digest_hex).unwrap();
+
+            if digest.len() != 16 {
+                return Err(ParseError);
+            }
+
+            RecordDigest::MD5(digest)
+        },
         Some("bzz") => {
             let digest_hex = v.next().unwrap();
             let digest = hex::decode(digest_hex).unwrap();
diff --git a/src/main.rs b/src/main.rs
@@ -40,6 +40,8 @@ use kitab::meta::{
     MetaData,
     digest_from_path,
 };
+use kitab::digest::from_urn;
+use kitab::digest::RecordDigest;
 
 
 fn args_setup() -> ArgMatches<'static> {
@@ -60,10 +62,18 @@ fn args_setup() -> ArgMatches<'static> {
         .version("0.0.1")
         );
     o_import = o_import.arg(
+        Arg::with_name("setdigest")
+        .short("d")
+        .long("digest")
+        .help("Explicitly set digest")
+        .multiple(true)
+        .takes_value(true)
+        .number_of_values(1)
+        );
+    o_import = o_import.arg(
         Arg::with_name("PATH")
         .help("Path to operate on")
         .required(true)
-        .index(1)
         );
     o = o.subcommand(o_import);
 
@@ -204,9 +214,9 @@ fn exec_import_rdf(f: &Path, index_path: &Path) -> bool {
     true
 }
 
-fn exec_import_biblatex(f: &Path, index_path: &Path) -> bool {
+fn exec_import_biblatex(f: &Path, index_path: &Path, digests: &Vec<RecordDigest>) -> bool {
     let f = File::open(f).unwrap();
-    let entries = match biblatex_read_all(&f) {
+    let entries = match biblatex_read_all(&f, digests) {
         Ok(v) => {
             v
         },
@@ -250,7 +260,7 @@ fn exec_apply(p: &Path, index_path: &Path) -> bool {
     true
 }
 
-fn exec_import(p: &Path, index_path: &Path) {
+fn exec_import(p: &Path, index_path: &Path, digests: Vec<RecordDigest>) {
     for entry in WalkDir::new(&p)
         .into_iter()
         .filter_map(Result::ok)
@@ -258,6 +268,7 @@ fn exec_import(p: &Path, index_path: &Path) {
 
         let fp = entry.path();
         debug!("attempt xattr import {:?}", fp);
+        //if exec_import_xattr(fp, index_path, &digests) {
         if exec_import_xattr(fp, index_path) {
             continue;
         }
@@ -269,12 +280,13 @@ fn exec_import(p: &Path, index_path: &Path) {
         }
 
         debug!("attempt rdf import {:?}", fp);
-        if exec_import_rdf(fp, index_path) {
+        //if exec_import_rdf(fp, index_path, &digests) {
+        if exec_import_rdf(fp, index_path) { 
             continue;
         } 
 
         debug!("attempt biblatex import {:?}", fp);
-        if exec_import_biblatex(fp, index_path) {
+        if exec_import_biblatex(fp, index_path, &digests) {
             continue;
         }
     }
@@ -294,15 +306,32 @@ fn main() {
 
     let index_dir = resolve_directory(&args);
     info!("have index directory {:?}", &index_dir);
-    
+   
     match args.subcommand_matches("import") {
-        Some(v) => {
-            let p = str_to_path(v);
+        Some(arg) => {
+            let p = str_to_path(&arg);
+            let mut digests: Vec<RecordDigest> = Vec::new();
+            match arg.values_of("setdigest") {
+                Some(r) => {
+                    for digest_str in r {
+                        match from_urn(&digest_str) {
+                            Ok(digest) => {
+                                info!("using digest {}", digest_str);
+                                digests.push(digest);
+                            },
+                            Err(e) => {
+                                panic!("invalid digest URN: {:?}", e);
+                            },
+                        }
+                    }
+                },
+                None => {},
+            };
             info!("import from path {:?}", &p);
-            return exec_import(&p, index_dir.as_path());
+            return exec_import(&p, index_dir.as_path(), digests);
         },
         _ => {},
-    }
+    };
 
 
     let mut r = true;
diff --git a/src/meta.rs b/src/meta.rs
@@ -20,10 +20,11 @@ use std::io::{
     BufReader,
 };
 use unic_langid_impl::LanguageIdentifier;
-use biblatex::EntryType;
 use std::str::FromStr;
 use std::os::linux::fs::MetadataExt;
 
+use biblatex::EntryType;
+
 #[cfg(feature = "magic")]
 use tree_magic;
 
@@ -96,7 +97,7 @@ impl MetaData {
     /// * `entry_type` - Maps to the [DCMetaData::typ] field.
     /// * `digest` - The digest of the media file.
     /// * `filename` - The client's optional local file name for the media.
-    pub fn new(title: &str, author: &str, entry_type: EntryType, digest: Vec<u8>, filename: Option<FileName>) -> MetaData {
+    pub fn new(title: &str, author: &str, entry_type: EntryType, digest: digest::RecordDigest, filename: Option<FileName>) -> MetaData {
         let dc = DCMetaData::new(title, author, entry_type);
 
         let mut m = MetaData{
@@ -134,8 +135,8 @@ impl MetaData {
 
     /// Set the digest as [digest::RecordDigest::Sha512](digest::RecordDigest::Sha512) instance of the provided
     /// fingerprint.
-    pub fn set_fingerprint(&mut self, fingerprint: Vec<u8>) {
-        self.digest = digest::from_vec(fingerprint).unwrap();
+    pub fn set_fingerprint(&mut self, fingerprint: digest::RecordDigest) {
+        self.digest = fingerprint; //digest::from_vec(fingerprint).unwrap();
     }
 
     /// Set the digest from the given URN string.
@@ -220,6 +221,9 @@ impl MetaData {
             digest::RecordDigest::Sha256(v) => {
                 return hex::encode(&v);
             },
+            digest::RecordDigest::MD5(v) => {
+                return hex::encode(&v);
+            },
             digest::RecordDigest::SwarmHash(v) => {
                 return hex::encode(&v);
             },
@@ -279,7 +283,7 @@ impl MetaData {
             None => {},
         }
 
-        let mut metadata = MetaData::new(title.as_str(), author.as_str(), typ, digest, Some(filename));
+        let mut metadata = MetaData::new(title.as_str(), author.as_str(), typ, digest::RecordDigest::Sha512(digest), Some(filename));
         if !metadata.validate() {
             return Err(ParseError{});
         }