Resolve activitystream TODOs

This commit is contained in:
Bat
2018-05-18 23:04:30 +01:00
parent 0e24ccbf29
commit 4a86af6fc1
14 changed files with 172 additions and 42 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ use openssl::pkey::{PKey, Private};
use openssl::rsa::Rsa;
use openssl::sign::Signer;
use activity_pub::{ActivityStream, Id};
use activity_pub::{ActivityStream, Id, IntoId};
use activity_pub::actor::{Actor as APActor, ActorType};
use activity_pub::inbox::WithInbox;
use activity_pub::sign;
@@ -175,8 +175,8 @@ impl Blog {
}
}
impl Into<Id> for Blog {
fn into(self) -> Id {
impl IntoId for Blog {
fn into_id(self) -> Id {
Id::new(self.ap_url)
}
}
+36 -1
View File
@@ -1,8 +1,12 @@
use activitystreams_types::{
activity::Create,
object::{Note, properties::ObjectProperties}
};
use chrono;
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods};
use serde_json;
use activity_pub::{ap_url, PUBLIC_VISIBILTY};
use activity_pub::{ap_url, IntoId, PUBLIC_VISIBILTY};
use activity_pub::actor::Actor;
use activity_pub::object::Object;
use models::posts::Post;
@@ -71,6 +75,37 @@ impl Comment {
pub fn get_post(&self, conn: &PgConnection) -> Post {
Post::get(conn, self.post_id).unwrap()
}
pub fn into_activity(&self, conn: &PgConnection) -> Note {
let mut to = self.get_author(conn).get_followers(conn).into_iter().map(|f| f.ap_url).collect::<Vec<String>>();
to.append(&mut self.get_post(conn).get_receivers_urls(conn));
to.push(PUBLIC_VISIBILTY.to_string());
let mut comment = Note::default();
comment.object_props = ObjectProperties {
id: Some(serde_json::to_value(self.ap_url.clone()).unwrap()),
summary: Some(serde_json::to_value(self.spoiler_text.clone()).unwrap()),
content: Some(serde_json::to_value(self.content.clone()).unwrap()),
in_reply_to: Some(serde_json::to_value(self.in_response_to_id.map_or_else(|| self.get_post(conn).ap_url, |id| {
let comm = Comment::get(conn, id).unwrap();
comm.ap_url.clone().unwrap_or(comm.compute_id(conn))
})).unwrap()),
published: Some(serde_json::to_value(self.creation_date).unwrap()),
attributed_to: Some(serde_json::to_value(self.get_author(conn).compute_id(conn)).unwrap()),
to: Some(serde_json::to_value(to).unwrap()),
cc: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
..ObjectProperties::default()
};
comment
}
pub fn create_activity(&self, conn: &PgConnection) -> Create {
let mut act = Create::default();
act.set_actor_link(self.get_author(conn).into_id()).unwrap();
act.set_object_object(self.into_activity(conn)).unwrap();
act.object_props.set_id_string(format!("{}/activity", self.ap_url.clone().unwrap())).unwrap();
act
}
}
impl Object for Comment {
+20 -1
View File
@@ -1,7 +1,9 @@
use activitystreams_types::activity;
use chrono;
use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods};
use serde_json;
use activity_pub::IntoId;
use activity_pub::actor::Actor;
use activity_pub::object::Object;
use models::posts::Post;
@@ -66,8 +68,25 @@ impl Like {
.into_iter().nth(0)
}
pub fn delete(&self, conn: &PgConnection) {
pub fn delete(&self, conn: &PgConnection) -> activity::Undo {
diesel::delete(self).execute(conn).unwrap();
let mut act = activity::Undo::default();
act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap();
act.set_object_object(self.into_activity(conn)).unwrap();
act
}
pub fn into_activity(&self, conn: &PgConnection) -> activity::Like {
let mut act = activity::Like::default();
act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap();
act.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap();
act.object_props.set_id_string(format!("{}/like/{}",
User::get(conn, self.user_id).unwrap().ap_url,
Post::get(conn, self.post_id).unwrap().ap_url
)).unwrap();
act
}
}
+39 -1
View File
@@ -1,10 +1,14 @@
use activitystreams_types::{
activity::Create,
object::{Article, properties::ObjectProperties}
};
use chrono::NaiveDateTime;
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl};
use diesel::dsl::any;
use serde_json;
use BASE_URL;
use activity_pub::{PUBLIC_VISIBILTY, ap_url};
use activity_pub::{PUBLIC_VISIBILTY, ap_url, Id, IntoId};
use activity_pub::actor::Actor;
use activity_pub::object::Object;
use models::blogs::Blog;
@@ -137,6 +141,40 @@ impl Post {
});
to
}
pub fn into_activity(&self, conn: &PgConnection) -> Article {
let mut to = self.get_receivers_urls(conn);
to.push(PUBLIC_VISIBILTY.to_string());
let mut article = Article::default();
article.object_props = ObjectProperties {
name: Some(serde_json::to_value(self.title.clone()).unwrap()),
id: Some(serde_json::to_value(self.ap_url.clone()).unwrap()),
attributed_to: Some(serde_json::to_value(self.get_authors(conn).into_iter().map(|x| x.ap_url).collect::<Vec<String>>()).unwrap()),
content: Some(serde_json::to_value(self.content.clone()).unwrap()),
published: Some(serde_json::to_value(self.creation_date).unwrap()),
tag: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
url: Some(serde_json::to_value(self.compute_id(conn)).unwrap()),
to: Some(serde_json::to_value(to).unwrap()),
cc: Some(serde_json::to_value(Vec::<serde_json::Value>::new()).unwrap()),
..ObjectProperties::default()
};
article
}
pub fn create_activity(&self, conn: &PgConnection) -> Create {
let mut act = Create::default();
act.object_props.set_id_string(format!("{}/activity", self.ap_url)).unwrap();
act.set_actor_link(Id::new(self.get_authors(conn)[0].clone().ap_url)).unwrap();
act.set_object_object(self.into_activity(conn)).unwrap();
act
}
}
impl IntoId for Post {
fn into_id(self) -> Id {
Id::new(self.ap_url.clone())
}
}
impl Object for Post {
+49 -10
View File
@@ -1,7 +1,9 @@
use activitystreams_traits::{Actor, Object};
use activitystreams_traits::{Actor, Object, Link};
use activitystreams_types::{
activity::Create,
collection::OrderedCollection
actor::Person,
collection::OrderedCollection,
object::properties::ObjectProperties,
CustomObject
};
use bcrypt;
use chrono::NaiveDateTime;
@@ -227,8 +229,11 @@ impl User {
}
pub fn outbox(&self, conn: &PgConnection) -> ActivityStream<OrderedCollection> {
let mut coll = OrderedCollection::default(); // TODO
coll.collection_props.items = serde_json::to_value(self.get_activities(conn)).unwrap();
let acts = self.get_activities(conn);
let n_acts = acts.len();
let mut coll = OrderedCollection::default();
coll.collection_props.items = serde_json::to_value(acts).unwrap();
coll.collection_props.set_total_items_u64(n_acts as u64).unwrap();
ActivityStream::new(coll)
}
@@ -237,10 +242,8 @@ impl User {
use schema::post_authors;
let posts_by_self = PostAuthor::belonging_to(self).select(post_authors::post_id);
let posts = posts::table.filter(posts::id.eq(any(posts_by_self))).load::<Post>(conn).unwrap();
posts.into_iter().map(|_| {
// TODO Create::new(self, &p, conn)
// TODO: add a method to convert Post -> Create
serde_json::to_value(Create::default()).unwrap()
posts.into_iter().map(|p| {
serde_json::to_value(p.create_activity(conn)).unwrap()
}).collect::<Vec<serde_json::Value>>()
}
@@ -278,6 +281,42 @@ impl User {
pub fn get_keypair(&self) -> PKey<Private> {
PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.clone().unwrap().as_ref()).unwrap()).unwrap()
}
pub fn into_activity(&self, conn: &PgConnection) -> CustomObject<ApProps, Person> {
let mut actor = Person::default();
actor.object_props = ObjectProperties {
id: Some(serde_json::to_value(self.compute_id(conn)).unwrap()),
name: Some(serde_json::to_value(self.get_display_name()).unwrap()),
summary: Some(serde_json::to_value(self.get_summary()).unwrap()),
url: Some(serde_json::to_value(self.compute_id(conn)).unwrap()),
..ObjectProperties::default()
};
CustomObject::new(actor, ApProps {
inbox: Some(serde_json::to_value(self.compute_inbox(conn)).unwrap()),
outbox: Some(serde_json::to_value(self.compute_outbox(conn)).unwrap()),
preferred_username: Some(serde_json::to_value(self.get_actor_id()).unwrap()),
endpoints: Some(json!({
"sharedInbox": ap_url(format!("{}/inbox", BASE_URL.as_str()))
}))
})
}
}
#[derive(Serialize, Deserialize, Default, Properties)]
#[serde(rename_all = "camelCase")]
pub struct ApProps {
#[activitystreams(ab(Object, Link))]
inbox: Option<serde_json::Value>,
#[activitystreams(ab(Object, Link))]
outbox: Option<serde_json::Value>,
#[activitystreams(ab(Object, Link))]
preferred_username: Option<serde_json::Value>,
#[activitystreams(ab(Object))]
endpoints: Option<serde_json::Value>
}
impl<'a, 'r> FromRequest<'a, 'r> for User {
@@ -359,7 +398,7 @@ impl APActor for User {
}
impl IntoId for User {
fn into(&self) -> Id {
fn into_id(self) -> Id {
Id::new(self.ap_url.clone())
}
}