kitab

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

commit 486942efb807b7f7d5b1e637f1ecd1d9a2843325
parent 9efbbf90a3328f613540f91e92ca0a1d8b6b0654
Author: lash <dev@holbrook.no>
Date:   Sat, 25 Jun 2022 08:54:25 +0000

Add mediatype, language, subject

Diffstat:
MCargo.toml | 2++
Msrc/dc/mod.rs | 18++++++++++++++++++
Msrc/meta.rs | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/rdf.rs | 47+++++++++++++++++++++++++++++++++++++++++------
4 files changed, 133 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -13,6 +13,8 @@ regex = "1.5.5" rio_turtle = "~0.7.1" rio_api = "~0.7.1" hex = "^0.4" +mime = "^0.3.13" +unic-langid-impl = "^0.9.0" [dependencies.biblatex] biblatex = "0.5.0" diff --git a/src/dc/mod.rs b/src/dc/mod.rs @@ -1,5 +1,23 @@ +use mime::Mime; +use unic_langid_impl::LanguageIdentifier; + + pub struct DCMetaData { pub title: String, pub author: String, pub subject: Option<String>, + pub mime: Option<Mime>, + pub language: Option<LanguageIdentifier>, +} + +impl DCMetaData { + pub fn new(title: &str, author: &str) -> DCMetaData { + DCMetaData{ + title: String::from(title), + author: String::from(author), + subject: None, + mime: None, + language: None, + } + } } diff --git a/src/meta.rs b/src/meta.rs @@ -2,6 +2,11 @@ use std::path; use std::fmt; use xattr; use hex; +use mime::{ + Mime +}; +use unic_langid_impl::LanguageIdentifier; +use std::str::FromStr; use crate::dc::DCMetaData; @@ -34,11 +39,7 @@ pub struct MetaData { impl MetaData { pub fn new(title: &str, author: &str, digest: Vec<u8>, filename: Option<FileName>) -> MetaData { - let dc:DCMetaData = DCMetaData{ - title: String::from(title), - author: String::from(author), - subject: None, - }; + let dc = DCMetaData::new(title, author); MetaData{ dc: dc, @@ -60,6 +61,42 @@ impl MetaData { self.dc.author.clone() } + pub fn set_subject(&mut self, v: &str) { + self.dc.subject = Some(String::from(v)); + } + + pub fn subject(&self) -> Option<String> { + return self.dc.subject.clone(); + } + + pub fn set_mime(&mut self, m: Mime) { + self.dc.mime = Some(m); + } + + pub fn set_mime_str(&mut self, s: &str) { + match Mime::from_str(s) { + Ok(v) => { + self.set_mime(v); + }, + Err(e) => { + panic!("invalid mime"); + }, + }; + } + + pub fn mime(&self) -> Option<Mime> { + self.dc.mime.clone() + } + + pub fn set_language(&mut self, s: &str) { + let v = s.parse().unwrap(); + self.dc.language = Some(v); + } + + pub fn language(&self) -> Option<LanguageIdentifier> { + self.dc.language.clone() + } + pub fn fingerprint(&self) -> String { hex::encode(&self.digest) } @@ -68,7 +105,7 @@ impl MetaData { let mut title: String = String::new(); let mut author: String = String::new(); - let mut subject: String = String::new(); + //let mut subject: String = String::new(); let filename: FileName; let title_src = xattr::get(filepath, "user.dcterms:title").unwrap(); @@ -95,7 +132,35 @@ impl MetaData { .into_string() .unwrap(); - MetaData::new(title.as_str(), author.as_str(), vec!(), Some(filename)) + let mut metadata = MetaData::new(title.as_str(), author.as_str(), vec!(), Some(filename)); + + match xattr::get(filepath, "user.dcterms:subject") { + Ok(v) => { + match v { + Some(v) => { + let s = std::str::from_utf8(&v).unwrap(); + metadata.set_subject(s); + }, + None => {}, + } + }, + _ => {}, + }; + + match xattr::get(filepath, "user.dcterms:MediaType") { + Ok(v) => { + match v { + Some(v) => { + let s = std::str::from_utf8(&v).unwrap(); + metadata.set_mime_str(s); + }, + None => {}, + } + }, + _ => {}, + } + + metadata } } diff --git a/src/rdf.rs b/src/rdf.rs @@ -17,11 +17,6 @@ use crate::meta::MetaData; pub fn write_rdf(entry: &MetaData, w: impl Write) -> Result<usize, std::io::Error> { - // TODO: parsers are apparently buggy, cannot decode dublin core rdf - //let mut f = File::open("../dublincore/dublin_core_terms.rdf").unwrap(); - //let mut parser = NTriplesParser::from_reader(f); - //let schema_graph: Graph = parser.decode().unwrap(); - let mut tfmt = TurtleFormatter::new(w); let urn_str = format!("URN:sha512:{}", entry.fingerprint()); @@ -41,6 +36,42 @@ pub fn write_rdf(entry: &MetaData, w: impl Write) -> Result<usize, std::io::Erro predicate: NamedNode { iri: "https://purl.org/dc/terms/creator" }.into(), object: Literal::Simple { value: entry.author().as_str() }.into(), }); + match entry.subject() { + Some(v) => { + tfmt.format(&Triple{ + subject: urn, + predicate: NamedNode { iri: "https://purl.org/dc/terms/subject" }.into(), + object: Literal::Simple { value: v.as_str() }.into(), + }); + }, + _ => (), + }; + + match entry.mime() { + Some(v) => { + let m: String = v.to_string(); + tfmt.format(&Triple{ + subject: urn, + predicate: NamedNode { iri: "https://purl.org/dc/terms/MediaType" }.into(), + object: Literal::Simple { value: m.as_str() }.into(), + }); + }, + _ => (), + }; + + match entry.language() { + Some(v) => { + let m: String = v.to_string(); + tfmt.format(&Triple{ + subject: urn, + predicate: NamedNode { iri: "https://purl.org/dc/terms/language" }.into(), + object: Literal::Simple { value: m.as_str() }.into(), + }); + }, + _ => (), + }; + + tfmt.finish(); Ok(0) } @@ -52,9 +83,13 @@ mod tests { #[test] fn test_write() { - let m = MetaData::new("foo", "bar", vec!(0x2a), None); + let mut m = MetaData::new("foo", "bar", vec!(0x2a), None); + 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); + println!(""); } }