2018-06-10 13:13:07 +02:00
|
|
|
use activitypub::{
|
2018-06-17 21:37:10 +02:00
|
|
|
Object,
|
2018-06-12 21:10:08 +02:00
|
|
|
activity::{Create, Like, Undo}
|
2018-05-16 20:20:44 +02:00
|
|
|
};
|
2018-05-01 16:00:29 +02:00
|
|
|
use diesel::PgConnection;
|
2018-05-16 20:20:44 +02:00
|
|
|
use failure::Error;
|
2018-05-01 16:00:29 +02:00
|
|
|
use serde_json;
|
|
|
|
|
2018-05-19 09:39:59 +02:00
|
|
|
use activity_pub::{
|
2018-06-12 21:10:08 +02:00
|
|
|
Id
|
2018-05-19 09:39:59 +02:00
|
|
|
};
|
|
|
|
use models::{
|
|
|
|
comments::*,
|
2018-06-12 21:10:08 +02:00
|
|
|
follows::Follow,
|
2018-05-19 09:39:59 +02:00
|
|
|
likes,
|
|
|
|
posts::*,
|
2018-06-12 21:10:08 +02:00
|
|
|
reshares::*
|
2018-05-19 09:39:59 +02:00
|
|
|
};
|
2018-05-01 16:00:29 +02:00
|
|
|
|
2018-05-16 20:20:44 +02:00
|
|
|
#[derive(Fail, Debug)]
|
|
|
|
enum InboxError {
|
|
|
|
#[fail(display = "The `type` property is required, but was not present")]
|
|
|
|
NoType,
|
|
|
|
#[fail(display = "Invalid activity type")]
|
|
|
|
InvalidType,
|
|
|
|
#[fail(display = "Couldn't undo activity")]
|
|
|
|
CantUndo
|
|
|
|
}
|
|
|
|
|
2018-06-12 21:10:08 +02:00
|
|
|
pub trait FromActivity<T: Object>: Sized {
|
|
|
|
fn from_activity(conn: &PgConnection, obj: T, actor: Id) -> Self;
|
2018-05-01 16:00:29 +02:00
|
|
|
|
2018-06-12 21:10:08 +02:00
|
|
|
fn try_from_activity(conn: &PgConnection, act: Create) -> bool {
|
|
|
|
if let Ok(obj) = act.create_props.object_object() {
|
|
|
|
Self::from_activity(conn, obj, act.create_props.actor_link::<Id>().unwrap());
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2018-05-16 20:20:44 +02:00
|
|
|
}
|
2018-06-12 21:10:08 +02:00
|
|
|
}
|
2018-05-16 20:20:44 +02:00
|
|
|
|
2018-06-17 21:37:10 +02:00
|
|
|
pub trait Notify<T: Object> {
|
2018-06-12 21:10:08 +02:00
|
|
|
fn notify(conn: &PgConnection, act: T, actor: Id);
|
|
|
|
}
|
2018-05-16 20:20:44 +02:00
|
|
|
|
2018-06-12 21:10:08 +02:00
|
|
|
pub trait Deletable {
|
|
|
|
/// true if success
|
|
|
|
fn delete_activity(conn: &PgConnection, id: Id) -> bool;
|
|
|
|
}
|
2018-05-16 20:20:44 +02:00
|
|
|
|
2018-06-12 21:10:08 +02:00
|
|
|
pub trait Inbox {
|
|
|
|
fn received(&self, conn: &PgConnection, act: serde_json::Value);
|
2018-05-16 20:20:44 +02:00
|
|
|
|
|
|
|
fn unlike(&self, conn: &PgConnection, undo: Undo) -> Result<(), Error> {
|
2018-06-10 13:13:07 +02:00
|
|
|
let like = likes::Like::find_by_ap_url(conn, undo.undo_props.object_object::<Like>()?.object_props.id_string()?).unwrap();
|
2018-05-16 20:20:44 +02:00
|
|
|
like.delete(conn);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn save(&self, conn: &PgConnection, act: serde_json::Value) -> Result<(), Error> {
|
2018-06-12 21:10:08 +02:00
|
|
|
let actor_id = Id::new(act["actor"].as_str().unwrap());
|
2018-05-16 20:20:44 +02:00
|
|
|
match act["type"].as_str() {
|
|
|
|
Some(t) => {
|
|
|
|
match t {
|
2018-06-12 21:10:08 +02:00
|
|
|
"Announce" => {
|
|
|
|
Reshare::from_activity(conn, serde_json::from_value(act.clone())?, actor_id);
|
|
|
|
Ok(())
|
|
|
|
},
|
2018-05-16 20:20:44 +02:00
|
|
|
"Create" => {
|
|
|
|
let act: Create = serde_json::from_value(act.clone())?;
|
2018-06-12 21:10:08 +02:00
|
|
|
if Post::try_from_activity(conn, act.clone()) || Comment::try_from_activity(conn, act) {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(InboxError::InvalidType)?
|
2018-05-16 20:20:44 +02:00
|
|
|
}
|
|
|
|
},
|
2018-06-12 21:10:08 +02:00
|
|
|
"Follow" => {
|
|
|
|
Follow::from_activity(conn, serde_json::from_value(act.clone())?, actor_id);
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
"Like" => {
|
|
|
|
likes::Like::from_activity(conn, serde_json::from_value(act.clone())?, actor_id);
|
|
|
|
Ok(())
|
|
|
|
},
|
2018-05-16 20:20:44 +02:00
|
|
|
"Undo" => {
|
|
|
|
let act: Undo = serde_json::from_value(act.clone())?;
|
2018-06-10 13:13:07 +02:00
|
|
|
match act.undo_props.object["type"].as_str().unwrap() {
|
2018-06-12 21:10:08 +02:00
|
|
|
"Like" => {
|
|
|
|
likes::Like::delete_activity(conn, Id::new(act.undo_props.object_object::<Like>()?.object_props.id_string()?));
|
|
|
|
Ok(())
|
|
|
|
},
|
2018-05-16 20:20:44 +02:00
|
|
|
_ => Err(InboxError::CantUndo)?
|
|
|
|
}
|
2018-05-13 12:44:05 +02:00
|
|
|
}
|
2018-05-16 20:20:44 +02:00
|
|
|
_ => Err(InboxError::InvalidType)?
|
2018-05-13 12:44:05 +02:00
|
|
|
}
|
|
|
|
},
|
2018-05-16 20:20:44 +02:00
|
|
|
None => Err(InboxError::NoType)?
|
2018-05-01 16:00:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-05-18 10:04:40 +02:00
|
|
|
|
|
|
|
pub trait WithInbox {
|
|
|
|
fn get_inbox_url(&self) -> String;
|
|
|
|
|
|
|
|
fn get_shared_inbox_url(&self) -> Option<String>;
|
|
|
|
}
|