kitab

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | LICENSE

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:
Msrc/biblatex.rs | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/digest.rs | 11+++++++++++
Msrc/main.rs | 51++++++++++++++++++++++++++++++++++++++++-----------
Msrc/meta.rs | 14+++++++++-----
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{}); }