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

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(())
}