You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.9 KiB
Rust
61 lines
1.9 KiB
Rust
use json_ld::{
|
|
syntax::{Parse, Value},
|
|
Expand, IndexedObject, RemoteDocument,
|
|
};
|
|
use locspan::{Meta, Span};
|
|
use mime::Mime;
|
|
use rdf_types::vocabulary::BlankIdIndex;
|
|
use rdf_types::{vocabulary::IriIndex, IndexVocabulary, Vocabulary};
|
|
|
|
use crate::ap::{
|
|
loader::CachedLoader,
|
|
trans::{ApDocument, ParseApub},
|
|
vocab::Ids,
|
|
};
|
|
use crate::core::*;
|
|
use crate::state::AppState;
|
|
|
|
/// Main API for handling ActivityPub ingress, called by [`crate::job::inbox::InboxWorker`].
|
|
pub async fn process_document(state: &AppState, raw: &str, mime: &Mime) -> Result<()> {
|
|
let mut vocab: IndexVocabulary = IndexVocabulary::new();
|
|
let indices = Ids::populate(&mut vocab);
|
|
|
|
let json = preprocess(raw)?;
|
|
let rd = RemoteDocument::new(None, Some(mime.clone()), json);
|
|
|
|
let mut loader = CachedLoader::new_with(state.clone(), move |_vocab, _iri, bytes| {
|
|
let content = std::str::from_utf8(bytes.as_ref())
|
|
.map_err(|e| Error::MalformedApub(format!("Invalid encoding: {e}")))?;
|
|
preprocess(&content)
|
|
});
|
|
let rd = rd.expand_with(&mut vocab, &mut loader).await.unwrap();
|
|
let vocab = vocab;
|
|
|
|
// this loop will usually only run once (one object per request)
|
|
for object in rd.into_value() {
|
|
if let Err(e) = process_object(object, &vocab, &indices).await {
|
|
error!("Error in remote document: {e}");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn preprocess(raw: &str) -> Result<Meta<Value<Span>, Span>> {
|
|
json_ld::syntax::Value::parse_str(raw, |span| span)
|
|
.map_err(|e| Error::MalformedApub(format!("{e}")))
|
|
}
|
|
|
|
async fn process_object(
|
|
obj: IndexedObject<IriIndex, BlankIdIndex, Span>,
|
|
vocab: &impl Vocabulary<Iri = IriIndex>,
|
|
ids: &Ids,
|
|
) -> Result<()> {
|
|
let document = ApDocument::parse_apub(&obj, vocab, ids);
|
|
if let Some(doc) = document {
|
|
debug!("\nParsed document:\n{doc:?}");
|
|
}
|
|
|
|
Ok(())
|
|
}
|