commit 486942efb807b7f7d5b1e637f1ecd1d9a2843325
parent 9efbbf90a3328f613540f91e92ca0a1d8b6b0654
Author: lash <dev@holbrook.no>
Date:   Sat, 25 Jun 2022 08:54:25 +0000
Add mediatype, language, subject
Diffstat:
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!("");
     }
 }