diff --git a/migrations/2018-05-10-101553_posts_add_ap_url/down.sql b/migrations/2018-05-10-101553_posts_add_ap_url/down.sql new file mode 100644 index 0000000..2a1fb81 --- /dev/null +++ b/migrations/2018-05-10-101553_posts_add_ap_url/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE posts DROP COLUMN ap_url; diff --git a/migrations/2018-05-10-101553_posts_add_ap_url/up.sql b/migrations/2018-05-10-101553_posts_add_ap_url/up.sql new file mode 100644 index 0000000..0ed4e93 --- /dev/null +++ b/migrations/2018-05-10-101553_posts_add_ap_url/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE posts ADD COLUMN ap_url VARCHAR NOT NULL DEFAULT ''; diff --git a/src/activity_pub/inbox.rs b/src/activity_pub/inbox.rs index e00dbf7..a58e86b 100644 --- a/src/activity_pub/inbox.rs +++ b/src/activity_pub/inbox.rs @@ -5,6 +5,7 @@ use activity_pub::activity; use activity_pub::actor::Actor; use activity_pub::sign::*; use models::blogs::Blog; +use models::comments::*; use models::follows::{Follow, NewFollow}; use models::posts::{Post, NewPost}; use models::users::User; @@ -18,14 +19,29 @@ pub trait Inbox: Actor + Sized { match act["object"]["type"].as_str().unwrap() { "Article" => { Post::insert(conn, NewPost { - blog_id: 0, - slug: String::from(""), - title: String::from(""), + blog_id: 0, // TODO + slug: String::from(""), // TODO + title: String::from(""), // TODO content: act["object"]["content"].as_str().unwrap().to_string(), published: true, - license: String::from("CC-0") + license: String::from("CC-0"), + ap_url: act["object"]["url"].as_str().unwrap().to_string() }); }, + "Note" => { + let previous_comment = Comment::get_by_ap_url(conn, act["object"]["inReplyTo"].as_str().unwrap().to_string()); + Comment::insert(conn, NewComment { + content: act["object"]["content"].as_str().unwrap().to_string(), + spoiler_text: act["object"]["summary"].as_str().unwrap_or("").to_string(), + ap_url: Some(act["object"]["id"].as_str().unwrap().to_string()), + in_response_to_id: previous_comment.clone().map(|c| c.id), + post_id: previous_comment + .map(|c| c.post_id) + .unwrap_or(Post::get_by_ap_url(conn, act["object"]["inReplyTo"].as_str().unwrap().to_string()).unwrap().id), + author_id: User::from_url(conn, act["actor"].as_str().unwrap().to_string()).unwrap().id, + sensitive: act["object"]["sensitive"].as_bool().unwrap_or(false) + }); + } x => println!("Received a new {}, but didn't saved it", x) } }, diff --git a/src/models/comments.rs b/src/models/comments.rs index f80a5a7..3bdf838 100644 --- a/src/models/comments.rs +++ b/src/models/comments.rs @@ -4,7 +4,7 @@ use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods}; use models::users::User; use schema::comments; -#[derive(Queryable, Identifiable, Serialize)] +#[derive(Queryable, Identifiable, Serialize, Clone)] pub struct Comment { pub id: i32, pub content: String, @@ -51,6 +51,14 @@ impl Comment { .expect("Error loading comment by post id") } + pub fn get_by_ap_url(conn: &PgConnection, ap_url: String) -> Option { + comments::table.filter(comments::ap_url.eq(ap_url)) + .limit(1) + .load::(conn) + .expect("Error loading comment by AP URL") + .into_iter().nth(0) + } + pub fn get_author(&self, conn: &PgConnection) -> User { User::get(conn, self.author_id).unwrap() } diff --git a/src/models/posts.rs b/src/models/posts.rs index 9d126df..7551d94 100644 --- a/src/models/posts.rs +++ b/src/models/posts.rs @@ -21,7 +21,8 @@ pub struct Post { pub content: String, pub published: bool, pub license: String, - pub creation_date: NaiveDateTime + pub creation_date: NaiveDateTime, + pub ap_url: String } #[derive(Insertable)] @@ -32,7 +33,8 @@ pub struct NewPost { pub title: String, pub content: String, pub published: bool, - pub license: String + pub license: String, + pub ap_url: String } impl Post { @@ -59,6 +61,14 @@ impl Post { .into_iter().nth(0) } + pub fn get_by_ap_url(conn: &PgConnection, ap_url: String) -> Option { + posts::table.filter(posts::ap_url.eq(ap_url)) + .limit(1) + .load::(conn) + .expect("Error loading post by AP URL") + .into_iter().nth(0) + } + pub fn get_authors(&self, conn: &PgConnection) -> Vec { use schema::users; use schema::post_authors; @@ -74,6 +84,14 @@ impl Post { .expect("Couldn't load blog associted to post") .into_iter().nth(0).unwrap() } + + pub fn update_ap_url(&self, conn: &PgConnection) { + if self.ap_url.len() == 0 { + diesel::update(self) + .set(posts::ap_url.eq(self.compute_id(conn))) + .get_result::(conn).expect("Couldn't update AP URL"); + } + } } impl Object for Post { diff --git a/src/routes/posts.rs b/src/routes/posts.rs index f2a928c..e039e04 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -72,8 +72,10 @@ fn create(blog_name: String, data: Form, user: User, conn: DbConn) title: form.title.to_string(), content: form.content.to_string(), published: true, - license: form.license.to_string() + license: form.license.to_string(), + ap_url: "".to_string() }); + post.update_ap_url(&*conn); PostAuthor::insert(&*conn, NewPostAuthor { post_id: post.id, author_id: user.id diff --git a/src/schema.rs b/src/schema.rs index a10c362..5b30da1 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -74,6 +74,7 @@ table! { published -> Bool, license -> Varchar, creation_date -> Timestamp, + ap_url -> Varchar, } }