use anyhow::Result;
use c2pa::{
assertions::{c2pa_action, labels, Action, Actions, CreativeWork, SchemaDotOrgPerson},
create_signer, Ingredient, Manifest, ManifestStore, SigningAlg,
};
use std::path::PathBuf;
const GENERATOR: &str = "test_app/0.1";
const INDENT_SPACE: usize = 2;
fn show_manifest(manifest_store: &ManifestStore, manifest_label: &str, level: usize) -> Result<()> {
let indent = " ".repeat(level * INDENT_SPACE);
println!("{}manifest_label: {}", indent, manifest_label);
if let Some(manifest) = manifest_store.get(manifest_label) {
println!(
"{}title: {} , format: {}, instance_id: {}",
indent,
manifest.title().unwrap_or_default(),
manifest.format(),
manifest.instance_id()
);
for assertion in manifest.assertions().iter() {
println!("{}", assertion.label_with_instance());
match assertion.label() {
labels::ACTIONS => {
let actions: Actions = assertion.to_assertion()?;
for action in actions.actions {
println!("{}{}", indent, action.action());
}
}
labels::CREATIVE_WORK => {
let creative_work: CreativeWork = assertion.to_assertion()?;
if let Some(authors) = creative_work.author() {
for author in authors {
if let Some(name) = author.name() {
println!("{}author = {} ", indent, name);
}
}
}
if let Some(url) = creative_work.get::<String>("url") {
println!("{}url = {} ", indent, url);
}
}
_ => {}
}
}
for ingredient in manifest.ingredients().iter() {
println!("{}Ingredient title:{}", indent, ingredient.title());
if let Some(label) = ingredient.active_manifest() {
show_manifest(manifest_store, label, level + 1)?;
}
}
}
Ok(())
}
pub fn main() -> Result<()> {
let args: Vec<String> = std::env::args().collect();
let (src, dst) = match args.len() >= 3 {
true => (args[1].as_str(), args[2].as_str()),
false => (
"sdk/tests/fixtures/earth_apollo17.jpg",
"target/tmp/client.jpg",
),
};
let source = PathBuf::from(src);
let dest = PathBuf::from(dst);
let parent = Ingredient::from_file(source.as_path())?;
let actions = Actions::new().add_action(
Action::new(c2pa_action::PLACED)
.set_parameter("identifier", parent.instance_id().to_owned())?,
);
let creative_work =
CreativeWork::new().add_author(SchemaDotOrgPerson::new().set_name("me")?)?;
let mut manifest = Manifest::new(GENERATOR.to_owned());
manifest
.set_parent(parent)?
.add_assertion(&actions)?
.add_assertion(&creative_work)?;
let signcert_path = "sdk/tests/fixtures/certs/es256.pub";
let pkey_path = "sdk/tests/fixtures/certs/es256.pem";
let signer = create_signer::from_files(signcert_path, pkey_path, SigningAlg::Es256, None)?;
manifest.embed(&source, &dest, &*signer)?;
let manifest_store = ManifestStore::from_file(&dest)?;
println!("{}\n", manifest_store);
if let Some(manifest_label) = manifest_store.active_label() {
show_manifest(&manifest_store, manifest_label, 0)?;
}
Ok(())
}