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!("");
}
}