use sophia_jsonld::loader::HttpLoader;
use sophia_jsonld::parser::{JsonLdParser, JsonLdQuadSource};
use sophia_jsonld::JsonLdOptions;
use sophia_jsonld::JsonLdQuadSource::Quads;
use sophia::api::prelude::*;
use sophia::inmem::graph::FastGraph;
use sophia::turtle::serializer::turtle::TurtleSerializer;
use sophia_api::prelude::Quad;
use sha256::digest;
use urn::UrnBuilder;
use nostr::prelude::*;
use nostr::Keys;
use nostr_sdk::prelude::*;
use serde_json::{json, Value};
use crate::err::LDError;
pub const EVKIND_TURTLE: Kind = Kind::Custom(7100);
pub const EVKIND_JSONLD: Kind = Kind::Custom(7101);
pub const EVKIND_JSONLD_META0: Kind = Kind::Custom(7102);
pub const EVKIND_JSONLD_SUBS: Kind = Kind::Custom(7103);
pub fn jsonld_event_builder(
mut value: Value,
evkind: Option<Kind>,
) -> EventBuilder {
let content_digest = digest(value.to_string());
let urn = UrnBuilder::new("nostr-content", &content_digest)
.build()
.unwrap();
value["@id"] = json!(urn.as_str());
let kind = match evkind {
Some(k) => k,
None => EVKIND_JSONLD,
};
EventBuilder::new(kind, value.to_string())
}
pub async fn build_jsonld_event_from_value(
keys: &Keys,
mut value: Value,
) -> Result<Event, LDError> {
let content_digest = digest(value.to_string());
let urn = UrnBuilder::new("nostr-content", &content_digest)
.build()
.map_err(|_| LDError::EventBuildError)?;
value["@id"] = json!(urn.as_str());
Ok(EventBuilder::new(EVKIND_JSONLD, value.to_string())
.sign(keys)
.await
.map_err(|_| LDError::EventBuildError)?)
}
pub async fn build_ttl_event_from_value(
keys: &Keys,
mut value: Value,
) -> Result<Event, LDError> {
let json_ld_s = value.to_string();
let event_id = EventId::new(
&keys.public_key(),
&Timestamp::now(),
&EVKIND_TURTLE,
&Tags::new(),
json_ld_s.as_str(),
);
let event_uri = event_id
.to_nostr_uri()
.map_err(|_| LDError::EventBuildError)?;
value["@id"] = json!(event_uri);
build_ttl_event(keys, &value.to_string()).await
}
pub async fn build_ttl_event(
keys: &Keys,
json_ld_str: &String,
) -> Result<Event, LDError> {
let options =
JsonLdOptions::new().with_default_document_loader::<HttpLoader>();
let parser = JsonLdParser::new_with_options(options);
let mut g = FastGraph::new();
let mut turtlizer = TurtleSerializer::new_stringifier();
let event_id = EventId::new(
&keys.public_key(),
&Timestamp::now(),
&EVKIND_TURTLE,
&Tags::new(),
json_ld_str,
);
let event_uri = event_id
.to_nostr_uri()
.map_err(|_| LDError::EventBuildError)?;
match parser.async_parse_str(json_ld_str.as_str()).await {
Quads(quads) => {
for quad in quads {
let triple = quad.into_triple();
let _ = g.insert(triple.s(), triple.p(), triple.o());
}
let _ = turtlizer
.serialize_graph(&g)
.map_err(|_| LDError::TTLSerializationError)?;
let tag_vals = vec![event_uri];
let ev = EventBuilder::new(EVKIND_TURTLE, turtlizer.to_string())
.tag(Tag::custom(
TagKind::SingleLetter(
SingleLetterTag::from_char('g').unwrap(),
),
tag_vals,
))
.sign(keys)
.await
.map_err(|_| LDError::EventBuildError)?;
Ok(ev)
}
JsonLdQuadSource::Err(_error) => {
eprintln!("=> {:?}", _error);
Err(LDError::JsonLDParseError)
}
}
}
pub fn ld_events_filter() -> Filter {
Filter::new().kind(EVKIND_JSONLD)
}
pub fn ld_metadata_events_filter() -> Filter {
Filter::new()
.kind(EVKIND_JSONLD_META0)
.kind(EVKIND_JSONLD_SUBS)
}