100 lines
2.4 KiB
Rust
100 lines
2.4 KiB
Rust
//! ActivityPub implementation code and related abstractions.
|
|
|
|
use futures::prelude::*;
|
|
use serde::Serialize;
|
|
|
|
use crate::{ Id, Activity, err, Result, Error, sign, ctx::Context };
|
|
|
|
#[derive(Clone, Serialize)]
|
|
pub enum Create {
|
|
Note { object: Note }
|
|
}
|
|
|
|
impl From<Create> for Activity { fn from (a: Create) -> Activity { Activity::Create (a) } }
|
|
|
|
#[derive(Clone, Serialize)]
|
|
pub enum Follow {
|
|
Actor { object: Actor }
|
|
}
|
|
|
|
impl From<Follow> for Activity { fn from (a: Follow) -> Activity { Activity::Follow (a) } }
|
|
|
|
#[derive(Clone, Serialize)]
|
|
pub enum Accept {
|
|
Follow { object: Follow }
|
|
}
|
|
|
|
impl From<Accept> for Activity { fn from (a: Accept) -> Activity { Activity::Accept (a) } }
|
|
|
|
/// An entity that publishes activities.
|
|
#[derive(Clone, Serialize, sqlx::FromRow)]
|
|
pub struct Actor {
|
|
id: Id,
|
|
}
|
|
|
|
#[derive(Clone, Serialize)]
|
|
pub struct Note {
|
|
id: Id,
|
|
}
|
|
|
|
impl Activity {
|
|
|
|
/// Deliver the activity to all its targets through the ActivityPub
|
|
/// delivery mechanism.
|
|
pub async fn deliver <S> (self, signer: &S) -> Result<()>
|
|
where
|
|
S: sign::Sign + ?Sized,
|
|
{
|
|
// Create a shared client #efficiency
|
|
let client = reqwest::Client::new();
|
|
|
|
// the function that does the delivery to a target. It creates
|
|
// a request with the proper headers and signs it using the
|
|
// `signer`.
|
|
let do_delivery = |url| async {
|
|
let req = {
|
|
let mut r = client.get(url).build()?;
|
|
signer.sign(&mut r)?;
|
|
r
|
|
};
|
|
client
|
|
.execute(req)
|
|
.map_err(err)
|
|
.await
|
|
};
|
|
|
|
// Collect only the errors, since we don't need to do anything
|
|
// with a successful delivery.
|
|
let errors = self
|
|
.delivery_targets()
|
|
.await?
|
|
.into_iter()
|
|
.map(do_delivery)
|
|
.collect::<stream::FuturesUnordered<_>>()
|
|
.filter_map(|r: Result<_>| async {
|
|
r.err().map(err)
|
|
})
|
|
.collect::<Vec<Error>>()
|
|
.await;
|
|
|
|
for err in errors {
|
|
// Failure to deliver is not a fatal error per se,
|
|
// so we log and move on.
|
|
println!("Failed to deliver activity: {:?}", err);
|
|
}
|
|
|
|
Ok (())
|
|
}
|
|
|
|
/// Get all delivery targets as urls.
|
|
async fn delivery_targets (&self) -> Result<Vec<reqwest::Url>> {
|
|
todo!()
|
|
}
|
|
|
|
/// Perform the activity.
|
|
pub async fn perform <S> (self, ctx: &mut Context<S>) -> Result<()> where S: sign::Sign {
|
|
todo!()
|
|
}
|
|
|
|
}
|