[niepce/lr-import: 11/20] Update to exempi2
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce/lr-import: 11/20] Update to exempi2
- Date: Mon, 20 Dec 2021 05:37:15 +0000 (UTC)
commit 0dda6a7a9e86d52d54dfd38fea8b22007a6a7bdc
Author: Hubert Figuière <hub figuiere net>
Date: Sun Dec 5 21:20:48 2021 -0500
Update to exempi2
Cargo.lock | 24 +++---
crates/npc-engine/Cargo.toml | 2 +-
crates/npc-engine/src/db/libmetadata.rs | 124 +++++++++++++++------------
crates/npc-engine/src/db/library.rs | 4 +-
crates/npc-fwk/Cargo.toml | 2 +-
crates/npc-fwk/src/base/date.rs | 8 +-
crates/npc-fwk/src/lib.rs | 2 +-
crates/npc-fwk/src/utils/exempi.rs | 147 ++++++++++++++------------------
crates/npc-fwk/src/utils/exiv2.rs | 32 +++----
9 files changed, 172 insertions(+), 173 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index f7874ed..1cb9755 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -221,22 +221,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
[[package]]
-name = "exempi"
-version = "2.6.0"
-source =
"git+https://github.com/hfiguiere/exempi-rs.git?rev=99e8ba5#99e8ba58318d693bdc7aecce1ca6375a3e11d89f"
+name = "exempi-sys"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "092ed317836115f2a074e1fcc8ed9b2ced33bc7af1e71512cd4aa3a5be696e37"
dependencies = [
- "bitflags",
- "exempi-sys",
"libc",
+ "pkg-config",
]
[[package]]
-name = "exempi-sys"
-version = "2.5.0"
-source =
"git+https://github.com/hfiguiere/exempi-rs.git?rev=99e8ba5#99e8ba58318d693bdc7aecce1ca6375a3e11d89f"
+name = "exempi2"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1deb5527e7a45f3ac714fc6cb78fa40e2be21a39824c93280deb71877216aa7d"
dependencies = [
+ "bitflags",
+ "exempi-sys",
"libc",
- "pkg-config",
]
[[package]]
@@ -774,7 +776,7 @@ dependencies = [
"cbindgen",
"chrono",
"clap",
- "exempi",
+ "exempi2",
"gdk-pixbuf",
"gdk-pixbuf-sys",
"gettext-rs 0.7.0",
@@ -795,7 +797,7 @@ dependencies = [
"cairo-rs",
"cbindgen",
"chrono",
- "exempi",
+ "exempi2",
"gdk",
"gdk-pixbuf",
"gdk-pixbuf-sys",
diff --git a/crates/npc-engine/Cargo.toml b/crates/npc-engine/Cargo.toml
index 2425eaf..69c5c1a 100644
--- a/crates/npc-engine/Cargo.toml
+++ b/crates/npc-engine/Cargo.toml
@@ -13,7 +13,7 @@ license = "GPL-3.0"
async-channel = "1.6.1"
clap = { version = "2.33.3", optional = true }
chrono = "0.4.19"
-exempi = { version = "2.6.0", git = "https://github.com/hfiguiere/exempi-rs.git", rev="99e8ba5" }
+exempi2 = { version = "0.1.1" }
gettext-rs = "0.7.0"
gdk-pixbuf-sys = "*"
gdk-pixbuf = "*"
diff --git a/crates/npc-engine/src/db/libmetadata.rs b/crates/npc-engine/src/db/libmetadata.rs
index f7d305d..30e71aa 100644
--- a/crates/npc-engine/src/db/libmetadata.rs
+++ b/crates/npc-engine/src/db/libmetadata.rs
@@ -29,11 +29,16 @@ use npc_fwk::{xmp_date_from, PropertyBag, PropertySet, PropertyValue, XmpMeta};
#[derive(Clone)]
pub struct LibMetadata {
- xmp: XmpMeta,
+ /// The XmpMeta block
+ xmp_meta: XmpMeta,
+ /// Library ID this is associated to.
id: LibraryId,
+ /// List of sidecards
pub sidecars: Vec<String>,
pub file_type: FileType,
+ /// name to be displayed
pub name: String,
+ /// Folder name for display
pub folder: String,
}
@@ -52,7 +57,7 @@ fn property_index_to_xmp(meta: Np) -> Option<IndexToXmp> {
impl LibMetadata {
pub fn new(id: LibraryId) -> LibMetadata {
LibMetadata {
- xmp: XmpMeta::new(),
+ xmp_meta: XmpMeta::new(),
id,
sidecars: vec![],
file_type: FileType::Unknown,
@@ -61,9 +66,10 @@ impl LibMetadata {
}
}
- pub fn new_with_xmp(id: LibraryId, xmp: XmpMeta) -> LibMetadata {
+ /// Create a LibMetadata with an XmpMeta.
+ pub fn new_with_xmp(id: LibraryId, xmp_meta: XmpMeta) -> LibMetadata {
LibMetadata {
- xmp,
+ xmp_meta,
id,
sidecars: vec![],
file_type: FileType::Unknown,
@@ -73,19 +79,20 @@ impl LibMetadata {
}
pub fn serialize_inline(&self) -> String {
- self.xmp.serialize_inline()
+ self.xmp_meta.serialize_inline()
}
fn get_metadata(&self, meta: Np) -> Option<PropertyValue> {
let index_to_xmp = property_index_to_xmp(meta)?;
- let mut prop_flags = exempi::PropFlags::default();
- let mut xmp_result =
- self.xmp
- .xmp
- .get_property(&index_to_xmp.ns, &index_to_xmp.property, &mut prop_flags);
- if xmp_result.is_ok() && prop_flags.contains(exempi::PropFlags::ARRAY_IS_ALTTEXT) {
- if let Ok((_, value)) = self.xmp.xmp.get_localized_text(
+ let mut prop_flags = exempi2::PropFlags::default();
+ let mut xmp_result = self.xmp_meta.xmp.get_property(
+ &index_to_xmp.ns,
+ &index_to_xmp.property,
+ &mut prop_flags,
+ );
+ if xmp_result.is_ok() && prop_flags.contains(exempi2::PropFlags::ARRAY_IS_ALTTEXT) {
+ if let Ok((_, value)) = self.xmp_meta.xmp.get_localized_text(
&index_to_xmp.ns,
&index_to_xmp.property,
"",
@@ -95,36 +102,42 @@ impl LibMetadata {
xmp_result = Ok(value);
}
}
- Some(PropertyValue::String(String::from(
- xmp_result.ok()?.to_str(),
- )))
+ Some(PropertyValue::String(String::from(&xmp_result.ok()?)))
}
pub fn set_metadata(&mut self, meta: Np, value: &PropertyValue) -> bool {
if let Some(ix) = property_index_to_xmp(meta) {
match *value {
PropertyValue::Empty => {
- return self.xmp.xmp.delete_property(&ix.ns, &ix.property).is_ok()
+ return self
+ .xmp_meta
+ .xmp
+ .delete_property(&ix.ns, &ix.property)
+ .is_ok()
}
PropertyValue::Int(i) => {
return self
+ .xmp_meta
.xmp
- .xmp
- .set_property_i32(&ix.ns, &ix.property, i, exempi::PropFlags::NONE)
+ .set_property_i32(&ix.ns, &ix.property, i, exempi2::PropFlags::NONE)
.is_ok()
}
PropertyValue::String(ref s) => {
if s.is_empty() {
- return self.xmp.xmp.delete_property(&ix.ns, &ix.property).is_ok();
- } else if self
- .xmp
- .xmp
- .set_property(&ix.ns, &ix.property, s, exempi::PropFlags::NONE)
- .is_err()
- {
- if exempi::get_error() == exempi::Error::BadXPath {
+ return self
+ .xmp_meta
+ .xmp
+ .delete_property(&ix.ns, &ix.property)
+ .is_ok();
+ } else if let Err(err) = self.xmp_meta.xmp.set_property(
+ &ix.ns,
+ &ix.property,
+ s,
+ exempi2::PropFlags::NONE,
+ ) {
+ if err == exempi2::Error(exempi2::XmpError::BadXPath) {
return self
- .xmp
+ .xmp_meta
.xmp
.set_localized_text(
&ix.ns,
@@ -132,7 +145,7 @@ impl LibMetadata {
"",
"x-default",
s,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)
.is_ok();
}
@@ -141,20 +154,25 @@ impl LibMetadata {
}
}
PropertyValue::StringArray(ref sa) => {
- if self.xmp.xmp.delete_property(&ix.ns, &ix.property).is_err() {
+ if self
+ .xmp_meta
+ .xmp
+ .delete_property(&ix.ns, &ix.property)
+ .is_err()
+ {
err_out!("Error deleting property {}", &ix.property);
return false;
}
for s in sa {
if self
- .xmp
+ .xmp_meta
.xmp
.append_array_item(
&ix.ns,
&ix.property,
- exempi::PropFlags::VALUE_IS_ARRAY,
+ exempi2::PropFlags::VALUE_IS_ARRAY,
s,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)
.is_err()
{
@@ -167,18 +185,18 @@ impl LibMetadata {
PropertyValue::Date(ref d) => {
let xmp_date = xmp_date_from(d);
return self
+ .xmp_meta
.xmp
- .xmp
- .set_property_date(&ix.ns, &ix.property, &xmp_date, exempi::PropFlags::NONE)
+ .set_property_date(
+ &ix.ns,
+ &ix.property,
+ &xmp_date,
+ exempi2::PropFlags::NONE,
+ )
.is_ok();
}
}
- err_out!(
- "error setting property {}:{} {}",
- ix.ns,
- ix.property,
- exempi::get_error() as u32
- );
+ err_out!("error setting property {}:{}", ix.ns, ix.property);
return false;
}
err_out!("Unknown property {:?}", meta);
@@ -191,39 +209,35 @@ impl LibMetadata {
for prop_id in propset {
match *prop_id {
Np::Index(NpXmpRatingProp) => {
- if let Some(rating) = self.xmp.rating() {
+ if let Some(rating) = self.xmp_meta.rating() {
props.set_value(*prop_id, PropertyValue::Int(rating));
}
}
Np::Index(NpXmpLabelProp) => {
- if let Some(label) = self.xmp.label() {
+ if let Some(label) = self.xmp_meta.label() {
props.set_value(*prop_id, PropertyValue::String(label));
}
}
Np::Index(NpTiffOrientationProp) => {
- if let Some(orientation) = self.xmp.orientation() {
+ if let Some(orientation) = self.xmp_meta.orientation() {
props.set_value(*prop_id, PropertyValue::Int(orientation));
}
}
Np::Index(NpExifDateTimeOriginalProp) => {
- if let Some(date) = self.xmp.creation_date() {
+ if let Some(date) = self.xmp_meta.creation_date() {
props.set_value(*prop_id, PropertyValue::Date(date));
}
}
Np::Index(NpIptcKeywordsProp) => {
- let mut iter = exempi::XmpIterator::new(
- &self.xmp.xmp,
+ let mut iter = exempi2::XmpIterator::new(
+ &self.xmp_meta.xmp,
NS_DC,
"subject",
- exempi::IterFlags::JUST_LEAF_NODES,
+ exempi2::IterFlags::JUST_LEAF_NODES,
);
let mut keywords: Vec<String> = vec![];
- let mut schema = exempi::XmpString::new();
- let mut name = exempi::XmpString::new();
- let mut value = exempi::XmpString::new();
- let mut flags = exempi::PropFlags::default();
- while iter.next(&mut schema, &mut name, &mut value, &mut flags) {
- keywords.push(String::from(value.to_str()));
+ while let Some(v) = iter.next() {
+ keywords.push(String::from(&v.value));
}
props.set_value(*prop_id, PropertyValue::StringArray(keywords));
}
@@ -255,9 +269,9 @@ impl LibMetadata {
pub fn touch(&mut self) -> bool {
let xmpdate = xmp_date_from(&Utc::now());
- self.xmp
+ self.xmp_meta
.xmp
- .set_property_date(NS_XAP, "MetadataDate", &xmpdate, exempi::PropFlags::NONE)
+ .set_property_date(NS_XAP, "MetadataDate", &xmpdate, exempi2::PropFlags::NONE)
.is_ok()
}
}
diff --git a/crates/npc-engine/src/db/library.rs b/crates/npc-engine/src/db/library.rs
index 48aaa0b..9193144 100644
--- a/crates/npc-engine/src/db/library.rs
+++ b/crates/npc-engine/src/db/library.rs
@@ -1343,8 +1343,6 @@ mod test {
fn file_bundle_import() {
use npc_fwk::utils::exempi::XmpMeta;
- exempi::init();
-
let lib = Library::new_in_memory();
assert!(lib.is_ok());
@@ -1378,7 +1376,7 @@ mod test {
// of the XMP SDK is written in the header so we can do comparisons
// byte by byte
let original_xmp_packet =
- exempi::Xmp::from_buffer(XMP_PACKET.as_bytes()).expect("XMP packet created");
+ exempi2::Xmp::from_buffer(XMP_PACKET.as_bytes()).expect("XMP packet created");
let original_xmp_packet = XmpMeta::new_with_xmp(original_xmp_packet);
let result = lib.set_image_properties(bundle_id, &props);
result.expect("Setting the XMP works");
diff --git a/crates/npc-fwk/Cargo.toml b/crates/npc-fwk/Cargo.toml
index 96c2eac..34003f1 100644
--- a/crates/npc-fwk/Cargo.toml
+++ b/crates/npc-fwk/Cargo.toml
@@ -11,7 +11,7 @@ build = "build.rs"
async-channel = "1.6.1"
cairo-rs = "*"
chrono = "0.4.0"
-exempi = { version = "2.6.0", git = "https://github.com/hfiguiere/exempi-rs.git", rev="99e8ba5" }
+exempi2 = { version = "0.1.1" }
gio-sys = "*"
gio = "^0.14.0"
glib-sys = "*"
diff --git a/crates/npc-fwk/src/base/date.rs b/crates/npc-fwk/src/base/date.rs
index bf400da..7e07f7c 100644
--- a/crates/npc-fwk/src/base/date.rs
+++ b/crates/npc-fwk/src/base/date.rs
@@ -1,7 +1,7 @@
/*
* niepce - fwk/base/date.rs
*
- * Copyright (C) 2017-2020 Hubert Figuière
+ * Copyright (C) 2017-2021 Hubert Figuière
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,11 +24,11 @@ use chrono::{Datelike, Timelike};
pub type Time = i64;
pub type Date = chrono::DateTime<chrono::Utc>;
-pub fn xmp_date_from(d: &chrono::DateTime<chrono::Utc>) -> exempi::DateTime {
- let mut xmp_date = exempi::DateTime::new();
+pub fn xmp_date_from(d: &chrono::DateTime<chrono::Utc>) -> exempi2::DateTime {
+ let mut xmp_date = exempi2::DateTime::new();
xmp_date.set_date(d.year(), d.month() as i32, d.day() as i32);
xmp_date.set_time(d.hour() as i32, d.minute() as i32, d.second() as i32);
- xmp_date.set_timezone(exempi::XmpTzSign::UTC, 0, 0);
+ xmp_date.set_timezone(exempi2::TzSign::UTC, 0, 0);
xmp_date
}
diff --git a/crates/npc-fwk/src/lib.rs b/crates/npc-fwk/src/lib.rs
index f6674c8..2f4d649 100644
--- a/crates/npc-fwk/src/lib.rs
+++ b/crates/npc-fwk/src/lib.rs
@@ -18,7 +18,7 @@
*/
extern crate chrono;
-extern crate exempi;
+extern crate exempi2;
extern crate gdk;
extern crate gdk_pixbuf;
extern crate gdk_pixbuf_sys;
diff --git a/crates/npc-fwk/src/utils/exempi.rs b/crates/npc-fwk/src/utils/exempi.rs
index f20ad65..1a555f3 100644
--- a/crates/npc-fwk/src/utils/exempi.rs
+++ b/crates/npc-fwk/src/utils/exempi.rs
@@ -24,7 +24,7 @@ use std::io::prelude::*;
use std::path::Path;
use chrono::{DateTime, Utc};
-use exempi::Xmp;
+use exempi2::Xmp;
use super::exiv2;
@@ -87,37 +87,37 @@ impl Flash {
xmp: &mut Xmp,
ns: &str,
property: &str,
- ) -> exempi::Result<()> {
+ ) -> exempi2::Result<()> {
// XXX use set_struct_field() as soon as it is available
xmp.set_property(
ns,
&format!("{}/exif:Fired", property),
bool_to_propstring(self.fired),
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)?;
xmp.set_property(
ns,
&format!("{}/exif:Return", property),
&format!("{}", self.rturn),
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)?;
xmp.set_property(
ns,
&format!("{}/exif:Mode", property),
&format!("{}", self.mode),
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)?;
xmp.set_property(
ns,
&format!("{}/exif:Function", property),
bool_to_propstring(self.function),
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)?;
xmp.set_property(
ns,
&format!("{}/exif:RedEyeMode", property),
bool_to_propstring(self.red_eye),
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
)?;
Ok(())
@@ -133,14 +133,13 @@ pub struct ExempiManager {}
impl ExempiManager {
pub fn new(namespaces: Option<Vec<NsDef>>) -> ExempiManager {
- if exempi::init() {
- exempi::register_namespace(NIEPCE_XMP_NAMESPACE, NIEPCE_XMP_NS_PREFIX);
- exempi::register_namespace(UFRAW_INTEROP_NAMESPACE, UFRAW_INTEROP_NS_PREFIX);
- }
+ exempi2::register_namespace(NIEPCE_XMP_NAMESPACE, NIEPCE_XMP_NS_PREFIX);
+ exempi2::register_namespace(UFRAW_INTEROP_NAMESPACE, UFRAW_INTEROP_NS_PREFIX);
+
if let Some(nslist) = namespaces {
for nsdef in nslist {
// TOOD check the return value
- exempi::register_namespace(nsdef.ns.as_str(), nsdef.prefix.as_str());
+ exempi2::register_namespace(nsdef.ns.as_str(), nsdef.prefix.as_str());
}
}
ExempiManager {}
@@ -163,13 +162,13 @@ impl Default for XmpMeta {
impl XmpMeta {
pub fn new() -> XmpMeta {
XmpMeta {
- xmp: exempi::Xmp::new(),
+ xmp: exempi2::Xmp::new(),
keywords: Vec::new(),
keywords_fetched: false,
}
}
- pub fn new_with_xmp(xmp: exempi::Xmp) -> XmpMeta {
+ pub fn new_with_xmp(xmp: exempi2::Xmp) -> XmpMeta {
XmpMeta {
xmp,
keywords: Vec::new(),
@@ -183,14 +182,12 @@ impl XmpMeta {
{
let file: &Path = p.as_ref();
if !file.exists() {
- err_out!("File {:?} doesn't exist", &file);
+ // XXX return an error.
return None;
}
let mut meta: Option<XmpMeta> = None;
if !sidecar_only {
- if let Ok(xmpfile) =
- exempi::XmpFile::open_new(&*file.to_string_lossy(), exempi::OpenFlags::READ)
- {
+ if let Ok(xmpfile) = exempi2::XmpFile::new_from_file(file, exempi2::OpenFlags::READ) {
meta = match xmpfile.get_new_xmp() {
Ok(xmp) => Some(Self::new_with_xmp(xmp)),
_ => exiv2::xmp_from_exiv2(file),
@@ -204,7 +201,7 @@ impl XmpMeta {
if let Ok(mut sidecarfile) = sidecaropen {
let mut sidecarcontent = String::new();
if sidecarfile.read_to_string(&mut sidecarcontent).is_ok() {
- let mut xmp = exempi::Xmp::new();
+ let mut xmp = exempi2::Xmp::new();
if xmp.parse(sidecarcontent.into_bytes().as_slice()).is_ok() {
sidecar_meta = Some(Self::new_with_xmp(xmp));
}
@@ -255,36 +252,28 @@ impl XmpMeta {
}
// Properties in source but not in destination gets copied over.
- let mut iter = exempi::XmpIterator::new(&self.xmp, "", "", exempi::IterFlags::PROPERTIES);
- {
- use exempi::XmpString;
- let mut schema = XmpString::new();
- let mut name = XmpString::new();
- let mut value = XmpString::new();
- let mut option = exempi::PropFlags::default();
- while iter.next(&mut schema, &mut name, &mut value, &mut option) {
- if name.to_str().is_empty() {
- continue;
- }
- if option.contains(exempi::PropFlags::VALUE_IS_ARRAY)
- || option.contains(exempi::PropFlags::VALUE_IS_STRUCT)
- {
- iter.skip(exempi::IterSkipFlags::SUBTREE);
- continue;
- }
+ let mut iter = exempi2::XmpIterator::new(&self.xmp, "", "", exempi2::IterFlags::PROPERTIES);
+ while let Some(v) = iter.next() {
+ if v.name.is_empty() {
+ continue;
+ }
+ if v.option.contains(exempi2::PropFlags::VALUE_IS_ARRAY)
+ || v.option.contains(exempi2::PropFlags::VALUE_IS_STRUCT)
+ {
+ exempi2::XmpIterator::skip(&mut iter, exempi2::IterSkipFlags::SUBTREE);
+ continue;
+ }
- if !dest.xmp.has_property(schema.to_str(), name.to_str())
- && dest
- .xmp
- .set_property(
- schema.to_str(),
- name.to_str(),
- value.to_str(),
- exempi::PropFlags::NONE,
- )
- .is_err()
+ let schema = v.schema.to_str().unwrap_or("");
+ let name = v.name.to_str().unwrap_or("");
+ if !dest.xmp.has_property(schema, name) {
+ let value = v.value.to_str().unwrap_or("");
+ if dest
+ .xmp
+ .set_property(schema, name, value, exempi2::PropFlags::NONE)
+ .is_err()
{
- err_out!("Can set property {}", name);
+ err_out!("Can not set property {}", v.name);
}
}
}
@@ -294,13 +283,13 @@ impl XmpMeta {
pub fn serialize_inline(&self) -> String {
if let Ok(xmpstr) = self.xmp.serialize_and_format(
- exempi::SerialFlags::OMITPACKETWRAPPER | exempi::SerialFlags::OMITALLFORMATTING,
+ exempi2::SerialFlags::OMITPACKETWRAPPER | exempi2::SerialFlags::OMITALLFORMATTING,
0,
"",
"",
0,
) {
- let buf = String::from(xmpstr.to_str());
+ let buf = String::from(&xmpstr);
return buf;
}
String::new()
@@ -309,9 +298,9 @@ impl XmpMeta {
pub fn serialize(&self) -> String {
if let Ok(xmpstr) =
self.xmp
- .serialize_and_format(exempi::SerialFlags::OMITPACKETWRAPPER, 0, "\n", "", 0)
+ .serialize_and_format(exempi2::SerialFlags::OMITPACKETWRAPPER, 0, "\n", "", 0)
{
- let buf = String::from(xmpstr.to_str());
+ let buf = String::from(&xmpstr);
return buf;
}
String::new()
@@ -322,61 +311,63 @@ impl XmpMeta {
}
pub fn orientation(&self) -> Option<i32> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::default();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::default();
self.xmp
.get_property_i32(NS_TIFF, "Orientation", &mut flags)
.ok()
}
pub fn label(&self) -> Option<String> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::default();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::default();
let xmpstring = self.xmp.get_property(NS_XAP, "Label", &mut flags).ok()?;
- Some(String::from(xmpstring.to_str()))
+ Some(String::from(&xmpstring))
}
pub fn rating(&self) -> Option<i32> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::default();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::default();
self.xmp.get_property_i32(NS_XAP, "Rating", &mut flags).ok()
}
pub fn flag(&self) -> Option<i32> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::empty();
self.xmp
.get_property_i32(NIEPCE_XMP_NAMESPACE, "Flag", &mut flags)
.ok()
}
pub fn creation_date(&self) -> Option<DateTime<Utc>> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::default();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::default();
let xmpstring = self
.xmp
.get_property(NS_EXIF, "DateTimeOriginal", &mut flags)
.ok()?;
- let date = DateTime::parse_from_rfc3339(xmpstring.to_str()).ok()?;
+ let date = xmpstring
+ .to_str()
+ .and_then(|s| DateTime::parse_from_rfc3339(s).ok())?;
Some(date.with_timezone(&Utc))
}
pub fn creation_date_str(&self) -> Option<String> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::empty();
let xmpstring = self
.xmp
.get_property(NS_EXIF, "DateTimeOriginal", &mut flags)
.ok()?;
- Some(String::from(xmpstring.to_str()))
+ Some(String::from(&xmpstring))
}
/// Get the date property and return a Option<DateTime<Utc>> parsed
/// from the string value.
pub fn get_date_property(&self, ns: &str, property: &str) -> Option<DateTime<Utc>> {
- let mut flags: exempi::PropFlags = exempi::PropFlags::default();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::default();
let property = self.xmp.get_property(ns, property, &mut flags);
if property.is_err() {
err_out!("Error getting date property {:?}", property.err());
return None;
}
- let xmpstring = property.unwrap();
- let parsed = DateTime::parse_from_rfc3339(xmpstring.to_str());
+ let xmpstring = property.as_ref().ok().and_then(|s| s.to_str()).unwrap();
+ let parsed = DateTime::parse_from_rfc3339(xmpstring);
if parsed.is_err() {
err_out!(
"Error parsing property value '{}': {:?}",
@@ -391,20 +382,14 @@ impl XmpMeta {
pub fn keywords(&mut self) -> &Vec<String> {
if !self.keywords_fetched {
- use exempi::XmpString;
-
- let mut iter = exempi::XmpIterator::new(
+ let mut iter = exempi2::XmpIterator::new(
&self.xmp,
NS_DC,
"subject",
- exempi::IterFlags::JUST_LEAF_NODES,
+ exempi2::IterFlags::JUST_LEAF_NODES,
);
- let mut schema = XmpString::new();
- let mut name = XmpString::new();
- let mut value = XmpString::new();
- let mut option = exempi::PropFlags::default();
- while iter.next(&mut schema, &mut name, &mut value, &mut option) {
- self.keywords.push(String::from(value.to_str()));
+ while let Some(v) = iter.next() {
+ self.keywords.push(String::from(&v.value));
}
self.keywords_fetched = true;
}
@@ -469,7 +454,7 @@ pub fn gps_coord_from_xmp(xmps: &str) -> Option<f64> {
/// Get and XMP date from an Exif date string
/// XXX Currently assume it is UTC.
-pub fn xmp_date_from_exif(d: &str) -> Option<exempi::DateTime> {
+pub fn xmp_date_from_exif(d: &str) -> Option<exempi2::DateTime> {
let v: Vec<&str> = d.split(' ').collect();
if v.len() != 2 {
err_out!("Space split failed {:?}", v);
@@ -508,12 +493,12 @@ pub fn xmp_date_from_exif(d: &str) -> Option<exempi::DateTime> {
return None;
}
- let mut xmp_date = exempi::DateTime::new();
+ let mut xmp_date = exempi2::DateTime::new();
xmp_date.set_date(year, month, day);
xmp_date.set_time(hour, min, sec);
// XXX use an actual timezone
- xmp_date.set_timezone(exempi::XmpTzSign::UTC, 0, 0);
+ xmp_date.set_timezone(exempi2::TzSign::UTC, 0, 0);
Some(xmp_date)
}
@@ -537,7 +522,7 @@ mod tests {
use super::xmp_date_from_exif;
use super::ExempiManager;
use super::XmpMeta;
- use exempi;
+ use exempi2;
use std::path::PathBuf;
fn get_xmp_sample_path() -> PathBuf {
@@ -580,10 +565,10 @@ mod tests {
}
fn test_property_value(meta: &XmpMeta, ns: &str, property: &str, expected_value: &str) {
- let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::empty();
let value = meta.xmp.get_property(ns, property, &mut flags);
assert!(value.is_ok());
- assert_eq!(value.unwrap().to_str(), expected_value);
+ assert_eq!(value.unwrap().to_str(), Some(expected_value));
}
fn test_property_array_value(
@@ -593,10 +578,10 @@ mod tests {
idx: i32,
expected_value: &str,
) {
- let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
+ let mut flags: exempi2::PropFlags = exempi2::PropFlags::empty();
let value = meta.xmp.get_array_item(ns, property, idx, &mut flags);
assert!(value.is_ok());
- assert_eq!(value.unwrap().to_str(), expected_value);
+ assert_eq!(value.unwrap().to_str(), Some(expected_value));
}
#[test]
diff --git a/crates/npc-fwk/src/utils/exiv2.rs b/crates/npc-fwk/src/utils/exiv2.rs
index c2c8afa..8b4bcd9 100644
--- a/crates/npc-fwk/src/utils/exiv2.rs
+++ b/crates/npc-fwk/src/utils/exiv2.rs
@@ -1,7 +1,7 @@
/*
* niepce - fwk/utils/exiv2.rs
*
- * Copyright (C) 2018-2020 Hubert Figuière
+ * Copyright (C) 2018-2021 Hubert Figuière
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +45,7 @@ enum Converted {
/// An int 32
Int(i32),
/// an Xmp DateTime value
- Date(Option<exempi::DateTime>),
+ Date(Option<exempi2::DateTime>),
/// The Flash XMP structure
Flash(Flash),
}
@@ -278,14 +278,14 @@ fn ascii_tag_to_xmp(
meta: &rexiv2::Metadata,
tag: &str,
xmp_prop: &XmpPropDesc,
- xmp: &mut exempi::Xmp,
+ xmp: &mut exempi2::Xmp,
) {
if let Ok(value) = meta.get_tag_string(tag) {
let converted = convert(xmp_prop.2, &value);
match converted {
Converted::Str(s) => {
if let Err(err) =
- xmp.set_property(xmp_prop.0, xmp_prop.1, &s, exempi::PropFlags::NONE)
+ xmp.set_property(xmp_prop.0, xmp_prop.1, &s, exempi2::PropFlags::NONE)
{
err_out!(
"Error setting property {} {}: {:?}",
@@ -298,7 +298,7 @@ fn ascii_tag_to_xmp(
Converted::Date(d) => {
if let Some(d) = d {
if let Err(err) =
- xmp.set_property_date(xmp_prop.0, xmp_prop.1, &d, exempi::PropFlags::NONE)
+ xmp.set_property_date(xmp_prop.0, xmp_prop.1, &d, exempi2::PropFlags::NONE)
{
err_out!(
"Error setting property {} {}: {:?}",
@@ -324,7 +324,7 @@ fn int_tag_to_xmp(
tag: &str,
tagtype: rexiv2::TagType,
xmp_prop: &XmpPropDesc,
- xmp: &mut exempi::Xmp,
+ xmp: &mut exempi2::Xmp,
) {
// XXX rexiv2 returns an i32, which is a problem for UnsignedLong
match xmp_prop.2 {
@@ -343,7 +343,7 @@ fn int_tag_to_xmp(
Conversion::None => {
let value = meta.get_tag_numeric(&tag);
if let Err(err) =
- xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PropFlags::NONE)
+ xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi2::PropFlags::NONE)
{
err_out!(
"Error setting property {} {}: {:?}",
@@ -356,7 +356,7 @@ fn int_tag_to_xmp(
Conversion::Interpreted => {
if let Ok(value) = meta.get_tag_interpreted_string(&tag) {
if let Err(err) =
- xmp.set_property(xmp_prop.0, xmp_prop.1, &value, exempi::PropFlags::NONE)
+ xmp.set_property(xmp_prop.0, xmp_prop.1, &value, exempi2::PropFlags::NONE)
{
err_out!(
"Error setting property {} {}: {:?}",
@@ -371,7 +371,7 @@ fn int_tag_to_xmp(
err_out!("Unknown conversion from {:?} to {:?}", tagtype, xmp_prop.2);
let value = meta.get_tag_numeric(&tag);
if let Err(err) =
- xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi::PropFlags::NONE)
+ xmp.set_property_i32(xmp_prop.0, xmp_prop.1, value, exempi2::PropFlags::NONE)
{
err_out!(
"Error setting property {} {}: {:?}",
@@ -386,7 +386,7 @@ fn int_tag_to_xmp(
pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
if let Ok(meta) = rexiv2::Metadata::new_from_path(file) {
- let mut xmp = exempi::Xmp::new();
+ let mut xmp = exempi2::Xmp::new();
let mut all_tags: Vec<String> = vec![];
if let Ok(mut tags) = meta.get_exif_tags() {
all_tags.append(&mut tags);
@@ -425,7 +425,7 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
xmp_prop.0,
xmp_prop.1,
&value,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
) {
err_out!(
"Error setting property {} {}: {:?}",
@@ -443,7 +443,7 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
xmp_prop.0,
xmp_prop.1,
&value_str,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
) {
err_out!(
"Error setting property {} {}: {:?}",
@@ -461,7 +461,7 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
xmp_prop.0,
xmp_prop.1,
&value,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
) {
err_out!(
"Error setting property {} {}: {:?}",
@@ -479,7 +479,7 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
xmp_prop.0,
xmp_prop.1,
&value,
- exempi::PropFlags::NONE,
+ exempi2::PropFlags::NONE,
) {
err_out!(
"Error setting property {} {}: {:?}",
@@ -503,10 +503,10 @@ pub fn xmp_from_exiv2<S: AsRef<OsStr>>(file: S) -> Option<XmpMeta> {
}
meta.get_gps_info();
- let mut options = exempi::PropFlags::default();
+ let mut options = exempi2::PropFlags::default();
if let Ok(date) = xmp.get_property_date(NS_XAP, "ModifyDate", &mut options) {
if let Err(err) =
- xmp.set_property_date(NS_XAP, "MetadataDate", &date, exempi::PropFlags::NONE)
+ xmp.set_property_date(NS_XAP, "MetadataDate", &date, exempi2::PropFlags::NONE)
{
err_out!("Error setting MetadataDate: {:?}", &err);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]